-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGeometry.java
More file actions
155 lines (128 loc) · 5.21 KB
/
Geometry.java
File metadata and controls
155 lines (128 loc) · 5.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package hackpack;
public class Geometry {
public static boolean doIntersect(Point[] line1, Point[] line2){
return ((line1[0].x <= line2[1].x && line1[1].x >= line2[0].x) || (line1[0].x >= line2[1].x && line1[1].x <= line2[0].x)) // x overlaps
&& ((line1[0].y <= line2[1].y && line1[1].y >= line2[0].y) || (line1[0].y >= line2[1].y && line1[1].y <= line2[0].y)); // y overlaps
}
public static boolean doIntersect(Circle c1, Circle c2){
return Math.pow(c1.centerX - c2.centerX,2)+ Math.pow(c1.centerY - c2.centerY,2) > 0;
}
/**
* Checks if two line segments intersect. If they do, generates
* and returns the intersection point
*
* @param line1 an array containing the end points of the line
* @param line2 an array containing the end points of the line
* @return intersection point if exists, otherwise null
*/
public static Point segmentsIntersect(Point[] line1, Point[] line2){
//check that bounds overlap
if(doIntersect(line1,line2)){
// Check if either line is vertical
if(line1[0].x == line1[1].x && line2[0].x == line2[1].x){
return new Point("Lines are both vertical",-1,-1);
}else if(line1[0].x == line1[1].x){
double a2 = (line2[1].y-line2[0].y)/(line2[1].x-line2[0].x);
double b2 = line2[0].y - a2*line2[0].x;
double y = line1[0].y;
double x = (y-b2)/a2;
return new Point("Lines intersect",x,y);
}else if(line2[0].x == line2[1].x){
double a1 = (line1[1].y-line1[0].y)/(line1[1].x-line1[0].x);
double b1 = line1[0].y - a1*line1[0].x;
double y = line2[0].y;
double x = (y-b1)/a1;
return new Point("Lines intersect",x,y);
}else{
// find equations by y = ax+b
double a1 = (line1[1].y-line1[0].y)/(line1[1].x-line1[0].x);
double b1 = line1[0].y - a1*line1[0].x;
double a2 = (line2[1].y-line2[0].y)/(line2[1].x-line2[0].x);
double b2 = line2[0].y - a2*line2[0].x;
if(a1 == a2){
return new Point("Lines are parallel",-1,-1);
}
//System.out.println("Slope: " + a1 + " Intercept: " + b1);
//System.out.println("Slope: " + a2 + " Intercept: " + b2);
double x = -(b1-b2)/(a1-a2);
double y = a1*x + b1;
return new Point("Intersection",x,y);
}
}
return null;
}
public static Point[] circlesIntersect(Circle circle1, Circle circle2){
double distSquared = Math.pow(circle1.centerX - circle2.centerX,2)+ Math.pow(circle1.centerY - circle2.centerY,2);
double dist = Math.sqrt(distSquared);
if(dist > 0){
double dLeft = (Math.pow(circle1.radius,2) - Math.pow(circle2.radius,2) + distSquared) / (2*dist);
double height = Math.sqrt(Math.pow(circle1.radius,2)-Math.pow(dLeft,2));
double midX = circle1.centerX + dLeft*(circle2.centerX-circle1.centerX)/dist;
double midY = circle1.centerY + dLeft*(circle2.centerY-circle1.centerY)/dist;
Point mid = new Point("midpoint",midX,midY);
double x1 = mid.x + (height*(circle2.centerY - circle1.centerY)/dist);
double y1 = mid.y - (height*(circle2.centerX - circle1.centerX)/dist);
double x2 = mid.x - (height*(circle2.centerY - circle1.centerY)/dist);
double y2 = mid.y + (height*(circle2.centerX - circle1.centerX)/dist);
return new Point[]{new Point("Intersection",x1,y1),new Point("Intersection",x2,y2)};
}
return null;
}
static Point[] lineCircleIntersect(Circle c,Point[] l){
Point[] ps = new Point[2];
double deltaX = l[1].x - l[0].x;
double deltaY = l[1].y - l[0].y;
double cToLX = c.centerX - l[0].x;
double cToLY = c.centerY - l[0].y;
System.out.println("dx: " + deltaX + " dy: " + deltaY);
System.out.println("c2lx: " + cToLX + " c2ly: " + cToLY);
double lineLengthSqrd = Math.pow(deltaX,2) + Math.pow(deltaY,2);
System.out.println("Line squared: " + lineLengthSqrd);
double bBy2 = deltaX*cToLX + deltaY*cToLY;
System.out.println("bby2: " + bBy2);
double distSqrd = Math.pow(cToLX, 2) + Math.pow(cToLY, 2) - Math.pow(c.radius, 2);
System.out.println("distSqrd: " + distSqrd);
double pBy2 = bBy2/lineLengthSqrd;
double vector = distSqrd / lineLengthSqrd;
double disc = Math.pow(pBy2,2) - vector;
System.out.println("disc: " + disc);
if(disc < 0){
// They don't intersect, so both are null
return ps;
}
double root = Math.sqrt(disc);
double scalingPos = -pBy2 + root;
double scalingNeg = -pBy2 - root;
ps[0] = new Point("Intersection",l[0].x - deltaX*scalingPos,l[0].y - deltaY*scalingPos);
if(disc == 0){
return ps;
}
ps[1] = new Point("Intersection",l[0].x - deltaX*scalingNeg,l[0].y - deltaY*scalingNeg);
return ps;
}
public static void main(String[] args){
Circle c1 = new Circle(2,3,3);
Circle c2 = new Circle(1,-1,4);
Point[] points = circlesIntersect(c1,c2);
System.out.println(points[0]);
System.out.println(points[1]);
Point[] l1 = {new Point(1,4),new Point(5,0)};
Point[] l2 = {new Point(1,0),new Point(5,4)};
System.out.println(segmentsIntersect(l1,l2));
Circle c3 = new Circle(2,2,1);
Point[] l3 = {new Point("a",0,2),new Point("b",4,2)};
Point[] ans = lineCircleIntersect(c3, l3);
System.out.println(ans[0]);
System.out.println(ans[1]);
}
}
class Circle{
double centerX;
double centerY;
double radius;
public Circle(double x, double y, double rad){
centerX = x;
centerY = y;
radius = rad;
}
}