27#define LENGTH(DX, DY) (sqrt((DX * DX) + (DY * DY)))
32#define NON_LOOPED_LINE 0
35static void norm_vector(
double x1,
double y1,
double x2,
double y2,
double *x,
42 if ((dx == 0) && (dy == 0)) {
56static void rotate_vector(
double x,
double y,
double cosa,
double sina,
57 double *nx,
double *ny)
69static void elliptic_transform(
double x,
double y,
double da,
double db,
70 double dalpha,
double *nx,
double *ny)
98static void elliptic_tangent(
double x,
double y,
double da,
double db,
106 rotate_vector(x, y,
cosa, -
sina, &x, &y);
123static void line_coefficients(
double x1,
double y1,
double x2,
double y2,
124 double *a,
double *
b,
double *c)
128 *c = x2 * y1 - x1 * y2;
138static int line_intersection(
double a1,
double b1,
double c1,
double a2,
139 double b2,
double c2,
double *x,
double *y)
150 d = a1 *
b2 - a2 *
b1;
152 *y = (
c1 * a2 -
c2 * a1) / d;
157static double angular_tolerance(
double tol,
double da,
double db)
180static void parallel_line(
struct line_pnts *Points,
double da,
double db,
186 double tx,
ty,
vx,
vy,
wx,
wy, nx, ny,
mx,
my,
rx,
ry;
188 double a0, b0,
c0, a1,
b1,
c1;
214 if ((np == 0) || (np == 1))
217 if ((
da == 0) || (
db == 0)) {
226 for (i = 0; i < np - 1; i++) {
234 norm_vector(x[i], y[i], x[i + 1], y[i + 1], &
tx, &
ty);
235 if ((
tx == 0) && (
ty == 0))
246 line_coefficients(nx, ny,
mx,
my, &a1, &
b1, &
c1);
265 norm_vector(0, 0,
vx,
vy, &
tx, &
ty);
278 res = line_intersection(a0, b0,
c0, a1,
b1,
c1, &
rx, &
ry);
322 if ((!
looped) && (i == np - 2)) {
339static void convolution_line(
struct line_pnts *Points,
double da,
double db,
345 double tx,
ty,
vx,
vy,
wx,
wy, nx, ny,
mx,
my,
rx,
ry;
347 double a0, b0,
c0, a1,
b1,
c1;
358 if ((np == 0) || (np == 1))
360 if ((x[0] != x[np - 1]) || (y[0] != y[np - 1])) {
367 if ((
da == 0) || (
db == 0)) {
377 norm_vector(x[i], y[i], x[i + 1], y[i + 1], &
tx, &
ty);
385 line_coefficients(nx, ny,
mx,
my, &a1, &
b1, &
c1);
387 for (i = 0; i <= np - 2; i++) {
388 G_debug(4,
"point %d, segment %d-%d", i, i, i + 1);
399 norm_vector(x[i], y[i], x[i + 1], y[i + 1], &
tx, &
ty);
400 if ((
tx == 0) && (
ty == 0))
409 line_coefficients(nx, ny,
mx,
my, &a1, &
b1, &
c1);
422 norm_vector(0, 0,
vx,
vy, &
tx, &
ty);
425 G_debug(4,
" append point (c) x=%.16f y=%.16f", x[i] +
wx +
tx,
429 G_debug(4,
" append point (c) x=%.16f y=%.16f", nx +
tx, ny +
ty);
433 res = line_intersection(a0, b0,
c0, a1,
b1,
c1, &
rx, &
ry);
436 G_debug(4,
" append point (o) x=%.16f y=%.16f",
rx,
ry);
443 _(
"Unexpected result of line_intersection() res = %d"),
470 G_debug(4,
" append point (r) x=%.16f y=%.16f", x[i] +
tx,
477 G_debug(4,
" append point (s) x=%.16f y=%.16f", nx, ny);
479 G_debug(4,
" append point (s) x=%.16f y=%.16f",
mx,
my);
512 G_debug(3,
"extract_contour(): v1=%d, v2=%d, side=%d, stop_at_line_end=%d",
534 G_debug(4,
"ec: v0=%d, v=%d, eside=%d, edge->v1=%d, edge->v2=%d",
v0, v,
549 for (
j = 0;
j <
vert->ecount;
j++) {
551 if (
vert->edges[
j] != edge) {
576 G_debug(3,
" end has been reached, will stop here");
583 G_debug(3,
" end has been reached, turning around");
592 G_warning(
_(
"Next edge was visited (right) but it is not the "
593 "first one !!! breaking loop"));
595 "ec: v0=%d, v=%d, eside=%d, edge->v1=%d, edge->v2=%d",
603 G_warning(
_(
"Next edge was visited (left) but it is not the "
604 "first one !!! breaking loop"));
606 "ec: v0=%d, v=%d, eside=%d, edge->v1=%d, edge->v2=%d",
616 v = (edge->
v1 == v) ? (edge->
v2) : (edge->
v1);
648 G_debug(3,
"extract_outer_contour()");
657 for (i = 0; i < pg->
vcount; i++) {
667 for (i = 0; i <
vert->ecount; i++) {
669 edge =
vert->edges[i];
696 G_debug(3,
"extract_inner_contour()");
698 for (i = 0; i < pg->
ecount; i++) {
701 if (!(pg->
e[i].visited_right)) {
709 if (pg->
e[i].visited_right) {
726static int point_in_buf(
struct line_pnts *Points,
double px,
double py,
741 for (i = 0; i < np - 1; i++) {
744 wx = Points->
x[i + 1];
745 wy = Points->
y[i + 1];
787 d =
dig_distance2_point_to_line(
px,
py, 0,
vx,
vy, 0,
wx,
wy, 0, 0,
801static int get_polygon_orientation(
const double *x,
const double *y,
int n)
803 double x1, y1, x2, y2;
817 area += (y2 + y1) * (x2 - x1);
824static void add_line_to_array(
struct line_pnts *Points,
826 int *allocated,
int more)
828 if (*allocated == *count) {
833 (*arrPoints)[*
count] = Points;
839static void destroy_lines_array(
struct line_pnts **
arr,
int count)
843 for (i = 0; i <
count; i++)
878 G_debug(3,
" processing outer contour");
917 G_warning(
_(
"Vect_get_point_in_poly() failed"));
926 G_debug(3,
" processing inner contours");
970 G_warning(
_(
"Vect_get_point_in_poly() failed"));
986 G_debug(3,
"buffer_lines() ... done");
1027 G_debug(2,
"Vect_line_buffer()");
1044 extract_outer_contour(pg, 0,
outer);
1091 G_debug(2,
"Vect_area_buffer()");
1106 for (i = 0; i < n_isles; i++) {
1122 buffer_lines(
outer, isles,
isles_count, 0,
da,
db,
dalpha,
round,
caps,
tol,
1201 "Vect_line_parallel(): npoints = %d, da = %f, "
1202 "db = %f, dalpha = %f, side = %d, round_corners = %d, tol = %f",
void Vect_line_parallel2(struct line_pnts *InPoints, double da, double db, double dalpha, int side, int round, double tol, struct line_pnts *OutPoints)
void Vect_line_buffer2(const struct line_pnts *Points, double da, double db, double dalpha, int round, int caps, double tol, struct line_pnts **oPoints, struct line_pnts ***iPoints, int *inner_count)
Creates buffer around line.
void Vect_area_buffer2(struct Map_info *Map, int area, double da, double db, double dalpha, int round, int caps, double tol, struct line_pnts **oPoints, struct line_pnts ***iPoints, int *inner_count)
Creates buffer around area.
void Vect_point_buffer2(double px, double py, double da, double db, double dalpha, int round, double tol, struct line_pnts **oPoints)
Creates buffer around the point (px, py).
void G_free(void *)
Free allocated memory.
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
void Vect_destroy_line_struct(struct line_pnts *)
Frees all memory associated with a line_pnts structure, including the structure itself.
int Vect_get_isle_points(struct Map_info *, int, struct line_pnts *)
Returns polygon array of points for given isle.
int Vect_get_area_points(struct Map_info *, int, struct line_pnts *)
Returns polygon array of points (outer ring) of given area.
int Vect_copy_xyz_to_pnts(struct line_pnts *, const double *, const double *, const double *, int)
Copy points from array to line_pnts structure.
int Vect_get_point_in_poly(const struct line_pnts *, double *, double *)
Get point inside polygon.
int Vect_get_area_isle(struct Map_info *, int, int)
Returns isle id for area.
int Vect_get_area_num_isles(struct Map_info *, int)
Returns number of isles for given area.
int Vect_point_in_poly(double, double, const struct line_pnts *)
Determines if a point (X,Y) is inside a polygon.
int Vect_line_delete_point(struct line_pnts *, int)
Delete point at given index and move all points above down.
void Vect_reset_line(struct line_pnts *)
Reset line.
int Vect_line_prune(struct line_pnts *)
Remove duplicate points, i.e. zero length segments.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
void pg_destroy_struct(struct planar_graph *pg)
struct planar_graph * pg_create(const struct line_pnts *Points)
double dig_distance2_point_to_line(double, double, double, double, double, double, double, double, double, int, double *, double *, double *, double *, int *)
int dig_find_area_poly(struct line_pnts *, double *)
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
int n_points
Number of points.
double * z
Array of Z coordinates.