24 #define LENGTH(DX, DY) (sqrt((DX*DX)+(DY*DY))) 26 #define MIN(X,Y) ((X<Y)?X:Y) 29 #define MAX(X,Y) ((X>Y)?X:Y) 33 struct intersection_point
40 struct seg_intersection
47 struct seg_intersection_list
51 struct seg_intersection *a;
54 struct seg_intersections
58 struct intersection_point *ip;
60 struct seg_intersection_list *il;
66 struct seg_intersections *si;
70 si =
G_malloc(
sizeof(
struct seg_intersections));
72 si->ipallocated = segments_count + 16;
73 si->ip =
G_malloc((si->ipallocated) *
sizeof(
struct intersection_point));
74 si->ilcount = segments_count;
75 si->il =
G_malloc(segments_count *
sizeof(
struct seg_intersection_list));
76 for (i = 0; i < segments_count; i++) {
78 si->il[i].allocated = 0;
89 for (i = 0; i < si->ilcount; i++)
99 void add_ipoint1(
struct seg_intersection_list *il,
int with,
double dist,
102 struct seg_intersection *s;
104 if (il->count == il->allocated) {
108 (il->allocated) *
sizeof(
struct seg_intersection));
110 s = &(il->a[il->count]);
121 double x,
double y,
struct seg_intersections *si)
123 struct intersection_point *
t;
129 if (si->ipcount == si->ipallocated) {
130 si->ipallocated += 16;
133 (si->ipallocated) *
sizeof(
struct intersection_point));
143 LENGTH((Points->
x[first_seg] - x),
144 (Points->
y[first_seg] - y)), ip);
147 LENGTH((Points->
x[second_seg] - x),
148 (Points->
y[second_seg] - y)), ip);
154 struct seg_intersection t;
156 G_debug(4,
"sort_intersection_list()");
160 for (i = 0; i < n - 1; i++) {
162 for (j = i + 1; j < n; j++) {
163 if (il->a[j].dist < il->a[min].dist) {
169 il->a[i] = il->a[
min];
179 struct intersection_point *aa, *bb;
181 aa = *((
struct intersection_point **)a);
182 bb = *((
struct intersection_point **)b);
186 else if (aa->x > bb->x)
189 return (aa->y < bb->y) ? -1 : ((aa->y > bb->y) ? 1 : 0);
205 min =
MAX(fabs(x[1] - x[0]), fabs(y[1] - y[0]));
206 for (i = 1; i <= np - 2; i++) {
207 t =
MAX(fabs(x[i + 1] - x[i]), fabs(y[i + 1] - y[i]));
208 if ((t > 0) && (t < min)) {
214 return min * 0.000001;
226 double x1, y1, x2, y2;
231 struct seg_intersections *si;
232 struct seg_intersection_list *il;
233 struct intersection_point **sorted;
235 G_debug(3,
"find_all_intersections()");
243 looped = ((x[0] == x[np - 1]) && (y[0] == y[np - 1]));
244 G_debug(3,
" looped=%d", looped);
246 G_debug(3,
" finding intersections...");
247 for (i = 0; i < np - 1; i++) {
248 for (j = i + 1; j < np - 1; j++) {
249 G_debug(4,
" checking %d-%d %d-%d", i, i + 1, j, j + 1);
253 y[j], x[j + 1], y[j + 1], &x1, &y1,
262 G_debug(4,
" intersection type = %d", res);
266 else if ((res >= 2) && (res <= 5)) {
274 add_ipoint(Points, 0, -1, Points->
x[0], Points->
y[0], si);
275 add_ipoint(Points, np - 2, -1, Points->
x[np - 1], Points->
y[np - 1],
278 G_debug(3,
" finding intersections...done");
280 G_debug(3,
" postprocessing...");
281 if (si->ipallocated > si->ipcount) {
282 si->ipallocated = si->ipcount;
285 (si->ipcount) *
sizeof(
struct intersection_point));
287 for (i = 0; i < si->ilcount; i++) {
289 if (il->allocated > il->count) {
290 il->allocated = il->count;
293 (il->count) *
sizeof(
struct seg_intersection));
303 sorted =
G_malloc((si->ipcount) *
sizeof(
struct intersection_point *));
304 for (i = 0; i < si->ipcount; i++)
305 sorted[i] = &(si->ip[i]);
307 qsort(sorted, si->ipcount,
sizeof(
struct intersection_point *),
compare);
311 for (i = 0; i < si->ipcount; i++) {
314 for (j = i - 1; j >= 0; j--) {
315 if (!
FEQUAL(sorted[j]->x, sorted[i]->x, EPSILON))
318 if (
FEQUAL(sorted[j]->y, sorted[i]->y, EPSILON)) {
320 t = sorted[j]->group;
324 G_debug(4,
" group=%d, ip=%d", t,
325 (
int)(sorted[i] - &(si->ip[0])));
326 sorted[i]->group =
t;
330 si->group_count = group;
332 G_debug(3,
" postprocessing...done");
335 for (i = 0; i < si->ilcount; i++) {
336 G_debug(4,
"%d-%d :", i, i + 1);
337 for (j = 0; j < si->il[i].count; j++) {
338 G_debug(4,
" %d-%d, group=%d", si->il[i].a[j].with,
339 si->il[i].a[j].with + 1, si->ip[si->il[i].a[j].ip].group);
340 G_debug(4,
" dist=%.18f", si->il[i].a[j].dist);
341 G_debug(4,
" x=%.18f, y=%.18f",
342 si->ip[si->il[i].a[j].ip].x, si->ip[si->il[i].a[j].ip].y);
359 memset(pg->
v, 0, n *
sizeof(
struct pg_vertex));
372 for (i = 0; i < pg->
vcount; i++) {
394 for (i = 0; i < ecount; i++) {
396 if (((e->
v1 == v1) && (e->
v2 ==
v2)) ||
397 ((e->
v1 ==
v2) && (e->
v2 == v1)))
420 G_debug(4,
"pg_addedge(), v1=%d, v2=%d", v1, v2);
422 if ((v1 == v2) || (v1 < 0) || (v1 >= pg->
vcount) || (v2 < 0) ||
433 "than the initial allocation size allows"));
451 struct seg_intersections *si;
453 struct intersection_point *ip;
465 for (i = 0; i < si->ipcount; i++) {
473 for (i = 0; i < si->ilcount; i++) {
474 v = si->ip[si->il[i].a[0].ip].group;
475 for (j = 1; j < si->il[i].count; j++) {
476 t = si->ip[si->il[i].a[j].ip].group;
485 for (i = 0; i < pg->
vcount; i++) {
488 for (j = 0; j < vert->
ecount; j++) {
489 edge = vert->
edges[j];
490 t = (edge->
v1 != i) ? (edge->
v1) : (edge->
v2);
492 atan2(pg->
v[t].
y - vert->
y, pg->
v[t].
x - vert->
x);
517 for (i = 0; i < pg->
vcount; i++) {
518 G_debug(4,
" vertex %d (%g, %g)", i, pg->
v[i].
x, pg->
v[i].
y);
519 for (j = 0; j < pg->
v[i].
ecount; j++) {
void pg_addedge(struct planar_graph *pg, int v1, int v2)
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
void sort_intersection_list(struct seg_intersection_list *il)
void pg_destroy_struct(struct planar_graph *pg)
void add_ipoint(const struct line_pnts *Points, int first_seg, int second_seg, double x, double y, struct seg_intersections *si)
void pg_addedge1(struct pg_vertex *v, struct pg_edge *e)
int n_points
Number of points.
#define FEQUAL(X, Y, TOL)
struct planar_graph * pg_create_struct(int n, int e)
void G_free(void *)
Free allocated memory.
int pg_existsedge(struct planar_graph *pg, int v1, int v2)
double * x
Array of X coordinates.
Feature geometry info - coordinates.
struct planar_graph * pg_create(const struct line_pnts *Points)
int segment_intersection_2d(double ax1, double ay1, double ax2, double ay2, double bx1, double by1, double bx2, double by2, double *x1, double *y1, double *x2, double *y2)
double * y
Array of Y coordinates.
int compare(const void *a, const void *b)
struct seg_intersections * create_si_struct(int segments_count)
void destroy_si_struct(struct seg_intersections *si)
double get_epsilon(struct line_pnts *Points)
struct seg_intersections * find_all_intersections(const struct line_pnts *Points)
void add_ipoint1(struct seg_intersection_list *il, int with, double dist, int ip)
int G_debug(int, const char *,...) __attribute__((format(printf