23#define LENGTH(DX, DY) (sqrt((DX * DX) + (DY * DY)))
28#define NON_LOOPED_LINE 0
31static void norm_vector(
double x1,
double y1,
double x2,
double y2,
double *x,
38 if ((dx == 0) && (dy == 0)) {
52static void rotate_vector(
double x,
double y,
double cosa,
double sina,
53 double *nx,
double *ny)
65static void elliptic_transform(
double x,
double y,
double da,
double db,
66 double dalpha,
double *nx,
double *ny)
94static void elliptic_tangent(
double x,
double y,
double da,
double db,
102 rotate_vector(x, y,
cosa, -
sina, &x, &y);
119static void line_coefficients(
double x1,
double y1,
double x2,
double y2,
120 double *a,
double *
b,
double *c)
124 *c = x2 * y1 - x1 * y2;
134static int line_intersection(
double a1,
double b1,
double c1,
double a2,
135 double b2,
double c2,
double *x,
double *y)
146 d = a1 *
b2 - a2 *
b1;
148 *y = (
c1 * a2 -
c2 * a1) / d;
153static double angular_tolerance(
double tol,
double da,
double db)
176static void parallel_line(
struct line_pnts *Points,
double da,
double db,
182 double tx,
ty,
vx,
vy,
wx,
wy, nx, ny,
mx,
my,
rx,
ry;
184 double a0, b0,
c0, a1,
b1,
c1;
210 if ((np == 0) || (np == 1))
213 if ((
da == 0) || (
db == 0)) {
222 for (i = 0; i < np - 1; i++) {
230 norm_vector(x[i], y[i], x[i + 1], y[i + 1], &
tx, &
ty);
231 if ((
tx == 0) && (
ty == 0))
242 line_coefficients(nx, ny,
mx,
my, &a1, &
b1, &
c1);
261 norm_vector(0, 0,
vx,
vy, &
tx, &
ty);
274 res = line_intersection(a0, b0,
c0, a1,
b1,
c1, &
rx, &
ry);
318 if ((!
looped) && (i == np - 2)) {
335static void convolution_line(
struct line_pnts *Points,
double da,
double db,
341 double tx,
ty,
vx,
vy,
wx,
wy, nx, ny,
mx,
my,
rx,
ry;
343 double a0, b0,
c0, a1,
b1,
c1;
354 if ((np == 0) || (np == 1))
356 if ((x[0] != x[np - 1]) || (y[0] != y[np - 1])) {
363 if ((
da == 0) || (
db == 0)) {
373 norm_vector(x[i], y[i], x[i + 1], y[i + 1], &
tx, &
ty);
381 line_coefficients(nx, ny,
mx,
my, &a1, &
b1, &
c1);
383 for (i = 0; i <= np - 2; i++) {
384 G_debug(4,
"point %d, segment %d-%d", i, i, i + 1);
395 norm_vector(x[i], y[i], x[i + 1], y[i + 1], &
tx, &
ty);
396 if ((
tx == 0) && (
ty == 0))
405 line_coefficients(nx, ny,
mx,
my, &a1, &
b1, &
c1);
418 norm_vector(0, 0,
vx,
vy, &
tx, &
ty);
421 G_debug(4,
" append point (c) x=%.16f y=%.16f", x[i] +
wx +
tx,
425 G_debug(4,
" append point (c) x=%.16f y=%.16f", nx +
tx, ny +
ty);
429 res = line_intersection(a0, b0,
c0, a1,
b1,
c1, &
rx, &
ry);
432 G_debug(4,
" append point (o) x=%.16f y=%.16f",
rx,
ry);
439 _(
"Unexpected result of line_intersection() res = %d"),
466 G_debug(4,
" append point (r) x=%.16f y=%.16f", x[i] +
tx,
473 G_debug(4,
" append point (s) x=%.16f y=%.16f", nx, ny);
475 G_debug(4,
" append point (s) x=%.16f y=%.16f",
mx,
my);
508 G_debug(3,
"extract_contour(): v1=%d, v2=%d, side=%d, stop_at_line_end=%d",
530 G_debug(4,
"ec: v0=%d, v=%d, eside=%d, edge->v1=%d, edge->v2=%d",
v0, v,
545 for (
j = 0;
j <
vert->ecount;
j++) {
547 if (
vert->edges[
j] != edge) {
572 G_debug(3,
" end has been reached, will stop here");
579 G_debug(3,
" end has been reached, turning around");
588 G_warning(
_(
"Next edge was visited (right) but it is not the "
589 "first one !!! breaking loop"));
591 "ec: v0=%d, v=%d, eside=%d, edge->v1=%d, edge->v2=%d",
599 G_warning(
_(
"Next edge was visited (left) but it is not the "
600 "first one !!! breaking loop"));
602 "ec: v0=%d, v=%d, eside=%d, edge->v1=%d, edge->v2=%d",
612 v = (edge->
v1 == v) ? (edge->
v2) : (edge->
v1);
644 G_debug(3,
"extract_outer_contour()");
653 for (i = 0; i < pg->
vcount; i++) {
663 for (i = 0; i <
vert->ecount; i++) {
665 edge =
vert->edges[i];
692 G_debug(3,
"extract_inner_contour()");
694 for (i = 0; i < pg->
ecount; i++) {
697 if (!(pg->
e[i].visited_right)) {
705 if (pg->
e[i].visited_right) {
722static int point_in_buf(
struct line_pnts *Points,
double px,
double py,
737 for (i = 0; i < np - 1; i++) {
740 wx = Points->
x[i + 1];
741 wy = Points->
y[i + 1];
783 d =
dig_distance2_point_to_line(
px,
py, 0,
vx,
vy, 0,
wx,
wy, 0, 0,
797static int get_polygon_orientation(
const double *x,
const double *y,
int n)
799 double x1, y1, x2, y2;
813 area += (y2 + y1) * (x2 - x1);
820static void add_line_to_array(
struct line_pnts *Points,
822 int *allocated,
int more)
824 if (*allocated == *count) {
829 (*arrPoints)[*
count] = Points;
835static void destroy_lines_array(
struct line_pnts **
arr,
int count)
839 for (i = 0; i <
count; i++)
874 G_debug(3,
" processing outer contour");
913 G_warning(
_(
"Vect_get_point_in_poly() failed"));
922 G_debug(3,
" processing inner contours");
966 G_warning(
_(
"Vect_get_point_in_poly() failed"));
982 G_debug(3,
"buffer_lines() ... done");
1023 G_debug(2,
"Vect_line_buffer()");
1040 extract_outer_contour(pg, 0,
outer);
1087 G_debug(2,
"Vect_area_buffer()");
1102 for (i = 0; i < n_isles; i++) {
1118 buffer_lines(
outer, isles,
isles_count, 0,
da,
db,
dalpha,
round,
caps,
tol,
1197 "Vect_line_parallel(): npoints = %d, da = %f, "
1198 "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.