123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- /**************************************************************
- * find intersection between two lines defined by points on the lines
- * line segment A is (ax1,ay1) to (ax2,ay2)
- * line segment B is (bx1,by1) to (bx2,by2)
- * returns
- * -1 segment A and B do not intersect (parallel without overlap)
- * 0 segment A and B do not intersect but extensions do intersect
- * 1 intersection is a single point
- * 2 intersection is a line segment (colinear with overlap)
- * x,y intersection point
- * ra - ratio that the intersection divides A
- * rb - ratio that the intersection divides B
- *
- * B2
- * /
- * /
- * r=p/(p+q) : A1---p-------*--q------A2
- * /
- * /
- * B1
- *
- **************************************************************/
- /**************************************************************
- *
- * A point P which lies on line defined by points A1=(x1,y1) and A2=(x2,y2)
- * is given by the equation r * (x2,y2) + (1-r) * (x1,y1).
- * if r is between 0 and 1, p lies between A1 and A2.
- *
- * Suppose points on line (A1, A2) has equation
- * (x,y) = ra * (ax2,ay2) + (1-ra) * (ax1,ay1)
- * or for x and y separately
- * x = ra * ax2 - ra * ax1 + ax1
- * y = ra * ay2 - ra * ay1 + ay1
- * and the points on line (B1, B2) are represented by
- * (x,y) = rb * (bx2,by2) + (1-rb) * (bx1,by1)
- * or for x and y separately
- * x = rb * bx2 - rb * bx1 + bx1
- * y = rb * by2 - rb * by1 + by1
- *
- * when the lines intersect, the point (x,y) has to
- * satisfy a system of 2 equations:
- * ra * ax2 - ra * ax1 + ax1 = rb * bx2 - rb * bx1 + bx1
- * ra * ay2 - ra * ay1 + ay1 = rb * by2 - rb * by1 + by1
- *
- * or
- *
- * (ax2 - ax1) * ra - (bx2 - bx1) * rb = bx1 - ax1
- * (ay2 - ay1) * ra - (by2 - by1) * rb = by1 - ay1
- *
- * by Cramer's method, one can solve this by computing 3
- * determinants of matrices:
- *
- * M = (ax2-ax1) (bx1-bx2)
- * (ay2-ay1) (by1-by2)
- *
- * M1 = (bx1-ax1) (bx1-bx2)
- * (by1-ay1) (by1-by2)
- *
- * M2 = (ax2-ax1) (bx1-ax1)
- * (ay2-ay1) (by1-ay1)
- *
- * Which are exactly the determinants D, D2, D1 below:
- *
- * D ((ax2-ax1)*(by1-by2) - (ay2-ay1)*(bx1-bx2))
- *
- * D1 ((bx1-ax1)*(by1-by2) - (by1-ay1)*(bx1-bx2))
- *
- * D2 ((ax2-ax1)*(by1-ay1) - (ay2-ay1)*(bx1-ax1))
- ***********************************************************************/
- #define D ((ax2-ax1)*(by1-by2) - (ay2-ay1)*(bx1-bx2))
- #define D1 ((bx1-ax1)*(by1-by2) - (by1-ay1)*(bx1-bx2))
- #define D2 ((ax2-ax1)*(by1-ay1) - (ay2-ay1)*(bx1-ax1))
- #define SWAP(x,y) {double t; t=x; x=y; y=t;}
- int G_intersect_line_segments(double ax1, double ay1, double ax2, double ay2,
- double bx1, double by1, double bx2, double by2,
- double *ra, double *rb, double *x, double *y)
- {
- double d;
- if (ax1 > ax2 || (ax1 == ax2 && ay1 > ay2)) {
- SWAP(ax1, ax2)
- SWAP(ay1, ay2)
- }
- if (bx1 > bx2 || (bx1 == bx2 && by1 > by2)) {
- SWAP(bx1, bx2)
- SWAP(by1, by2)
- }
- d = D;
- if (d) { /* lines are not parallel */
- *ra = D1 / d;
- *rb = D2 / d;
- *x = ax1 + (*ra) * (ax2 - ax1);
- *y = ay1 + (*ra) * (ay2 - ay1);
- return (*ra >= 0.0 && *ra <= 1.0 && *rb >= 0.0 && *rb <= 1.0);
- }
- /* lines are parallel */
- if (D1 || D2) {
- return -1;
- }
- /* segments are colinear. check for overlap */
- /* Collinear vertical */
- if (ax1 == ax2) {
- if (ay1 > by2) {
- *x = ax1;
- *y = ay1;
- return 0; /* extensions overlap */
- }
- if (ay2 < by1) {
- *x = ax2;
- *y = ay2;
- return 0; /* extensions overlap */
- }
- /* there is overlap */
- if (ay1 == by2) {
- *x = ax1;
- *y = ay1;
- return 1; /* endpoints only */
- }
- if (ay2 == by1) {
- *x = ax2;
- *y = ay2;
- return 1; /* endpoints only */
- }
- /* overlap, no single intersection point */
- if (ay1 > by1 && ay1 < by2) {
- *x = ax1;
- *y = ay1;
- }
- else {
- *x = ax2;
- *y = ay2;
- }
- return 2;
- }
- else {
- if (ax1 > bx2) {
- *x = ax1;
- *y = ay1;
- return 0; /* extensions overlap */
- }
- if (ax2 < bx1) {
- *x = ax2;
- *y = ay2;
- return 0; /* extensions overlap */
- }
- /* there is overlap */
- if (ax1 == bx2) {
- *x = ax1;
- *y = ay1;
- return 1; /* endpoints only */
- }
- if (ax2 == bx1) {
- *x = ax2;
- *y = ay2;
- return 1; /* endpoints only */
- }
-
- /* overlap, no single intersection point */
- if (ax1 > bx1 && ax1 < bx2) {
- *x = ax1;
- *y = ay1;
- }
- else {
- *x = ax2;
- *y = ay2;
- }
- return 2;
- }
- return 0; /* should not be reached */
- }
|