/************************************************************** * 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 */ }