intersect.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /**************************************************************
  2. * find interesection between two lines defined by points on the lines
  3. * line segment A is (ax1,ay1) to (ax2,ay2)
  4. * line segment B is (bx1,by1) to (bx2,by2)
  5. * returns
  6. * -1 segment A and B do not intersect (parallel without overlap)
  7. * 0 segment A and B do not intersect but extensions do intersect
  8. * 1 intersection is a single point
  9. * 2 intersection is a line segment (colinear with overlap)
  10. * x,y intersection point
  11. * ra - ratio that the intersection divides A
  12. * rb - ratio that the intersection divides B
  13. *
  14. * B2
  15. * /
  16. * /
  17. * r=p/(p+q) : A1---p-------*--q------A2
  18. * /
  19. * /
  20. * B1
  21. *
  22. **************************************************************/
  23. /**************************************************************
  24. *
  25. * A point P which lies on line defined by points A1=(x1,y1) and A2=(x2,y2)
  26. * is given by the equation r * (x2,y2) + (1-r) * (x1,y1).
  27. * if r is between 0 and 1, p lies between A1 and A2.
  28. *
  29. * Suppose points on line (A1, A2) has equation
  30. * (x,y) = ra * (ax2,ay2) + (1-ra) * (ax1,ay1)
  31. * or for x and y separately
  32. * x = ra * ax2 - ra * ax1 + ax1
  33. * y = ra * ay2 - ra * ay1 + ay1
  34. * and the points on line (B1, B2) are represented by
  35. * (x,y) = rb * (bx2,by2) + (1-rb) * (bx1,by1)
  36. * or for x and y separately
  37. * x = rb * bx2 - rb * bx1 + bx1
  38. * y = rb * by2 - rb * by1 + by1
  39. *
  40. * when the lines intersect, the point (x,y) has to
  41. * satisfy a system of 2 equations:
  42. * ra * ax2 - ra * ax1 + ax1 = rb * bx2 - rb * bx1 + bx1
  43. * ra * ay2 - ra * ay1 + ay1 = rb * by2 - rb * by1 + by1
  44. *
  45. * or
  46. *
  47. * (ax2 - ax1) * ra - (bx2 - bx1) * rb = bx1 - ax1
  48. * (ay2 - ay1) * ra - (by2 - by1) * rb = by1 - ay1
  49. *
  50. * by Cramer's method, one can solve this by computing 3
  51. * determinants of matrices:
  52. *
  53. * M = (ax2-ax1) (bx1-bx2)
  54. * (ay2-ay1) (by1-by2)
  55. *
  56. * M1 = (bx1-ax1) (bx1-bx2)
  57. * (by1-ay1) (by1-by2)
  58. *
  59. * M2 = (ax2-ax1) (bx1-ax1)
  60. * (ay2-ay1) (by1-ay1)
  61. *
  62. * Which are exactly the determinants D, D2, D1 below:
  63. *
  64. * D ((ax2-ax1)*(by1-by2) - (ay2-ay1)*(bx1-bx2))
  65. *
  66. * D1 ((bx1-ax1)*(by1-by2) - (by1-ay1)*(bx1-bx2))
  67. *
  68. * D2 ((ax2-ax1)*(by1-ay1) - (ay2-ay1)*(bx1-ax1))
  69. ***********************************************************************/
  70. #define D ((ax2-ax1)*(by1-by2) - (ay2-ay1)*(bx1-bx2))
  71. #define D1 ((bx1-ax1)*(by1-by2) - (by1-ay1)*(bx1-bx2))
  72. #define D2 ((ax2-ax1)*(by1-ay1) - (ay2-ay1)*(bx1-ax1))
  73. #define SWAP(x,y) {int t; t=x; x=y; y=t;}
  74. int G_intersect_line_segments(double ax1, double ay1, double ax2, double ay2,
  75. double bx1, double by1, double bx2, double by2,
  76. double *ra, double *rb, double *x, double *y)
  77. {
  78. double d;
  79. d = D;
  80. if (d) { /* lines are not parallel */
  81. *ra = D1 / d;
  82. *rb = D2 / d;
  83. *x = ax1 + (*ra) * (ax2 - ax1);
  84. *y = ay1 + (*ra) * (ay2 - ay1);
  85. return (*ra >= 0.0 && *ra <= 1.0 && *rb >= 0.0 && *rb <= 1.0);
  86. }
  87. if (D1 || D2)
  88. return -1; /* lines are parallel, not colinear */
  89. if (ax1 > ax2) {
  90. SWAP(ax1, ax2)
  91. }
  92. if (bx1 > bx2) {
  93. SWAP(bx1, bx2)
  94. }
  95. if (ax1 > bx2)
  96. return -1;
  97. if (ax2 < bx1)
  98. return -1;
  99. /* there is overlap */
  100. if (ax1 == bx2) {
  101. *x = ax1;
  102. *y = ay1;
  103. return 1; /* at endpoints only */
  104. }
  105. if (ax2 == bx1) {
  106. *x = ax2;
  107. *y = ay2;
  108. return 1; /* at endpoints only */
  109. }
  110. return 2; /* colinear with overlap on an interval, not just a single point */
  111. }