24 #define LENGTH(DX, DY) (sqrt((DX * DX) + (DY * DY)))
28 static void vect(
double x1,
double y1,
double x2,
double y2,
double *
x,
53 static int find_cross(
struct line_pnts *Points,
int s1,
int s2,
int s3,
int s4,
59 G_debug(5,
"find_cross(): npoints = %d, s1 = %d, s2 = %d, s3 = %d, s4 = %d",
65 for (i = s1; i <= s2; i++) {
66 for (j = s3; j <= s4; j++) {
71 x[j], y[j],
x[j + 1], y[j + 1]);
72 if (ret == 1 && ((i - j) > 1 || (i - j) < -1)) {
75 G_debug(5,
" intersection: s5 = %d, s6 = %d", *s5, *s6);
81 G_debug(5,
" overlap: s5 = %d, s6 = %d", *s5, *s6);
94 static int point_in_buf(
struct line_pnts *Points,
double px,
double py,
102 for (i = 0; i < np - 1; i++) {
104 0, Points->
x[i + 1], Points->
y[i + 1],
128 static void clean_parallel(
struct line_pnts *Points,
129 struct line_pnts *origPoints,
double d,
int rm_end)
131 int i, j, np, npn, sa, sb;
133 int first = 0, current, last, lcount;
134 double *
x, *y, px, py, ix, iy;
137 G_debug(4,
"clean_parallel(): npoints = %d, d = %f, rm_end = %d",
152 while (first < np - 2) {
157 while (find_cross(Points, current, last - 1, current + 1, last, &sa,
166 G_debug(5,
" current = %d, last = %d, lcount = %d", current, last,
180 if ((sb - sa) == 1) {
187 y[sb],
x[sb + 1],
y[sb + 1], &ix, &iy);
189 for (i = sa + 1; i < sb + 1; i++) {
193 if (point_in_buf(origPoints, px, py, d)) {
209 for (i = j; i < Points->
n_points; i++) {
220 for (i = 0; i < Points->
n_points - 1; i++) {
221 px = (
x[i] +
x[i + 1]) / 2;
222 py = (
y[i] +
y[i + 1]) / 2;
223 if (point_in_buf(origPoints,
x[i],
y[i], d * 0.9999) &&
224 point_in_buf(origPoints, px, py, d * 0.9999)) {
233 for (i = j; i < Points->
n_points; i++) {
242 for (i = Points->
n_points - 1; i >= 1; i--) {
243 px = (
x[i] +
x[i - 1]) / 2;
244 py = (
y[i] +
y[i - 1]) / 2;
245 if (point_in_buf(origPoints,
x[i],
y[i], d * 0.9999) &&
246 point_in_buf(origPoints, px, py, d * 0.9999)) {
266 static void parallel_line(
struct line_pnts *Points,
double d,
double tol,
269 int i, j, np, na, side;
270 double *
x, *
y, nx, ny, tx, ty, vx, vy, ux, uy, wx, wy;
271 double atol, atol2, a, av, aw;
296 side = (int)(d / fabs(d));
297 atol = 2 * acos(1 - tol / fabs(d));
299 for (i = 0; i < np - 1; i++) {
300 vect(
x[i],
y[i],
x[i + 1],
y[i + 1], &tx, &ty);
314 vect(
x[i + 1],
y[i + 1],
x[i + 2],
y[i + 2], &ux, &uy);
319 a = (aw - av) * side;
325 if (a <= PI && a > atol) {
326 na = (int)(a / atol);
327 atol2 = a / (na + 1) * side;
328 for (j = 0; j < na; j++) {
330 nx =
x[i + 1] + fabs(d) * cos(av);
331 ny =
y[i + 1] + fabs(d) * sin(av);
354 double tolerance,
int rm_end,
358 "Vect_line_parallel(): npoints = %d, distance = %f, tolerance = %f",
359 InPoints->
n_points, distance, tolerance);
361 parallel_line(InPoints, distance, tolerance, OutPoints);
363 clean_parallel(OutPoints, InPoints, distance, rm_end);
382 double tolerance,
struct line_pnts *OutPoints)
389 distance = fabs(distance);
391 dangle = 2 * acos(1 - tolerance / fabs(distance));
410 else if (npoints == 1) {
413 for (angle = 0; angle < 2 *
PI; angle += dangle) {
414 x = Points->
x[0] + distance * cos(angle);
415 y = Points->
y[0] + distance * sin(angle);
422 for (side = 0; side < 2; side++) {
423 double angle, sangle;
424 double lx1, ly1, lx2, ly2;
425 double x,
y, nx, ny, sx, sy, ex, ey;
440 lx1 = Points->
x[npoints - 2];
441 ly1 = Points->
y[npoints - 2];
442 lx2 = Points->
x[npoints - 1];
443 ly2 = Points->
y[npoints - 1];
453 vect(lx1, ly1, lx2, ly2, &nx, &ny);
456 sangle = atan2(-nx, ny);
457 sx = lx2 + ny * distance;
458 sy = ly2 - nx * distance;
461 ex = lx2 - ny * distance;
462 ey = ly2 + nx * distance;
467 for (angle = dangle; angle <
PI; angle += dangle) {
468 x = lx2 + distance * cos(sangle + angle);
469 y = ly2 + distance * sin(sangle + angle);
void Vect_line_parallel(struct line_pnts *InPoints, double distance, double tolerance, int rm_end, struct line_pnts *OutPoints)
Create parallel line.
void Vect_line_buffer(const struct line_pnts *InPoints, double distance, double tolerance, struct line_pnts *OutPoints)
Create buffer around the line line.
int G_debug(int, const char *,...) __attribute__((format(printf
int Vect_find_poly_centroid(const struct line_pnts *, double *, double *)
Get centroid of polygon.
int Vect_copy_xyz_to_pnts(struct line_pnts *, const double *, const double *, const double *, int)
Copy points from array to line_pnts structure.
struct line_pnts * Vect_new_line_struct(void)
Creates and initializes a line_pnts structure.
void Vect_reset_line(struct line_pnts *)
Reset line.
int Vect_line_prune(struct line_pnts *)
Remove duplicate points, i.e. zero length segments.
int Vect_append_point(struct line_pnts *, double, double, double)
Appends one point to the end of a line.
int Vect_append_points(struct line_pnts *, const struct line_pnts *, int)
Appends points to the end of a line.
#define GV_FORWARD
Line direction indicator forward/backward.
double dig_distance2_point_to_line(double, double, double, double, double, double, double, double, double, int, double *, double *, double *, double *, int *)
int dig_find_intersection(double, double, double, double, double, double, double, double, double *, double *)
int dig_test_for_intersection(double, double, double, double, double, double, double, double)
Feature geometry info - coordinates.
double * y
Array of Y coordinates.
double * x
Array of X coordinates.
int n_points
Number of points.