22 #include <grass/Vect.h>
23 #include <grass/gis.h>
25 #define LENGTH(DX, DY) ( sqrt( (DX*DX)+(DY*DY) ) )
29 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,
54 int s4,
int *s5,
int *s6)
60 "find_cross(): npoints = %d, s1 = %d, s2 = %d, s3 = %d, s4 = %d",
61 Points->n_points, s1, s2, s3, s4);
65 np = Points->n_points;
67 for (i = s1; i <= s2; i++) {
68 for (j = s3; j <= s4; j++) {
74 x[j], y[j], x[j + 1], y[j + 1]);
75 if (ret == 1 && ((i - j) > 1 || (i - j) < -1)) {
78 G_debug(5,
" intersection: s5 = %d, s6 = %d", *s5, *s6);
84 G_debug(5,
" overlap: s5 = %d, s6 = %d", *s5, *s6);
97 static int point_in_buf(
struct line_pnts *Points,
double px,
double py,
103 np = Points->n_points;
105 for (i = 0; i < np - 1; i++) {
107 Points->x[i], Points->y[i], 0,
108 Points->x[i + 1], Points->y[i + 1],
132 static void clean_parallel(
struct line_pnts *Points,
133 struct line_pnts *origPoints,
double d,
int rm_end)
135 int i, j, np, npn, sa, sb;
137 int first = 0, current, last, lcount;
138 double *x, *
y, px, py, ix, iy;
139 static struct line_pnts *sPoints =
NULL;
141 G_debug(4,
"clean_parallel(): npoints = %d, d = %f, rm_end = %d",
142 Points->n_points, d, rm_end);
146 np = Points->n_points;
156 while (first < np - 2) {
159 last = Points->n_points - 2;
162 (Points, current, last - 1, current + 1, last, &sa,
171 G_debug(5,
" current = %d, last = %d, lcount = %d", current,
185 if ((sb - sa) == 1) {
192 y[sb], x[sb + 1], y[sb + 1], &ix, &iy);
194 for (i = sa + 1; i < sb + 1; i++) {
198 if (point_in_buf(origPoints, px, py, d)) {
214 for (i = j; i < Points->n_points; i++) {
219 Points->n_points = npn;
225 for (i = 0; i < Points->n_points - 1; i++) {
226 px = (x[i] + x[i + 1]) / 2;
227 py = (y[i] + y[i + 1]) / 2;
228 if (point_in_buf(origPoints, x[i], y[i], d * 0.9999)
229 && point_in_buf(origPoints, px, py, d * 0.9999)) {
238 for (i = j; i < Points->n_points; i++) {
243 Points->n_points = npn;
247 for (i = Points->n_points - 1; i >= 1; i--) {
248 px = (x[i] + x[i - 1]) / 2;
249 py = (y[i] + y[i - 1]) / 2;
250 if (point_in_buf(origPoints, x[i], y[i], d * 0.9999)
251 && point_in_buf(origPoints, px, py, d * 0.9999)) {
259 Points->n_points -= j;
271 static void parallel_line(
struct line_pnts *Points,
double d,
double tol,
272 struct line_pnts *nPoints)
274 int i, j, np, na, side;
275 double *x, *
y, nx, ny, tx, ty, vx, vy, ux, uy, wx, wy;
276 double atol, atol2, a, av, aw;
283 np = Points->n_points;
300 side = (int)(d / fabs(d));
301 atol = 2 * acos(1 - tol / fabs(d));
303 for (i = 0; i < np - 1; i++) {
304 vect(x[i], y[i], x[i + 1], y[i + 1], &tx, &ty);
317 vect(x[i + 1], y[i + 1], x[i + 2], y[i + 2], &ux, &uy);
322 a = (aw - av) * side;
327 if (a <= PI && a > atol) {
328 na = (int)(a / atol);
329 atol2 = a / (na + 1) * side;
330 for (j = 0; j < na; j++) {
332 nx = x[i + 1] + fabs(d) * cos(av);
333 ny = y[i + 1] + fabs(d) * sin(av);
355 double tolerance,
int rm_end,
struct line_pnts *OutPoints)
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);
381 double tolerance,
struct line_pnts *OutPoints)
385 static struct line_pnts *Points =
NULL;
386 static struct line_pnts *PPoints =
NULL;
388 distance = fabs(distance);
390 dangle = 2 * acos(1 - tolerance / fabs(distance));
405 npoints = Points->n_points;
409 else if (npoints == 1) {
412 for (angle = 0; angle < 2 *
PI; angle += dangle) {
413 x = Points->x[0] + distance * cos(angle);
414 y = Points->y[0] + distance * sin(angle);
421 for (side = 0; side < 2; side++) {
422 double angle, sangle;
423 double lx1, ly1, lx2, ly2;
424 double x,
y, nx, ny, sx, sy, ex, ey;
439 lx1 = Points->x[npoints - 2];
440 ly1 = Points->y[npoints - 2];
441 lx2 = Points->x[npoints - 1];
442 ly2 = Points->y[npoints - 1];
452 vect(lx1, ly1, lx2, ly2, &nx, &ny);
455 sangle = atan2(-nx, ny);
456 sx = lx2 + ny * distance;
457 sy = ly2 - nx * distance;
460 ex = lx2 - ny * distance;
461 ey = ly2 + nx * distance;
466 for (angle = dangle; angle <
PI; angle += dangle) {
467 x = lx2 + distance * cos(sangle + angle);
468 y = ly2 + distance * sin(sangle + angle);
struct line_pnts * Vect_new_line_struct()
Creates and initializes a struct line_pnts.
int dig_find_intersection(double ax1, double ay1, double ax2, double ay2, double bx1, double by1, double bx2, double by2, double *x, double *y)
int Vect_append_points(struct line_pnts *Points, struct line_pnts *APoints, int direction)
Appends points to the end of a line.
int Vect_reset_line(struct line_pnts *Points)
Reset line.
double dig_distance2_point_to_line(double x, double y, double z, double x1, double y1, double z1, double x2, double y2, double z2, int with_z, double *px, double *py, double *pz, double *pdist, int *status)
void Vect_line_buffer(struct line_pnts *InPoints, double distance, double tolerance, struct line_pnts *OutPoints)
Create buffer around the line line.
int Vect_append_point(struct line_pnts *Points, double x, double y, double z)
Appends one point to the end of a line.
int Vect_copy_xyz_to_pnts(struct line_pnts *Points, double *x, double *y, double *z, int n)
Copy points from array to line structure.
int Vect_find_poly_centroid(struct line_pnts *points, double *cent_x, double *cent_y)
Get centroid of polygon.
int dig_test_for_intersection(double ax1, double ay1, double ax2, double ay2, double bx1, double by1, double bx2, double by2)
int Vect_line_prune(struct line_pnts *Points)
Remove duplicate points, i.e. zero length segments.
int G_debug(int level, const char *msg,...)
Print debugging message.
void Vect_line_parallel(struct line_pnts *InPoints, double distance, double tolerance, int rm_end, struct line_pnts *OutPoints)
Create parrallel line.