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
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
83
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
96 if (lambda >= 0 && lambda <= bMinusAModulus) {
97 Vector dMinusA = bMinusA.times(lambda / bMinusAModulus);
98
99 return cMinusA.modulusSquared() - dMinusA.modulusSquared() <= radiusSquared;
100 } else {
101
102
103 return cMinusA.modulusSquared() <= radiusSquared
104 || c.minus(b).modulusSquared() <= radiusSquared;
105 }
106 }
107
108 }
109
110
111 }