intersect.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /**************************************************************
  2. * find intersection 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) {double 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. if (ax1 > ax2 || (ax1 == ax2 && ay1 > ay2)) {
  80. SWAP(ax1, ax2)
  81. SWAP(ay1, ay2)
  82. }
  83. if (bx1 > bx2 || (bx1 == bx2 && by1 > by2)) {
  84. SWAP(bx1, bx2)
  85. SWAP(by1, by2)
  86. }
  87. d = D;
  88. if (d) { /* lines are not parallel */
  89. *ra = D1 / d;
  90. *rb = D2 / d;
  91. *x = ax1 + (*ra) * (ax2 - ax1);
  92. *y = ay1 + (*ra) * (ay2 - ay1);
  93. return (*ra >= 0.0 && *ra <= 1.0 && *rb >= 0.0 && *rb <= 1.0);
  94. }
  95. /* lines are parallel */
  96. if (D1 || D2) {
  97. return -1;
  98. }
  99. /* segments are colinear. check for overlap */
  100. /* Collinear vertical */
  101. if (ax1 == ax2) {
  102. if (ay1 > by2) {
  103. *x = ax1;
  104. *y = ay1;
  105. return 0; /* extensions overlap */
  106. }
  107. if (ay2 < by1) {
  108. *x = ax2;
  109. *y = ay2;
  110. return 0; /* extensions overlap */
  111. }
  112. /* there is overlap */
  113. if (ay1 == by2) {
  114. *x = ax1;
  115. *y = ay1;
  116. return 1; /* endpoints only */
  117. }
  118. if (ay2 == by1) {
  119. *x = ax2;
  120. *y = ay2;
  121. return 1; /* endpoints only */
  122. }
  123. /* overlap, no single intersection point */
  124. if (ay1 > by1 && ay1 < by2) {
  125. *x = ax1;
  126. *y = ay1;
  127. }
  128. else {
  129. *x = ax2;
  130. *y = ay2;
  131. }
  132. return 2;
  133. }
  134. else {
  135. if (ax1 > bx2) {
  136. *x = ax1;
  137. *y = ay1;
  138. return 0; /* extensions overlap */
  139. }
  140. if (ax2 < bx1) {
  141. *x = ax2;
  142. *y = ay2;
  143. return 0; /* extensions overlap */
  144. }
  145. /* there is overlap */
  146. if (ax1 == bx2) {
  147. *x = ax1;
  148. *y = ay1;
  149. return 1; /* endpoints only */
  150. }
  151. if (ax2 == bx1) {
  152. *x = ax2;
  153. *y = ay2;
  154. return 1; /* endpoints only */
  155. }
  156. /* overlap, no single intersection point */
  157. if (ax1 > bx1 && ax1 < bx2) {
  158. *x = ax1;
  159. *y = ay1;
  160. }
  161. else {
  162. *x = ax2;
  163. *y = ay2;
  164. }
  165. return 2;
  166. }
  167. return 0; /* should not be reached */
  168. }