View Javadoc
1   package com.github.davidmoten.rtree.geometry.internal;
2   
3   import com.github.davidmoten.rtree.geometry.Circle;
4   import com.github.davidmoten.rtree.geometry.Rectangle;
5   
6   public final class GeometryUtil {
7   
8       private GeometryUtil() {
9           // prevent instantiation
10      }
11  
12      public static double distanceSquared(double x1, double y1, double x2, double y2) {
13          double dx = x2 - x1;
14          double dy = y2 - y1;
15          return dx * dx + dy * dy;
16      }
17  
18      public static double max(double a, double b) {
19          if (a < b)
20              return b;
21          else
22              return a;
23      }
24  
25      public static float max(float a, float b) {
26          if (a < b)
27              return b;
28          else
29              return a;
30      }
31  
32      public static double min(double a, double b) {
33          if (a < b)
34              return a;
35          else
36              return b;
37      }
38  
39      public static float min(float a, float b) {
40          if (a < b)
41              return a;
42          else
43              return b;
44      }
45  
46      public static double distance(double x, double y, Rectangle r) {
47          return distance(x, y, r.x1(), r.y1(), r.x2(), r.y2());
48      }
49  
50      public static double distance(double x, double y, double a1, double b1, double a2, double b2) {
51          return distance(x, y, x, y, a1, b1, a2, b2);
52      }
53  
54      public static double distance(double x1, double y1, double x2, double y2, double a1, double b1,
55              double a2, double b2) {
56          if (intersects(x1, y1, x2, y2, a1, b1, a2, b2)) {
57              return 0;
58          }
59          boolean xyMostLeft = x1 < a1;
60          double mostLeftX1 = xyMostLeft ? x1 : a1;
61          double mostRightX1 = xyMostLeft ? a1 : x1;
62          double mostLeftX2 = xyMostLeft ? x2 : a2;
63          double xDifference = max(0, mostLeftX1 == mostRightX1 ? 0 : mostRightX1 - mostLeftX2);
64  
65          boolean xyMostDown = y1 < b1;
66          double mostDownY1 = xyMostDown ? y1 : b1;
67          double mostUpY1 = xyMostDown ? b1 : y1;
68          double mostDownY2 = xyMostDown ? y2 : b2;
69  
70          double yDifference = max(0, mostDownY1 == mostUpY1 ? 0 : mostUpY1 - mostDownY2);
71  
72          return Math.sqrt(xDifference * xDifference + yDifference * yDifference);
73      }
74  
75      public static boolean intersects(double x1, double y1, double x2, double y2, double a1,
76              double b1, double a2, double b2) {
77          return x1 <= a2 && a1 <= x2 && y1 <= b2 && b1 <= y2;
78      }
79      
80      public static boolean lineIntersects(double x1, double y1, double x2, double y2, Circle circle) {
81  
82          // using Vector Projection
83          // https://en.wikipedia.org/wiki/Vector_projection
84          Vector c = Vector.create(circle.x(), circle.y());
85          Vector a = Vector.create(x1, y1);
86          Vector cMinusA = c.minus(a);
87          double radiusSquared = circle.radius() * circle.radius();
88          if (x1 == x2 && y1 == y2) {
89              return cMinusA.modulusSquared() <= radiusSquared;
90          } else {
91              Vector b = Vector.create(x2, y2);
92              Vector bMinusA = b.minus(a);
93              double bMinusAModulus = bMinusA.modulus();
94              double lambda = cMinusA.dot(bMinusA) / bMinusAModulus;
95              // if projection is on the segment
96              if (lambda >= 0 && lambda <= bMinusAModulus) {
97                  Vector dMinusA = bMinusA.times(lambda / bMinusAModulus);
98                  // calculate distance to line from c using pythagoras' theorem
99                  return cMinusA.modulusSquared() - dMinusA.modulusSquared() <= radiusSquared;
100             } else {
101                 // return true if and only if an endpoint is within radius of
102                 // centre
103                 return cMinusA.modulusSquared() <= radiusSquared
104                         || c.minus(b).modulusSquared() <= radiusSquared;
105             }
106         }
107 
108     }
109 
110 
111 }