29 #define D ((ax2 - ax1) * (by1 - by2) - (ay2 - ay1) * (bx1 - bx2))
30 #define DA ((bx1 - ax1) * (by1 - by2) - (by1 - ay1) * (bx1 - bx2))
31 #define DB ((ax2 - ax1) * (by1 - ay1) - (ay2 - ay1) * (bx1 - ax1))
33 #ifdef ASDASDASFDSAFFDAS
34 mpf_t p11, p12, p21, p22, t1, t2;
35 mpf_t dd, dda, ddb, delta;
40 void initialize_mpf_vars()
42 mpf_set_default_prec(2048);
68 void det22(mpf_t rop,
double a11,
double b11,
double a12,
double b12,
69 double a21,
double b21,
double a22,
double b22)
84 mpf_mul(t1, p11, p22);
85 mpf_mul(t2, p12, p21);
91 void swap(
double *a,
double *
b)
101 int segment_intersection_2d_e(
double ax1,
double ay1,
double ax2,
double ay2,
102 double bx1,
double by1,
double bx2,
double by2,
103 double *x1,
double *y1,
double *x2,
double *y2)
107 double max_ax, min_ax, max_ay, min_ay;
109 double max_bx, min_bx, max_by, min_by;
111 int sgn_d, sgn_da, sgn_db;
115 int f11, f12, f21, f22;
122 initialize_mpf_vars();
125 G_debug(3,
"segment_intersection_2d_e()");
126 G_debug(4,
" ax1 = %.18f, ay1 = %.18f", ax1, ay1);
127 G_debug(4,
" ax2 = %.18f, ay2 = %.18f", ax2, ay2);
128 G_debug(4,
" bx1 = %.18f, by1 = %.18f", bx1, by1);
129 G_debug(4,
" bx2 = %.18f, by2 = %.18f", bx2, by2);
131 f11 = ((ax1 == bx1) && (ay1 == by1));
132 f12 = ((ax1 == bx2) && (ay1 == by2));
133 f21 = ((ax2 == bx1) && (ay2 == by1));
134 f22 = ((ax2 == bx2) && (ay2 == by2));
137 if ((f11 && f22) || (f12 && f21)) {
138 G_debug(3,
" identical segments");
147 G_debug(3,
" connected by endpoints");
153 G_debug(3,
" connected by endpoints");
159 if ((
MAX(ax1, ax2) <
MIN(bx1, bx2)) || (
MAX(bx1, bx2) <
MIN(ax1, ax2))) {
160 G_debug(3,
" no intersection (disjoint bounding boxes)");
163 if ((
MAX(ay1, ay2) <
MIN(by1, by2)) || (
MAX(by1, by2) <
MIN(ay1, ay2))) {
164 G_debug(3,
" no intersection (disjoint bounding boxes)");
168 det22(dd, ax2, ax1, bx1, bx2, ay2, ay1, by1, by2);
171 G_debug(3,
" general position");
173 det22(dda, bx1, ax1, bx1, bx2, by1, ay1, by1, by2);
174 sgn_da = mpf_sgn(dda);
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");
198 if ((sgn_da > 0) || (mpf_cmp(dda, dd) < 0)) {
199 G_debug(3,
" no intersection");
203 det22(ddb, ax2, ax1, bx1, ax1, ay2, ay1, by1, ay1);
204 sgn_db = mpf_sgn(ddb);
205 if ((sgn_db > 0) || (mpf_cmp(ddb, dd) < 0)) {
206 G_debug(3,
" no intersection");
217 mpf_set_d(delta, ax2 - ax1);
218 mpf_mul(t1, dda, delta);
220 *x1 = ax1 + mpf_get_d(t2);
222 mpf_set_d(delta, ay2 - ay1);
223 mpf_mul(t1, dda, delta);
225 *y1 = ay1 + mpf_get_d(t2);
227 G_debug(3,
" intersection %.16g, %.16g", *x1, *y1);
232 det22(dda, bx1, ax1, bx1, bx2, by1, ay1, by1, by2);
233 sgn_da = mpf_sgn(dda);
236 G_debug(3,
" parallel segments");
249 else if (ax1 == ax2) {
260 else if (bx1 == bx2) {
267 G_debug(3,
" collinear segments");
269 if ((bx2 < ax1) || (bx1 > ax2)) {
270 G_debug(3,
" no intersection");
278 if ((ax1 < bx1) && (ax2 > bx2)) {
296 if ((ax1 > bx1) && (ax2 < bx2)) {
314 G_debug(3,
" partial overlap");
315 if ((bx1 > ax1) && (bx1 < ax2)) {
330 if ((bx2 > ax1) && (bx2 < ax2)) {
347 G_warning((
"segment_intersection_2d() ERROR (should not be reached)"));
362 double bx1,
double by1,
double bx2,
double by2,
363 double *x1,
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);
384 G_debug(2,
" -> identical segments");
395 else if (bx1 == ax1) {
398 else if (bx2 == ax2) {
401 else if (by1 == ay1) {
423 d = (ax2 - ax1) * (by1 - by2) - (ay2 - ay1) * (bx1 - bx2);
424 d1 = (bx1 - ax1) * (by1 - by2) - (by1 - ay1) * (bx1 - bx2);
425 d2 = (ax2 - ax1) * (by1 - ay1) - (ay2 - ay1) * (bx1 - ax1);
431 tola = tol /
MAX(fabs(ax2 - ax1), fabs(ay2 - ay1));
432 tolb = tol /
MAX(fabs(bx2 - bx1), fabs(by2 - by1));
433 G_debug(2,
" tol = %.18g", tol);
434 G_debug(2,
" tola = %.18g", tola);
435 G_debug(2,
" tolb = %.18g", tolb);
436 if (!
FZERO(d, tol)) {
440 G_debug(2,
" not parallel/collinear: ra = %.18g", ra);
443 if ((ra <= -tola) || (ra >= 1 + tola) || (rb <= -tolb) ||
445 G_debug(2,
" no intersection");
450 *x1 = ax1 + ra * (ax2 - ax1);
451 *y1 = ay1 + ra * (ay2 - ay1);
453 G_debug(2,
" intersection %.18f, %.18f", *x1, *y1);
458 G_debug(3,
" -> parallel/collinear");
477 G_debug(2,
" -> collinear vertical");
488 if (ay1 > by2 || ay2 < by1) {
489 G_debug(2,
" -> no intersection");
494 if (
FEQUAL(ay1, by2, tol)) {
497 G_debug(2,
" -> connected by end points");
500 if (
FEQUAL(ay2, by1, tol)) {
503 G_debug(2,
" -> connected by end points");
508 G_debug(3,
" -> vertical overlap");
510 if (ay1 <= by1 && ay2 >= by2) {
511 G_debug(2,
" -> a contains b");
522 if (ay1 >= by1 && ay2 <= by2) {
523 G_debug(2,
" -> b contains a");
535 G_debug(2,
" -> partial overlap");
536 if (by1 > ay1 && by1 < ay2) {
552 if (by2 > ay1 && by2 < ay2) {
570 "Vect_segment_intersection() ERROR (collinear vertical segments)"));
579 G_debug(2,
" -> collinear non vertical");
582 if ((bx1 > ax1 && bx2 > ax1 && bx1 > ax2 && bx2 > ax2) ||
583 (bx1 < ax1 && bx2 < ax1 && bx1 < ax2 && bx2 < ax2)) {
584 G_debug(2,
" -> no intersection");
589 G_debug(2,
" -> overlap/connected end points");
592 if ((ax1 == bx1 && ay1 == by1) || (ax1 == bx2 && ay1 == by2)) {
595 G_debug(2,
" -> connected by end points");
598 if ((ax2 == bx1 && ay2 == by1) || (ax2 == bx2 && ay2 == by2)) {
601 G_debug(2,
" -> connected by end points");
623 if (ax1 <= bx1 && ax2 >= bx2) {
624 G_debug(2,
" -> a contains b");
635 if (ax1 >= bx1 && ax2 <= bx2) {
636 G_debug(2,
" -> b contains a");
648 G_debug(2,
" -> partial overlap");
649 if (bx1 > ax1 && bx1 < ax2) {
664 if (bx2 > ax1 && bx2 < ax2) {
682 (
"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");
818 *x1 = ax1 + (ax2 - ax1) * da / d;
819 *y1 = ay1 + (ay2 - ay1) * da / d;
821 G_debug(DLEVEL,
" intersection %.16g, %.16g", *x1, *y1);
828 if ((da != 0) || (db != 0)) {
830 G_debug(DLEVEL,
" parallel segments");
836 G_debug(DLEVEL,
" collinear segments");
838 if ((bx2 < ax1) || (bx1 > ax2)) {
839 G_debug(DLEVEL,
" no intersection");
847 if ((ax1 < bx1) && (ax2 > bx2)) {
848 G_debug(DLEVEL,
" a contains b");
865 if ((ax1 > bx1) && (ax2 < bx2)) {
866 G_debug(DLEVEL,
" b contains a");
883 G_debug(DLEVEL,
" partial overlap");
884 if ((bx1 > ax1) && (bx1 < ax2)) {
899 if ((bx2 > ax1) && (bx2 < ax2)) {
916 G_warning((
"segment_intersection_2d() ERROR (should not be reached)"));
935 if (a == 0 ||
b == 0) {
943 return (bits >
N + abs(ea - eb));
945 return (e < ea -
N + bits);
949 int segment_intersection_2d_test(
double ax1,
double ay1,
double ax2,
double ay2,
950 double bx1,
double by1,
double bx2,
double by2,
951 double *x1,
double *y1,
double *x2,
double *y2)
955 double max_ax, min_ax, max_ay, min_ay;
957 double max_bx, min_bx, max_by, min_by;
959 int sgn_d, sgn_da, sgn_db;
963 int f11, f12, f21, f22;
969 double d, da, db, ra, rb;
972 initialize_mpf_vars();
975 G_debug(3,
"segment_intersection_2d_test()");
976 G_debug(3,
" ax1 = %.18e, ay1 = %.18e", ax1, ay1);
977 G_debug(3,
" ax2 = %.18e, ay2 = %.18e", ax2, ay2);
978 G_debug(3,
" bx1 = %.18e, by1 = %.18e", bx1, by1);
979 G_debug(3,
" bx2 = %.18e, by2 = %.18e", bx2, by2);
981 f11 = ((ax1 == bx1) && (ay1 == by1));
982 f12 = ((ax1 == bx2) && (ay1 == by2));
983 f21 = ((ax2 == bx1) && (ay2 == by1));
984 f22 = ((ax2 == bx2) && (ay2 == by2));
987 if ((f11 && f22) || (f12 && f21)) {
988 G_debug(4,
" identical segments");
997 G_debug(4,
" connected by endpoints");
1003 G_debug(4,
" connected by endpoints");
1009 if ((
MAX(ax1, ax2) <
MIN(bx1, bx2)) || (
MAX(bx1, bx2) <
MIN(ax1, ax2))) {
1010 G_debug(4,
" no intersection (disjoint bounding boxes)");
1013 if ((
MAX(ay1, ay2) <
MIN(by1, by2)) || (
MAX(by1, by2) <
MIN(ay1, ay2))) {
1014 G_debug(4,
" no intersection (disjoint bounding boxes)");
1018 d = (ax2 - ax1) * (by1 - by2) - (ay2 - ay1) * (bx1 - bx2);
1019 da = (bx1 - ax1) * (by1 - by2) - (by1 - ay1) * (bx1 - bx2);
1020 db = (ax2 - ax1) * (by1 - ay1) - (ay2 - ay1) * (bx1 - ax1);
1022 det22(dd, ax2, ax1, bx1, bx2, ay2, ay1, by1, by2);
1023 sgn_d = mpf_sgn(dd);
1024 s = mpf_get_str(
NULL, &exp, 10, 40, dd);
1025 G_debug(3,
" dd = %sE%d", (s[0] == 0) ?
"0" : s, exp);
1029 G_debug(3,
" general position");
1031 det22(dda, bx1, ax1, bx1, bx2, by1, ay1, by1, by2);
1032 det22(ddb, ax2, ax1, bx1, ax1, ay2, ay1, by1, ay1);
1033 sgn_da = mpf_sgn(dda);
1034 sgn_db = mpf_sgn(ddb);
1038 mpf_div(rra, dda, dd);
1039 mpf_div(rrb, ddb, dd);
1041 s = mpf_get_str(
NULL, &exp, 10, 40, rra);
1042 G_debug(4,
" rra = %sE%d", (s[0] == 0) ?
"0" : s, exp);
1043 G_debug(4,
" ra = %.18E", ra);
1044 s = mpf_get_str(
NULL, &exp, 10, 40, rrb);
1045 G_debug(4,
" rrb = %sE%d", (s[0] == 0) ?
"0" : s, exp);
1046 G_debug(4,
" rb = %.18E", rb);
1049 if ((sgn_da < 0) || (mpf_cmp(dda, dd) > 0)) {
1050 G_debug(DLEVEL,
" no intersection");
1054 if ((sgn_db < 0) || (mpf_cmp(ddb, dd) > 0)) {
1055 G_debug(DLEVEL,
" no intersection");
1060 if ((sgn_da > 0) || (mpf_cmp(dda, dd) < 0)) {
1061 G_debug(DLEVEL,
" no intersection");
1065 if ((sgn_db > 0) || (mpf_cmp(ddb, dd) < 0)) {
1066 G_debug(DLEVEL,
" no intersection");
1071 mpf_set_d(delta, ax2 - ax1);
1072 mpf_mul(t1, dda, delta);
1073 mpf_div(t2, t1, dd);
1074 *x1 = ax1 + mpf_get_d(t2);
1076 mpf_set_d(delta, ay2 - ay1);
1077 mpf_mul(t1, dda, delta);
1078 mpf_div(t2, t1, dd);
1079 *y1 = ay1 + mpf_get_d(t2);
1081 G_debug(2,
" intersection at:");
1082 G_debug(2,
" xx = %.18e", *x1);
1083 G_debug(2,
" x = %.18e", ax1 + ra * (ax2 - ax1));
1084 G_debug(2,
" yy = %.18e", *y1);
1085 G_debug(2,
" y = %.18e", ay1 + ra * (ay2 - ay1));
1089 G_debug(3,
" parallel/collinear...");
void G_warning(const char *,...) __attribute__((format(printf
int G_debug(int, const char *,...) __attribute__((format(printf
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)
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 almost_equal(double a, double b, int bits)
#define FEQUAL(X, Y, TOL)