取由三个点P[n-1], P[n]
和定义的两条边P[n+1]
,分别具有法线m1
和m2
。
让
然后法线是
现在Q
fromP[n]
的距离m0
是
所以因此
Q'
另一边的多边形点在哪里。
编辑:C 实现:
#include <stdlib.h>
#include <math.h>
#include "bmp.h"
typedef struct v { double x, y; } vec_t;
#define VECT(x, y) (vec_t){x, y}
vec_t v_add(vec_t a, vec_t b) { return VECT(a.x + b.x, a.y + b.y); }
vec_t v_sub(vec_t a, vec_t b) { return VECT(a.x - b.x, a.y - b.y); }
vec_t v_mul(vec_t v, double c) { return VECT(v.x * c, v.y * c); }
vec_t v_div(vec_t v, double d) { return v_mul(v, 1.0 / d); }
double v_dot(vec_t a, vec_t b) { return a.x * b.x + a.y * b.y; }
double v_mag(vec_t a) { return sqrt(a.x * a.x + a.y * a.y); }
vec_t v_nor(vec_t v) { return v_div(v, v_mag(v)); }
vec_t v_prp(vec_t v) { return VECT(-v.y, v.x); }
vec_t get_disp(vec_t i, vec_t j, vec_t k, double d)
{
vec_t a = v_sub(j, i), b = v_sub(k, j);
vec_t m1 = v_nor(v_prp(a)), m2 = v_nor(v_prp(b));
vec_t m0 = v_nor(v_add(m1, m2));
return v_mul(m0, d / v_dot(m0, m1));
}
void compute_polygon(vec_t* P, vec_t* Q, int N, double d)
{
int T = 2 * N - 1;
for (int i = 1; i < N - 1; i++)
{
vec_t M = get_disp(P[i - 1], P[i], P[i + 1], d);
Q[i] = v_add(P[i], M);
Q[T - i] = v_sub(P[i], M);
}
vec_t A = v_mul(v_nor(v_prp(v_sub(P[1], P[0]))), d);
vec_t B = v_mul(v_nor(v_prp(v_sub(P[N-1], P[N-2]))), d);
Q[0] = v_add(P[0], A); Q[T] = v_sub(P[0], A);
Q[N - 1] = v_add(P[N - 1], B); Q[N] = v_sub(P[N - 1], B);
}
int iround(double c) { return (int)((c > 0.0) ? c+0.5 : c-0.5); }
void draw_line(bmp_t* i, vec_t a, vec_t b, int c)
{
bmp_aux_draw_line(i, iround(a.x), iround(a.y), iround(b.x), iround(b.y), c);
}
void draw_dot(bmp_t* i, vec_t p, int c)
{
bmp_aux_draw_dot(i, iround(p.x), iround(p.y), 3, c);
}
int main()
{
const int N = 5;
vec_t P[N], Q[2*N];
P[0] = VECT(30, 30);
P[1] = VECT(70, 150);
P[2] = VECT(130, 170);
P[3] = VECT(190, 240);
P[4] = VECT(270, 190);
compute_polygon(P, Q, N, 10.0);
bmp_t* img = bmp_new(300, 300);
for (int i = 0; i < N-1; i++)
{
draw_line(img, P[i], P[i+1], 0);
draw_dot(img, P[i], 0x0000FF);
}
draw_dot(img, P[N-1], 0x0000FF);
for (int i = 0; i < 2*N-1; i++)
draw_line(img, Q[i], Q[i + 1], 0xEEEE00);
draw_line(img, Q[0], Q[2*N-1], 0xEEEE00);
bmp_write(img, "a.bmp");
bmp_free(img);
return 0;
}
点在 (30, 30), (70, 150), (130, 170), (190, 240), (270, 190)。