23 #define SWAP(a,b) {double t = a; a = b; b = t;} 25 #define MIN(X,Y) ((X<Y)?X:Y) 28 #define MAX(X,Y) ((X>Y)?X:Y) 30 #define D ((ax2-ax1)*(by1-by2) - (ay2-ay1)*(bx1-bx2)) 31 #define DA ((bx1-ax1)*(by1-by2) - (by1-ay1)*(bx1-bx2)) 32 #define DB ((ax2-ax1)*(by1-ay1) - (ay2-ay1)*(bx1-ax1)) 35 #ifdef ASDASDASFDSAFFDAS 36 mpf_t p11, p12, p21, p22, t1, t2;
37 mpf_t dd, dda, ddb, delta;
42 void initialize_mpf_vars()
44 mpf_set_default_prec(2048);
70 void det22(mpf_t rop,
double a11,
double b11,
double a12,
double b12,
71 double a21,
double b21,
double a22,
double b22)
86 mpf_mul(t1, p11, p22);
87 mpf_mul(t2, p12, p21);
93 void swap(
double *a,
double *
b)
103 int segment_intersection_2d_e(
double ax1,
double ay1,
double ax2,
double ay2,
104 double bx1,
double by1,
double bx2,
double by2,
105 double *x1,
double *y1,
double *x2,
double *y2)
109 double max_ax, min_ax, max_ay, min_ay;
111 double max_bx, min_bx, max_by, min_by;
113 int sgn_d, sgn_da, sgn_db;
117 int f11, f12, f21, f22;
124 initialize_mpf_vars();
127 G_debug(3,
"segment_intersection_2d_e()");
128 G_debug(4,
" ax1 = %.18f, ay1 = %.18f", ax1, ay1);
129 G_debug(4,
" ax2 = %.18f, ay2 = %.18f", ax2, ay2);
130 G_debug(4,
" bx1 = %.18f, by1 = %.18f", bx1, by1);
131 G_debug(4,
" bx2 = %.18f, by2 = %.18f", bx2, by2);
133 f11 = ((ax1 == bx1) && (ay1 == by1));
134 f12 = ((ax1 == bx2) && (ay1 == by2));
135 f21 = ((ax2 == bx1) && (ay2 == by1));
136 f22 = ((ax2 == bx2) && (ay2 == by2));
139 if ((f11 && f22) || (f12 && f21)) {
140 G_debug(3,
" identical segments");
149 G_debug(3,
" connected by endpoints");
155 G_debug(3,
" connected by endpoints");
161 if ((
MAX(ax1, ax2) <
MIN(bx1, bx2)) || (
MAX(bx1, bx2) <
MIN(ax1, ax2))) {
162 G_debug(3,
" no intersection (disjoint bounding boxes)");
165 if ((
MAX(ay1, ay2) <
MIN(by1, by2)) || (
MAX(by1, by2) <
MIN(ay1, ay2))) {
166 G_debug(3,
" no intersection (disjoint bounding boxes)");
170 det22(dd, ax2, ax1, bx1, bx2, ay2, ay1, by1, by2);
173 G_debug(3,
" general position");
175 det22(dda, bx1, ax1, bx1, bx2, by1, ay1, by1, by2);
176 sgn_da = mpf_sgn(dda);
187 if ((sgn_da < 0) || (mpf_cmp(dda, dd) > 0)) {
188 G_debug(3,
" no intersection");
192 det22(ddb, ax2, ax1, bx1, ax1, ay2, ay1, by1, ay1);
193 sgn_db = mpf_sgn(ddb);
194 if ((sgn_db < 0) || (mpf_cmp(ddb, dd) > 0)) {
195 G_debug(3,
" no intersection");
200 if ((sgn_da > 0) || (mpf_cmp(dda, dd) < 0)) {
201 G_debug(3,
" no intersection");
205 det22(ddb, ax2, ax1, bx1, ax1, ay2, ay1, by1, ay1);
206 sgn_db = mpf_sgn(ddb);
207 if ((sgn_db > 0) || (mpf_cmp(ddb, dd) < 0)) {
208 G_debug(3,
" no intersection");
216 mpf_set_d(delta, ax2 - ax1);
217 mpf_mul(t1, dda, delta);
219 *x1 = ax1 + mpf_get_d(t2);
221 mpf_set_d(delta, ay2 - ay1);
222 mpf_mul(t1, dda, delta);
224 *y1 = ay1 + mpf_get_d(t2);
226 G_debug(3,
" intersection %.16g, %.16g", *x1, *y1);
231 det22(dda, bx1, ax1, bx1, bx2, by1, ay1, by1, by2);
232 sgn_da = mpf_sgn(dda);
235 G_debug(3,
" parallel segments");
248 else if (ax1 == ax2) {
259 else if (bx1 == bx2) {
266 G_debug(3,
" collinear segments");
268 if ((bx2 < ax1) || (bx1 > ax2)) {
269 G_debug(3,
" no intersection");
277 if ((ax1 < bx1) && (ax2 > bx2)) {
295 if ((ax1 > bx1) && (ax2 < bx2)) {
313 G_debug(3,
" partial overlap");
314 if ((bx1 > ax1) && (bx1 < ax2)) {
329 if ((bx2 > ax1) && (bx2 < ax2)) {
346 G_warning((
"segment_intersection_2d() ERROR (should not be reached)"));
361 double ay2,
double bx1,
double by1,
362 double bx2,
double by2,
double *x1,
363 double *y1,
double *x2,
double *y2,
368 double d, d1, d2, ra, rb,
t;
373 G_debug(4,
"segment_intersection_2d()");
374 G_debug(4,
" ax1 = %.18f, ay1 = %.18f", ax1, ay1);
375 G_debug(4,
" ax2 = %.18f, ay2 = %.18f", ax2, ay2);
376 G_debug(4,
" bx1 = %.18f, by1 = %.18f", bx1, by1);
377 G_debug(4,
" bx2 = %.18f, by2 = %.18f", bx2, by2);
385 G_debug(2,
" -> identical segments");
396 else if (bx1 == ax1) {
399 else if (bx2 == ax2) {
402 else if (by1 == ay1) {
424 d = (ax2 - ax1) * (by1 - by2) - (ay2 - ay1) * (bx1 - bx2);
425 d1 = (bx1 - ax1) * (by1 - by2) - (by1 - ay1) * (bx1 - bx2);
426 d2 = (ax2 - ax1) * (by1 - ay1) - (ay2 - ay1) * (bx1 - ax1);
432 tola = tol /
MAX(fabs(ax2 - ax1), fabs(ay2 - ay1));
433 tolb = tol /
MAX(fabs(bx2 - bx1), fabs(by2 - by1));
434 G_debug(2,
" tol = %.18g", tol);
435 G_debug(2,
" tola = %.18g", tola);
436 G_debug(2,
" tolb = %.18g", tolb);
437 if (!
FZERO(d, tol)) {
441 G_debug(2,
" not parallel/collinear: ra = %.18g", ra);
444 if ((ra <= -tola) || (ra >= 1 + tola) || (rb <= -tolb) ||
446 G_debug(2,
" no intersection");
451 *x1 = ax1 + ra * (ax2 - ax1);
452 *y1 = ay1 + ra * (ay2 - ay1);
454 G_debug(2,
" intersection %.18f, %.18f", *x1, *y1);
459 G_debug(3,
" -> parallel/collinear");
479 G_debug(2,
" -> collinear vertical");
490 if (ay1 > by2 || ay2 < by1) {
491 G_debug(2,
" -> no intersection");
496 if (
FEQUAL(ay1, by2, tol)) {
499 G_debug(2,
" -> connected by end points");
502 if (
FEQUAL(ay2, by1, tol)) {
505 G_debug(2,
" -> connected by end points");
510 G_debug(3,
" -> vertical overlap");
512 if (ay1 <= by1 && ay2 >= by2) {
513 G_debug(2,
" -> a contains b");
524 if (ay1 >= by1 && ay2 <= by2) {
525 G_debug(2,
" -> b contains a");
537 G_debug(2,
" -> partial overlap");
538 if (by1 > ay1 && by1 < ay2) {
554 if (by2 > ay1 && by2 < ay2) {
571 G_warning((
"Vect_segment_intersection() ERROR (collinear vertical segments)"));
580 G_debug(2,
" -> collinear non vertical");
583 if ((bx1 > ax1 && bx2 > ax1 && bx1 > ax2 && bx2 > ax2) ||
584 (bx1 < ax1 && bx2 < ax1 && bx1 < ax2 && bx2 < ax2)) {
585 G_debug(2,
" -> no intersection");
590 G_debug(2,
" -> overlap/connected end points");
593 if ((ax1 == bx1 && ay1 == by1) || (ax1 == bx2 && ay1 == by2)) {
596 G_debug(2,
" -> connected by end points");
599 if ((ax2 == bx1 && ay2 == by1) || (ax2 == bx2 && ay2 == by2)) {
602 G_debug(2,
" -> connected by end points");
624 if (ax1 <= bx1 && ax2 >= bx2) {
625 G_debug(2,
" -> a contains b");
636 if (ax1 >= bx1 && ax2 <= bx2) {
637 G_debug(2,
" -> b contains a");
649 G_debug(2,
" -> partial overlap");
650 if (bx1 > ax1 && bx1 < ax2) {
665 if (bx2 > ax1 && bx2 < ax2) {
682 G_warning((
"segment_intersection_2d() ERROR (collinear non vertical segments)"));
693 double bx1,
double by1,
double bx2,
double by2,
694 double *x1,
double *y1,
double *x2,
double *y2)
696 const int DLEVEL = 4;
700 int f11, f12, f21, f22;
705 G_debug(DLEVEL,
"segment_intersection_2d()");
706 G_debug(4,
" ax1 = %.18f, ay1 = %.18f", ax1, ay1);
707 G_debug(4,
" ax2 = %.18f, ay2 = %.18f", ax2, ay2);
708 G_debug(4,
" bx1 = %.18f, by1 = %.18f", bx1, by1);
709 G_debug(4,
" bx2 = %.18f, by2 = %.18f", bx2, by2);
711 f11 = ((ax1 == bx1) && (ay1 == by1));
712 f12 = ((ax1 == bx2) && (ay1 == by2));
713 f21 = ((ax2 == bx1) && (ay2 == by1));
714 f22 = ((ax2 == bx2) && (ay2 == by2));
717 if ((f11 && f22) || (f12 && f21)) {
718 G_debug(DLEVEL,
" identical segments");
727 G_debug(DLEVEL,
" connected by endpoints");
733 G_debug(DLEVEL,
" connected by endpoints");
739 if ((
MAX(ax1, ax2) <
MIN(bx1, bx2)) || (
MAX(bx1, bx2) <
MIN(ax1, ax2))) {
740 G_debug(DLEVEL,
" no intersection (disjoint bounding boxes)");
743 if ((
MAX(ay1, ay2) <
MIN(by1, by2)) || (
MAX(by1, by2) <
MIN(ay1, ay2))) {
744 G_debug(DLEVEL,
" no intersection (disjoint bounding boxes)");
755 else if (ax1 == ax2) {
766 else if (bx1 == bx2) {
775 G_debug(DLEVEL,
" general position");
788 if ((da < 0) || (da > d)) {
789 G_debug(DLEVEL,
" no intersection");
794 if ((db < 0) || (db > d)) {
795 G_debug(DLEVEL,
" no intersection");
800 if ((da > 0) || (da < d)) {
801 G_debug(DLEVEL,
" no intersection");
806 if ((db > 0) || (db < d)) {
807 G_debug(DLEVEL,
" no intersection");
815 *x1 = ax1 + (ax2 - ax1) * da / d;
816 *y1 = ay1 + (ay2 - ay1) * da / d;
818 G_debug(DLEVEL,
" intersection %.16g, %.16g", *x1, *y1);
825 if ((da != 0) || (db != 0)) {
827 G_debug(DLEVEL,
" parallel segments");
833 G_debug(DLEVEL,
" collinear segments");
835 if ((bx2 < ax1) || (bx1 > ax2)) {
836 G_debug(DLEVEL,
" no intersection");
844 if ((ax1 < bx1) && (ax2 > bx2)) {
845 G_debug(DLEVEL,
" a contains b");
862 if ((ax1 > bx1) && (ax2 < bx2)) {
863 G_debug(DLEVEL,
" b contains a");
880 G_debug(DLEVEL,
" partial overlap");
881 if ((bx1 > ax1) && (bx1 < ax2)) {
896 if ((bx2 > ax1) && (bx2 < ax2)) {
913 G_warning((
"segment_intersection_2d() ERROR (should not be reached)"));
932 if (a == 0 || b == 0) {
940 return (bits >
N + abs(ea - eb));
942 return (e < ea -
N + bits);
946 int segment_intersection_2d_test(
double ax1,
double ay1,
double ax2,
947 double ay2,
double bx1,
double by1,
948 double bx2,
double by2,
double *x1,
949 double *y1,
double *x2,
double *y2)
953 double max_ax, min_ax, max_ay, min_ay;
955 double max_bx, min_bx, max_by, min_by;
957 int sgn_d, sgn_da, sgn_db;
961 int f11, f12, f21, f22;
967 double d, da, db, ra, rb;
970 initialize_mpf_vars();
973 G_debug(3,
"segment_intersection_2d_test()");
974 G_debug(3,
" ax1 = %.18e, ay1 = %.18e", ax1, ay1);
975 G_debug(3,
" ax2 = %.18e, ay2 = %.18e", ax2, ay2);
976 G_debug(3,
" bx1 = %.18e, by1 = %.18e", bx1, by1);
977 G_debug(3,
" bx2 = %.18e, by2 = %.18e", bx2, by2);
979 f11 = ((ax1 == bx1) && (ay1 == by1));
980 f12 = ((ax1 == bx2) && (ay1 == by2));
981 f21 = ((ax2 == bx1) && (ay2 == by1));
982 f22 = ((ax2 == bx2) && (ay2 == by2));
985 if ((f11 && f22) || (f12 && f21)) {
986 G_debug(4,
" identical segments");
995 G_debug(4,
" connected by endpoints");
1001 G_debug(4,
" connected by endpoints");
1007 if ((
MAX(ax1, ax2) <
MIN(bx1, bx2)) || (
MAX(bx1, bx2) <
MIN(ax1, ax2))) {
1008 G_debug(4,
" no intersection (disjoint bounding boxes)");
1011 if ((
MAX(ay1, ay2) <
MIN(by1, by2)) || (
MAX(by1, by2) <
MIN(ay1, ay2))) {
1012 G_debug(4,
" no intersection (disjoint bounding boxes)");
1016 d = (ax2 - ax1) * (by1 - by2) - (ay2 - ay1) * (bx1 - bx2);
1017 da = (bx1 - ax1) * (by1 - by2) - (by1 - ay1) * (bx1 - bx2);
1018 db = (ax2 - ax1) * (by1 - ay1) - (ay2 - ay1) * (bx1 - ax1);
1020 det22(dd, ax2, ax1, bx1, bx2, ay2, ay1, by1, by2);
1021 sgn_d = mpf_sgn(dd);
1022 s = mpf_get_str(
NULL, &exp, 10, 40, dd);
1023 G_debug(3,
" dd = %sE%d", (s[0] == 0) ?
"0" : s, exp);
1027 G_debug(3,
" general position");
1029 det22(dda, bx1, ax1, bx1, bx2, by1, ay1, by1, by2);
1030 det22(ddb, ax2, ax1, bx1, ax1, ay2, ay1, by1, ay1);
1031 sgn_da = mpf_sgn(dda);
1032 sgn_db = mpf_sgn(ddb);
1036 mpf_div(rra, dda, dd);
1037 mpf_div(rrb, ddb, dd);
1039 s = mpf_get_str(
NULL, &exp, 10, 40, rra);
1040 G_debug(4,
" rra = %sE%d", (s[0] == 0) ?
"0" : s, exp);
1041 G_debug(4,
" ra = %.18E", ra);
1042 s = mpf_get_str(
NULL, &exp, 10, 40, rrb);
1043 G_debug(4,
" rrb = %sE%d", (s[0] == 0) ?
"0" : s, exp);
1044 G_debug(4,
" rb = %.18E", rb);
1047 if ((sgn_da < 0) || (mpf_cmp(dda, dd) > 0)) {
1048 G_debug(DLEVEL,
" no intersection");
1052 if ((sgn_db < 0) || (mpf_cmp(ddb, dd) > 0)) {
1053 G_debug(DLEVEL,
" no intersection");
1058 if ((sgn_da > 0) || (mpf_cmp(dda, dd) < 0)) {
1059 G_debug(DLEVEL,
" no intersection");
1063 if ((sgn_db > 0) || (mpf_cmp(ddb, dd) < 0)) {
1064 G_debug(DLEVEL,
" no intersection");
1069 mpf_set_d(delta, ax2 - ax1);
1070 mpf_mul(t1, dda, delta);
1071 mpf_div(t2, t1, dd);
1072 *x1 = ax1 + mpf_get_d(t2);
1074 mpf_set_d(delta, ay2 - ay1);
1075 mpf_mul(t1, dda, delta);
1076 mpf_div(t2, t1, dd);
1077 *y1 = ay1 + mpf_get_d(t2);
1079 G_debug(2,
" intersection at:");
1080 G_debug(2,
" xx = %.18e", *x1);
1081 G_debug(2,
" x = %.18e", ax1 + ra * (ax2 - ax1));
1082 G_debug(2,
" yy = %.18e", *y1);
1083 G_debug(2,
" y = %.18e", ay1 + ra * (ay2 - ay1));
1087 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)
void G_warning(const char *,...) __attribute__((format(printf
int almost_equal(double a, double b, int bits)
int G_debug(int, const char *,...) __attribute__((format(printf