Advertisement
Guest User

Untitled

a guest
Jun 25th, 2018
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.48 KB | None | 0 0
  1. package opengl.figures;
  2.  
  3. public class CylinderLineIntersector {
  4.  
  5. static class Point2D {
  6. double x, y;
  7.  
  8. Point2D(double x, double y) {
  9. super();
  10. this.x = x;
  11. this.y = y;
  12. }
  13.  
  14. double distanceTo(Point2D other) {
  15. double dx = this.x - other.x;
  16. double dy = this.y - other.y;
  17. return Math.sqrt(dx * dx + dy * dy);
  18. }
  19. }
  20.  
  21. static class Point3D extends Point2D {
  22.  
  23. double z;
  24.  
  25. Point3D(double x, double y, double z) {
  26. super(x, y);
  27. this.z = z;
  28. }
  29.  
  30. }
  31.  
  32. private static class Vector3D extends Point3D {
  33.  
  34. Vector3D(Point3D end) {
  35. this(end.x, end.y, end.z);
  36. }
  37.  
  38. Vector3D(double x, double y, double z) {
  39. super(x, y, z);
  40. }
  41.  
  42. Vector3D normalize() {
  43. double length = length();
  44. x /= length;
  45. y /= length;
  46. z /= length;
  47.  
  48. return this;
  49. }
  50.  
  51. double length() {
  52. return Math.sqrt(x * x + y * y + z * z);
  53. }
  54.  
  55. Vector3D multiply(double k) {
  56. x *= k;
  57. y *= k;
  58. z *= k;
  59.  
  60. return this;
  61. }
  62.  
  63. Point3D applyTo(Point3D point) {
  64. return new Point3D(point.x + x, point.y + y, point.z + z);
  65. }
  66. }
  67.  
  68. private static class Line3D {
  69.  
  70. Point3D from, to;
  71.  
  72. double a, b, c;
  73.  
  74. Line3D(Point3D from, Point3D to) {
  75. this.from = from;
  76. this.to = to;
  77.  
  78. /*
  79. * x = t * (x2 - x1) + x1
  80. * y = t * (y2 - y1) + y1
  81. * z = t * (z2 - z1) + z1
  82. */
  83.  
  84. this.a = to.x - from.x;
  85. this.b = to.y - from.y;
  86. this.c = to.z - from.z;
  87. }
  88.  
  89. private double getT(Point2D point) {
  90. if (a != 0) {
  91. return (point.x - from.x) / a;
  92. }
  93.  
  94. if (b != 0) {
  95. return (point.y - from.y) / b;
  96. }
  97.  
  98. return 0;
  99. }
  100.  
  101. double getZ(Point2D point) {
  102. double t = getT(point);
  103. return c * t + from.z;
  104. }
  105. }
  106.  
  107. private static class Line2D {
  108.  
  109. double a, b, c;
  110.  
  111. Line2D(Point2D from, Point2D to) {
  112. this.a = to.y - from.y;
  113. this.b = from.x - to.x;
  114. this.c = -a * from.x - b * from.y;
  115.  
  116. double length = Math.sqrt(a * a + b * b);
  117. a /= length;
  118. b /= length;
  119. c /= length;
  120. }
  121.  
  122. double distanceTo(Point2D point) {
  123. return Math.abs(a * point.x + b * point.y + c);
  124. }
  125. }
  126.  
  127. public static boolean intersects(
  128. Point3D center, double radius, double height,
  129. Point3D from, Point3D to) {
  130. Vector3D moving = new Vector3D(center).multiply(-1);
  131.  
  132. center = moving.applyTo(center);
  133. from = moving.applyTo(from);
  134. to = moving.applyTo(to);
  135.  
  136. // now center of cylinder in (0, 0, 0)
  137.  
  138. // edgecase - if line is vertical - so it looks as Point on circle
  139. if (from.x == to.x && from.y == to.y) {
  140. Point2D planeIntersection = new Point2D(from.x, from.y);
  141. return center.distanceTo(planeIntersection) <= radius;
  142. }
  143.  
  144. Line2D line2D = new Line2D(from, to);
  145.  
  146. double centerLineDistance = line2D.distanceTo(center);
  147. if (centerLineDistance > radius) return false;
  148.  
  149. double otherTriangleSide = Math.sqrt(radius * radius - centerLineDistance * centerLineDistance);
  150.  
  151. Vector3D lineNormal = new Vector3D(line2D.a, line2D.b, 0).normalize().multiply(centerLineDistance);
  152. Vector3D lineCollinear = new Vector3D(-line2D.b, line2D.a, 0).normalize().multiply(otherTriangleSide);
  153.  
  154. Point3D middle = lineNormal.applyTo(center);
  155.  
  156. Point3D first = lineCollinear.applyTo(middle);
  157. Point3D second = lineCollinear.multiply(-1).applyTo(middle);
  158.  
  159. Line3D line3D = new Line3D(from, to);
  160.  
  161. double z1 = line3D.getZ(first), z2 = line3D.getZ(second);
  162.  
  163. if (z1 > z2) {
  164. double tmp = z1;
  165. z1 = z2;
  166. z2 = tmp;
  167. }
  168.  
  169. double cylinderZ1 = -height / 2, cylinderZ2 = height / 2;
  170.  
  171. // check intersection of two segments [z1; z2] and [cZ1; cZ2] on line
  172. return Math.max(z1, cylinderZ1) <= Math.min(z2, cylinderZ2);
  173. }
  174. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement