Advertisement
Guest User

Untitled

a guest
Jul 6th, 2015
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.23 KB | None | 0 0
  1. template <typename Type>
  2. bool intersect(Type a) {
  3. return a.intersect(*this);
  4. }
  5.  
  6. #include <iostream>
  7. #include <cmath>
  8.  
  9. using namespace std;
  10.  
  11. // Point class, defined by x and y coordinates
  12. class Point {
  13. public:
  14. double x, y;
  15. Point(double xPos, double yPos)
  16. : x(xPos)
  17. , y(yPos)
  18. { }
  19. // Calculate distance between points
  20. double distance(Point a) {
  21. double dX = x - a.x;
  22. double dY = y - a.y;
  23. return sqrt(pow(dX,2) + pow(dY,2));
  24. }
  25.  
  26. };
  27.  
  28. // Line class, defined by two endpoints
  29. class Line {
  30. public:
  31. Point start, end;
  32. Line(Point start, Point end)
  33. : start(start)
  34. , end(end)
  35. { }
  36. // Return length of line
  37. double length() {
  38. return start.distance(end);
  39. }
  40. // Return true if point a exists on this line segment
  41. bool onLine(Point a) {
  42. if (a.x <= max(start.x, end.x) && a.x >= min(start.x, end.x) && a.y <= max(start.y, end.y) && a.y >= min(start.y, end.y)) {
  43. double m = gradient();
  44. double b = yIntercept();
  45. return a.y == m * a.x + b;
  46. }
  47. return false;
  48. }
  49. // Return gradient of line
  50. double gradient() {
  51. double dX = start.x - end.x;
  52. double dY = start.y - end.y;
  53. return dY/dX;
  54. }
  55. double yIntercept() {
  56. double m = gradient();
  57. return start.y - m*start.x;
  58. }
  59. // Return orientation of line endpoints & point a
  60. int orientation(Point a) {
  61. double val = (end.y - start.y) * (a.x - end.x) - (end.x - start.x) * (a.y - end.y);
  62. if (val == 0) {
  63. return 0; // 0 = colinear
  64. } else if (val > 0) {
  65. return 1; // 1 = clockwise
  66. } else {
  67. return 2; // 2 = counter-clockwise
  68. }
  69. }
  70. // Return true if this line intersects line a
  71. bool intersect(Line a) {
  72. // Orientations: 0 is colinear, 1 is clockwise, 2 is counter-clockwise
  73. int o1 = a.orientation(start);
  74. int o2 = a.orientation(end);
  75. int o3 = orientation(a.start);
  76. int o4 = orientation(a.end);
  77.  
  78. // General case - each line's points are on opposite sides of the other line
  79. if (o1 != o2 && o3 != o4) {
  80. return true;
  81. // Line a and this line's start are colinear and this line's start lies on line a's segment
  82. } else if (o1 == 0 && a.onLine(start)) {
  83. return true;
  84. // Line a and this line's end are colinear and this line's end lies on line a's segment
  85. } else if (o2 == 0 && a.onLine(end)) {
  86. return true;
  87. // This line and a.start are colinear and a.start lies on this line segment
  88. } else if (o3 == 0 && onLine(a.start)) {
  89. return true;
  90. // This line and a.end are colinear and a.end lies on this line segment
  91. } else if (o4 == 0 && onLine(a.end)) {
  92. return true;
  93. }
  94. return false; // Doesn't fall in any of the above cases
  95. }
  96. // Catch-all intersect function in case intersect is called on a higher shape
  97. template <typename Type>
  98. bool intersect(Type a) {
  99. return a.intersect(*this);
  100. }
  101. };
  102.  
  103. // Circle class, defined by centre point and radius
  104. class Circle {
  105. public:
  106. Point centre;
  107. double radius;
  108. Circle(Point centre, double radius)
  109. : centre(centre)
  110. , radius(radius)
  111. { }
  112. // Return true if this circle intersects line a
  113. bool intersect(Line a) {
  114. // Line equation coefficients: y = mx + b
  115. double m = a.gradient();
  116. double b = a.yIntercept();
  117. // Circle equation coefficients: (x - p)^2 + (y - q)^2 = r^2
  118. double p = centre.x;
  119. double q = centre.y;
  120. double r = radius;
  121. // Quadratic equation coefficients: Ax^2 + Bx + C = 0
  122. double A = pow(m,2) + 1;
  123. double B = 2*(m*b - m*q - p);
  124. double C = pow(q,2) - pow(r,2) + pow(p,2) - 2*b*q + pow(b,2);
  125.  
  126. // A discriminant < 0 results in imaginary roots, therefore line does not intersect circle
  127. double discriminant = pow(B,2)-4*A*C;
  128. if (discriminant < 0) {
  129. return false;
  130. }
  131.  
  132. // Since discriminant >= 0, find roots
  133. double x1 = (-B+sqrt(discriminant)) / (2*A);
  134. double y1 = m*x1 + b;
  135. double x2 = (-B-sqrt(discriminant)) / (2*A);
  136. double y2 = m*x2 + b;
  137.  
  138. // If either root exists on line, the line intersects the circle
  139. if (a.onLine(Point(x1,y1))) {
  140. return true;
  141. } else if (a.onLine(Point(x2,y2))) {
  142. return true;
  143. }
  144. // Otherwise, if neither intesect appear on line segment, shapes do not intersect
  145. return false;
  146. }
  147. // Return true if circle a intersects this circle
  148. bool intersect(Circle a) {
  149. double distance = a.centre.distance(centre);
  150. if (distance <= a.radius + radius) {
  151. return true;
  152. }
  153. return false;
  154. }
  155. // Catch-all intersect function in case intersect is called on a higher shape
  156. template <typename Type>
  157. bool intersect(Type a) {
  158. return a.intersect(*this);
  159. }
  160. };
  161.  
  162. // Rectangle class, defined by lower left and upper right points
  163. class Rectangle {
  164. public:
  165. Point lowerLeft, upperRight;
  166. private:
  167. Point upperLeft, lowerRight;
  168. Line topLine, bottomLine, leftLine, rightLine;
  169.  
  170. public:
  171. // Initialise object with corner points and edge lines
  172. Rectangle(Point lowLeft, Point upRight)
  173. : lowerLeft(lowLeft)
  174. , upperRight(upRight)
  175. , upperLeft(Point(lowLeft.x, upRight.y))
  176. , lowerRight(Point(upRight.x, lowLeft.y))
  177. , topLine(upperLeft, upperRight)
  178. , bottomLine(lowerLeft, lowerRight)
  179. , leftLine(lowerLeft, upperLeft)
  180. , rightLine(lowerRight, upperRight)
  181.  
  182. { }
  183. // Return true if point a is on or in this rectangle
  184. bool pointOn(Point a) {
  185. if (a.x < lowerLeft.x || a.x > upperRight.x) {
  186. return false;
  187. } else if (a.y < lowerLeft.y || a.y > upperRight.y) {
  188. return false;
  189. }
  190. return true;
  191. }
  192. // Return true if line a is inside this rectangle
  193. bool isInside(Line a) {
  194. if (pointOn(a.start)) {
  195. return true;
  196. } else if (pointOn(a.end)) {
  197. return true;
  198. }
  199. return false;
  200. }
  201. // Return true if circle a is inside this rectangle
  202. bool isInside(Circle a) {
  203. return pointOn(a.centre);
  204. }
  205. // Return true if any corners of rectangle a are inside this rectangle
  206. bool isInside(Rectangle a) {
  207. if (pointOn(a.lowerLeft)) {
  208. return true;
  209. } else if (pointOn(a.upperRight)) {
  210. return true;
  211. } else if (pointOn(a.upperLeft)) {
  212. return true;
  213. } else if (pointOn(a.lowerRight)) {
  214. return true;
  215. }
  216. return false;
  217. }
  218. // Return true if shape a intersects with this rectangle
  219. template <typename Type>
  220. bool intersect(Type a) {
  221. // Determine if shape a is inside this rectangle
  222. if (isInside(a)) return true;
  223. // If not, do any of the rectangle's lines intersect shape a?
  224. if (a.intersect(topLine)) return true;
  225. if (a.intersect(bottomLine)) return true;
  226. if (a.intersect(leftLine)) return true;
  227. if (a.intersect(rightLine)) return true;
  228. // None do, therefore no intersection
  229. return false;
  230. }
  231. };
  232.  
  233. // Function to determine intercept - call intercept method of object a on object b
  234. // If object a is of lesser rank than b, object a will call intercept method of b
  235. template <typename Type1, typename Type2>
  236. bool intersect(Type1 &&a, Type2 &&b) {
  237. return a.intersect(b);
  238. }
  239.  
  240. Circle c1(Point(1,0),2);
  241. Circle c2(Point(3,0),2);
  242. Circle c3(Point(0,10),2);
  243. Line l1(Point(3,0),Point(10,7));
  244. Line l2(Point(3,7),Point(10,5));
  245. Line l3(Point(-100,-50),Point(-100,-40));
  246. Rectangle r1(Point(4,-2),Point(6,2));
  247. Rectangle r2(Point(5.5,1),Point(7.5,3));
  248. Rectangle r3(Point(100,90),Point(110,100));
  249.  
  250. template <typename Type>
  251. void printLine(const char* label, Type a) {
  252. cout << label;
  253. cout << intersect(a,c1) << ", " << intersect(a,c2) << ", " << intersect(a,c3) << ", ";
  254. cout << intersect(a,l1) << ", " << intersect(a,l2) << ", " << intersect(a,l3) << ", ";
  255. cout << intersect(a,r1) << ", " << intersect(a,r2) << ", " << intersect(a,r3) << endl;
  256. }
  257.  
  258. int main()
  259. {
  260. cout << " C1, C2, C3, L1, L2, L3, R1, R2, R3" << endl;
  261. printLine("C1: ", c1);
  262. printLine("C2: ", c2);
  263. printLine("C3: ", c3);
  264. printLine("L1: ", l1);
  265. printLine("L2: ", l2);
  266. printLine("L3: ", l3);
  267. printLine("R1: ", r1);
  268. printLine("R2: ", r2);
  269. printLine("R3: ", r3);
  270. Line l(Point(1,1),Point(3,3));
  271. Point p(2,2);
  272. cout << l.onLine(p);
  273. intersect(Line({2,1},{3,4}),Circle({0,0},0));
  274. return 0;
  275. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement