6 #define SWAP(a,b) {t = a; a = b; b = t;}
8 #define MIN(X,Y) ((X<Y)?X:Y)
11 #define MAX(X,Y) ((X>Y)?X:Y)
13 #define D (ax2-ax1)*(by1-by2) - (ay2-ay1)*(bx1-bx2)
14 #define DA (bx1-ax1)*(by1-by2) - (by1-ay1)*(bx1-bx2)
15 #define DB (ax2-ax1)*(by1-ay1) - (ay2-ay1)*(bx1-ax1)
18 #ifdef ASDASDASFDSAFFDAS
19 mpf_t p11, p12, p21, p22, t1, t2;
21 mpf_t dd, dda, ddb, delta;
27 void initialize_mpf_vars()
29 mpf_set_default_prec(2048);
55 void det22(mpf_t rop,
double a11,
double b11,
double a12,
double b12,
56 double a21,
double b21,
double a22,
double b22)
71 mpf_mul(t1, p11, p22);
72 mpf_mul(t2, p12, p21);
78 void swap(
double *a,
double *
b)
88 int segment_intersection_2d_e(
double ax1,
double ay1,
double ax2,
double ay2,
89 double bx1,
double by1,
double bx2,
double by2,
90 double *x1,
double *y1,
double *x2,
double *y2)
94 double max_ax, min_ax, max_ay, min_ay;
96 double max_bx, min_bx, max_by, min_by;
98 int sgn_d, sgn_da, sgn_db;
102 int f11, f12, f21, f22;
109 initialize_mpf_vars();
112 G_debug(3,
"segment_intersection_2d_e()");
113 G_debug(4,
" ax1 = %.18f, ay1 = %.18f", ax1, ay1);
114 G_debug(4,
" ax2 = %.18f, ay2 = %.18f", ax2, ay2);
115 G_debug(4,
" bx1 = %.18f, by1 = %.18f", bx1, by1);
116 G_debug(4,
" bx2 = %.18f, by2 = %.18f", bx2, by2);
118 f11 = ((ax1 == bx1) && (ay1 == by1));
119 f12 = ((ax1 == bx2) && (ay1 == by2));
120 f21 = ((ax2 == bx1) && (ay2 == by1));
121 f22 = ((ax2 == bx2) && (ay2 == by2));
124 if ((f11 && f22) || (f12 && f21)) {
125 G_debug(3,
" identical segments");
134 G_debug(3,
" connected by endpoints");
140 G_debug(3,
" connected by endpoints");
146 if ((
MAX(ax1, ax2) <
MIN(bx1, bx2)) || (
MAX(bx1, bx2) <
MIN(ax1, ax2))) {
147 G_debug(3,
" no intersection (disjoint bounding boxes)");
150 if ((
MAX(ay1, ay2) <
MIN(by1, by2)) || (
MAX(by1, by2) <
MIN(ay1, ay2))) {
151 G_debug(3,
" no intersection (disjoint bounding boxes)");
155 det22(dd, ax2, ax1, bx1, bx2, ay2, ay1, by1, by2);
158 G_debug(3,
" general position");
160 det22(dda, bx1, ax1, bx1, bx2, by1, ay1, by1, by2);
161 sgn_da = mpf_sgn(dda);
172 if ((sgn_da < 0) || (mpf_cmp(dda, dd) > 0)) {
173 G_debug(3,
" no intersection");
177 det22(ddb, ax2, ax1, bx1, ax1, ay2, ay1, by1, ay1);
178 sgn_db = mpf_sgn(ddb);
179 if ((sgn_db < 0) || (mpf_cmp(ddb, dd) > 0)) {
180 G_debug(3,
" no intersection");
185 if ((sgn_da > 0) || (mpf_cmp(dda, dd) < 0)) {
186 G_debug(3,
" no intersection");
190 det22(ddb, ax2, ax1, bx1, ax1, ay2, ay1, by1, ay1);
191 sgn_db = mpf_sgn(ddb);
192 if ((sgn_db > 0) || (mpf_cmp(ddb, dd) < 0)) {
193 G_debug(3,
" no intersection");
201 mpf_set_d(delta, ax2 - ax1);
202 mpf_mul(t1, dda, delta);
204 *x1 = ax1 + mpf_get_d(t2);
206 mpf_set_d(delta, ay2 - ay1);
207 mpf_mul(t1, dda, delta);
209 *y1 = ay1 + mpf_get_d(t2);
211 G_debug(3,
" intersection %.16g, %.16g", *x1, *y1);
216 det22(dda, bx1, ax1, bx1, bx2, by1, ay1, by1, by2);
217 sgn_da = mpf_sgn(dda);
220 G_debug(3,
" parallel segments");
233 else if (ax1 == ax2) {
244 else if (bx1 == bx2) {
251 G_debug(3,
" collinear segments");
253 if ((bx2 < ax1) || (bx1 > ax2)) {
254 G_debug(3,
" no intersection");
262 if ((ax1 < bx1) && (ax2 > bx2)) {
280 if ((ax1 > bx1) && (ax2 < bx2)) {
298 G_debug(3,
" partial overlap");
299 if ((bx1 > ax1) && (bx1 < ax2)) {
314 if ((bx2 > ax1) && (bx2 < ax2)) {
331 G_warning((
"segment_intersection_2d() ERROR (should not be reached)"));
346 double ay2,
double bx1,
double by1,
347 double bx2,
double by2,
double *x1,
348 double *y1,
double *x2,
double *y2,
353 double d, d1, d2, ra, rb, t;
358 G_debug(4,
"segment_intersection_2d()");
359 G_debug(4,
" ax1 = %.18f, ay1 = %.18f", ax1, ay1);
360 G_debug(4,
" ax2 = %.18f, ay2 = %.18f", ax2, ay2);
361 G_debug(4,
" bx1 = %.18f, by1 = %.18f", bx1, by1);
362 G_debug(4,
" bx2 = %.18f, by2 = %.18f", bx2, by2);
370 G_debug(2,
" -> identical segments");
381 else if (bx1 == ax1) {
384 else if (bx2 == ax2) {
387 else if (by1 == ay1) {
409 d = (ax2 - ax1) * (by1 - by2) - (ay2 - ay1) * (bx1 - bx2);
410 d1 = (bx1 - ax1) * (by1 - by2) - (by1 - ay1) * (bx1 - bx2);
411 d2 = (ax2 - ax1) * (by1 - ay1) - (ay2 - ay1) * (bx1 - ax1);
417 tola = tol /
MAX(fabs(ax2 - ax1), fabs(ay2 - ay1));
418 tolb = tol /
MAX(fabs(bx2 - bx1), fabs(by2 - by1));
419 G_debug(2,
" tol = %.18g", tol);
420 G_debug(2,
" tola = %.18g", tola);
421 G_debug(2,
" tolb = %.18g", tolb);
422 if (!
FZERO(d, tol)) {
426 G_debug(2,
" not parallel/collinear: ra = %.18g", ra);
429 if ((ra <= -tola) || (ra >= 1 + tola) || (rb <= -tolb) ||
431 G_debug(2,
" no intersection");
436 *x1 = ax1 + ra * (ax2 - ax1);
437 *y1 = ay1 + ra * (ay2 - ay1);
439 G_debug(2,
" intersection %.18f, %.18f", *x1, *y1);
444 G_debug(3,
" -> parallel/collinear");
464 G_debug(2,
" -> collinear vertical");
475 if (ay1 > by2 || ay2 < by1) {
476 G_debug(2,
" -> no intersection");
481 if (
FEQUAL(ay1, by2, tol)) {
484 G_debug(2,
" -> connected by end points");
487 if (
FEQUAL(ay2, by1, tol)) {
490 G_debug(2,
" -> connected by end points");
495 G_debug(3,
" -> vertical overlap");
497 if (ay1 <= by1 && ay2 >= by2) {
498 G_debug(2,
" -> a contains b");
509 if (ay1 >= by1 && ay2 <= by2) {
510 G_debug(2,
" -> b contains a");
522 G_debug(2,
" -> partial overlap");
523 if (by1 > ay1 && by1 < ay2) {
539 if (by2 > ay1 && by2 < ay2) {
556 G_warning((
"Vect_segment_intersection() ERROR (collinear vertical segments)"));
565 G_debug(2,
" -> collinear non vertical");
568 if ((bx1 > ax1 && bx2 > ax1 && bx1 > ax2 && bx2 > ax2) ||
569 (bx1 < ax1 && bx2 < ax1 && bx1 < ax2 && bx2 < ax2)) {
570 G_debug(2,
" -> no intersection");
575 G_debug(2,
" -> overlap/connected end points");
578 if ((ax1 == bx1 && ay1 == by1) || (ax1 == bx2 && ay1 == by2)) {
581 G_debug(2,
" -> connected by end points");
584 if ((ax2 == bx1 && ay2 == by1) || (ax2 == bx2 && ay2 == by2)) {
587 G_debug(2,
" -> connected by end points");
609 if (ax1 <= bx1 && ax2 >= bx2) {
610 G_debug(2,
" -> a contains b");
621 if (ax1 >= bx1 && ax2 <= bx2) {
622 G_debug(2,
" -> b contains a");
634 G_debug(2,
" -> partial overlap");
635 if (bx1 > ax1 && bx1 < ax2) {
650 if (bx2 > ax1 && bx2 < ax2) {
667 G_warning((
"segment_intersection_2d() ERROR (collinear non vertical segments)"));
678 double bx1,
double by1,
double bx2,
double by2,
679 double *x1,
double *y1,
double *x2,
double *y2)
681 const int DLEVEL = 4;
687 int f11, f12, f21, f22;
692 G_debug(DLEVEL,
"segment_intersection_2d()");
693 G_debug(4,
" ax1 = %.18f, ay1 = %.18f", ax1, ay1);
694 G_debug(4,
" ax2 = %.18f, ay2 = %.18f", ax2, ay2);
695 G_debug(4,
" bx1 = %.18f, by1 = %.18f", bx1, by1);
696 G_debug(4,
" bx2 = %.18f, by2 = %.18f", bx2, by2);
698 f11 = ((ax1 == bx1) && (ay1 == by1));
699 f12 = ((ax1 == bx2) && (ay1 == by2));
700 f21 = ((ax2 == bx1) && (ay2 == by1));
701 f22 = ((ax2 == bx2) && (ay2 == by2));
704 if ((f11 && f22) || (f12 && f21)) {
705 G_debug(DLEVEL,
" identical segments");
714 G_debug(DLEVEL,
" connected by endpoints");
720 G_debug(DLEVEL,
" connected by endpoints");
726 if ((
MAX(ax1, ax2) <
MIN(bx1, bx2)) || (
MAX(bx1, bx2) <
MIN(ax1, ax2))) {
727 G_debug(DLEVEL,
" no intersection (disjoint bounding boxes)");
730 if ((
MAX(ay1, ay2) <
MIN(by1, by2)) || (
MAX(by1, by2) <
MIN(ay1, ay2))) {
731 G_debug(DLEVEL,
" no intersection (disjoint bounding boxes)");
737 G_debug(DLEVEL,
" general position");
750 if ((da < 0) || (da > d)) {
751 G_debug(DLEVEL,
" no intersection");
756 if ((db < 0) || (db > d)) {
757 G_debug(DLEVEL,
" no intersection");
762 if ((da > 0) || (da < d)) {
763 G_debug(DLEVEL,
" no intersection");
768 if ((db > 0) || (db < d)) {
769 G_debug(DLEVEL,
" no intersection");
777 *x1 = ax1 + (ax2 - ax1) * da / d;
778 *y1 = ay1 + (ay2 - ay1) * da / d;
780 G_debug(DLEVEL,
" intersection %.16g, %.16g", *x1, *y1);
787 if ((da != 0) || (db != 0)) {
789 G_debug(DLEVEL,
" parallel segments");
802 else if (ax1 == ax2) {
813 else if (bx1 == bx2) {
820 G_debug(DLEVEL,
" collinear segments");
822 if ((bx2 < ax1) || (bx1 > ax2)) {
823 G_debug(DLEVEL,
" no intersection");
831 if ((ax1 < bx1) && (ax2 > bx2)) {
832 G_debug(DLEVEL,
" a contains b");
849 if ((ax1 > bx1) && (ax2 < bx2)) {
850 G_debug(DLEVEL,
" b contains a");
867 G_debug(DLEVEL,
" partial overlap");
868 if ((bx1 > ax1) && (bx1 < ax2)) {
883 if ((bx2 > ax1) && (bx2 < ax2)) {
900 G_warning((
"segment_intersection_2d() ERROR (should not be reached)"));
919 if (a == 0 || b == 0) {
927 return (bits >
N + abs(ea - eb));
929 return (e < ea -
N + bits);
933 int segment_intersection_2d_test(
double ax1,
double ay1,
double ax2,
934 double ay2,
double bx1,
double by1,
935 double bx2,
double by2,
double *x1,
936 double *y1,
double *x2,
double *y2)
940 double max_ax, min_ax, max_ay, min_ay;
942 double max_bx, min_bx, max_by, min_by;
944 int sgn_d, sgn_da, sgn_db;
948 int f11, f12, f21, f22;
954 double d, da, db, ra, rb;
957 initialize_mpf_vars();
960 G_debug(3,
"segment_intersection_2d_test()");
961 G_debug(3,
" ax1 = %.18e, ay1 = %.18e", ax1, ay1);
962 G_debug(3,
" ax2 = %.18e, ay2 = %.18e", ax2, ay2);
963 G_debug(3,
" bx1 = %.18e, by1 = %.18e", bx1, by1);
964 G_debug(3,
" bx2 = %.18e, by2 = %.18e", bx2, by2);
966 f11 = ((ax1 == bx1) && (ay1 == by1));
967 f12 = ((ax1 == bx2) && (ay1 == by2));
968 f21 = ((ax2 == bx1) && (ay2 == by1));
969 f22 = ((ax2 == bx2) && (ay2 == by2));
972 if ((f11 && f22) || (f12 && f21)) {
973 G_debug(4,
" identical segments");
982 G_debug(4,
" connected by endpoints");
988 G_debug(4,
" connected by endpoints");
994 if ((
MAX(ax1, ax2) <
MIN(bx1, bx2)) || (
MAX(bx1, bx2) <
MIN(ax1, ax2))) {
995 G_debug(4,
" no intersection (disjoint bounding boxes)");
998 if ((
MAX(ay1, ay2) <
MIN(by1, by2)) || (
MAX(by1, by2) <
MIN(ay1, ay2))) {
999 G_debug(4,
" no intersection (disjoint bounding boxes)");
1003 d = (ax2 - ax1) * (by1 - by2) - (ay2 - ay1) * (bx1 - bx2);
1004 da = (bx1 - ax1) * (by1 - by2) - (by1 - ay1) * (bx1 - bx2);
1005 db = (ax2 - ax1) * (by1 - ay1) - (ay2 - ay1) * (bx1 - ax1);
1007 det22(dd, ax2, ax1, bx1, bx2, ay2, ay1, by1, by2);
1008 sgn_d = mpf_sgn(dd);
1009 s = mpf_get_str(
NULL, &exp, 10, 40, dd);
1010 G_debug(3,
" dd = %sE%d", (s[0] == 0) ?
"0" : s, exp);
1014 G_debug(3,
" general position");
1016 det22(dda, bx1, ax1, bx1, bx2, by1, ay1, by1, by2);
1017 det22(ddb, ax2, ax1, bx1, ax1, ay2, ay1, by1, ay1);
1018 sgn_da = mpf_sgn(dda);
1019 sgn_db = mpf_sgn(ddb);
1023 mpf_div(rra, dda, dd);
1024 mpf_div(rrb, ddb, dd);
1026 s = mpf_get_str(
NULL, &exp, 10, 40, rra);
1027 G_debug(4,
" rra = %sE%d", (s[0] == 0) ?
"0" : s, exp);
1028 G_debug(4,
" ra = %.18E", ra);
1029 s = mpf_get_str(
NULL, &exp, 10, 40, rrb);
1030 G_debug(4,
" rrb = %sE%d", (s[0] == 0) ?
"0" : s, exp);
1031 G_debug(4,
" rb = %.18E", rb);
1034 if ((sgn_da < 0) || (mpf_cmp(dda, dd) > 0)) {
1035 G_debug(DLEVEL,
" no intersection");
1039 if ((sgn_db < 0) || (mpf_cmp(ddb, dd) > 0)) {
1040 G_debug(DLEVEL,
" no intersection");
1045 if ((sgn_da > 0) || (mpf_cmp(dda, dd) < 0)) {
1046 G_debug(DLEVEL,
" no intersection");
1050 if ((sgn_db > 0) || (mpf_cmp(ddb, dd) < 0)) {
1051 G_debug(DLEVEL,
" no intersection");
1056 mpf_set_d(delta, ax2 - ax1);
1057 mpf_mul(t1, dda, delta);
1058 mpf_div(t2, t1, dd);
1059 *x1 = ax1 + mpf_get_d(t2);
1061 mpf_set_d(delta, ay2 - ay1);
1062 mpf_mul(t1, dda, delta);
1063 mpf_div(t2, t1, dd);
1064 *y1 = ay1 + mpf_get_d(t2);
1066 G_debug(2,
" intersection at:");
1067 G_debug(2,
" xx = %.18e", *x1);
1068 G_debug(2,
" x = %.18e", ax1 + ra * (ax2 - ax1));
1069 G_debug(2,
" yy = %.18e", *y1);
1070 G_debug(2,
" y = %.18e", ay1 + ra * (ay2 - ay1));
1074 G_debug(3,
" parallel/collinear...");
#define FEQUAL(X, Y, TOL)
int segment_intersection_2d_tol(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 tol)
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)
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_debug(int level, const char *msg,...)
Print debugging message.
int almost_equal(double a, double b, int bits)