-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.pde
267 lines (217 loc) · 8.27 KB
/
utils.pde
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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
/*
* utils.pde
*
* Useful utility methods
*
* Created on: July 26, 2020
* Author: Sean LaPlante
*/
import java.lang.reflect.*;
Method getInternalProcessingMethod(String methodName) {
/*
* Helper method that can be used to return
* an internal processing method by name
*/
Class cls = this.getClass();
try {
return cls.getMethod(methodName);
} catch (Exception e) {
println("Cannot find", methodName, ":", e);
return null;
}
}
Object invokeInternalProcessingMethod(String methodName, Object ... args) {
Method meth = getInternalProcessingMethod(methodName);
if (meth != null) {
try {
return meth.invoke(this, args);
} catch (Exception e) {
println("Unable to invoke", methodName, ":", e);
}
}
return null;
}
Object getInternalProcessingField(String fieldName) {
/*
* Helper method that can be used to return
* an internal processing field by name
*/
Class cls = this.getClass();
try {
return cls.getField(fieldName).get(this);
} catch (Exception e) {
println("Unable to get field", fieldName, ": ", e);
return null;
}
}
boolean isAndroidMode() {
/*
* Determine if we're running in Android mode or not
*/
// What?
// In Android mode 'displayDensity' is a field and in Java
// mode 'displayDensity' is a method. This is a hack...but
// it works.
if (getInternalProcessingMethod("displayDensity") == null) {
return true;
}
return false;
}
float getDisplayDensity() {
/*
* Get the display density regardless of whether or not
* we're running on Android (where display density is not
* a method) or if we're running on a PC where it is a method.
*/
if (IS_ANDROID_MODE) {
try {
return (float)getInternalProcessingField("displayDensity");
} catch (Exception e) {
println("Android mode: Unable to get display density: ", e);
return 1.0;
}
} else {
try {
// In java mode the displayDensity method returns an int, but
// in Android mode it returns a float. This whole thing is
// stupid.
return ((Integer)invokeInternalProcessingMethod("displayDensity")).floatValue();
} catch (Exception e) {
println("Java mode: Unable to get display density: ", e);
return 1.0;
}
}
}
boolean isCircleInRect(PVector cLocation, float radius, PVector rLocation, float w, float h) {
/*
* Determine if the circle is overlapping the rect
*
* Taken/Modified from: http://jeffreythompson.org/collision-detection/
*/
float distance;
float testX = cLocation.x;
float testY = cLocation.y;
// which edge is closest?
if (cLocation.x < rLocation.x) {
// Left of rect
testX = rLocation.x;
} else if (cLocation.x > rLocation.x + w) {
// Right of rect
testX = rLocation.x + w;
}
if (cLocation.y < rLocation.y) {
// Top of rect
testY = rLocation.y;
} else if (cLocation.y > rLocation.y + h) {
// Bottom of rect
testY = rLocation.y + h;
}
distance = new PVector(cLocation.x - testX, cLocation.y - testY).mag();
return distance <= radius;
}
boolean isCircleInCircle(PVector locationOne, float radiusOne, PVector locationTwo, float radiusTwo) {
/*
* Determine if the circles are overlapping
*
* Taken/Modified from: http://jeffreythompson.org/collision-detection/
*/
return dist(locationOne.x, locationOne.y, locationTwo.x, locationTwo.y) < (radiusOne + radiusTwo);
}
PVector getLineIntersectPointWithRectLeft(float x1, float y1, float x2, float y2, float rx, float ry, float rw, float rh) {
/*
* Calculate and return the points at which a line intersects a rect's left side.
* This method will return null if the line doesn't intersect the rect.
*
* Taken/Modified from: http://jeffreythompson.org/collision-detection/
*/
// check if the line has hit any of the rectangle's sides
// uses the getLineInterectPoint method below
PVector left = getLineInterectPoint(x1,y1,x2,y2, rx,ry,rx, ry+rh);
if (left != null) {
return left;
}
return null;
}
PVector getLineIntersectPointWithRectRight(float x1, float y1, float x2, float y2, float rx, float ry, float rw, float rh) {
/*
* Calculate and return the points at which a line intersects a rect's right side.
* This method will return null if the line doesn't intersect the rect.
*
* Taken/Modified from: http://jeffreythompson.org/collision-detection/
*/
// check if the line has hit any of the rectangle's sides
// uses the getLineInterectPoint method below
PVector right = getLineInterectPoint(x1,y1,x2,y2, rx+rw,ry, rx+rw,ry+rh);
if (right != null) {
return right;
}
return null;
}
PVector getLineIntersectPointWithRectTop(float x1, float y1, float x2, float y2, float rx, float ry, float rw, float rh) {
/*
* Calculate and return the points at which a line intersects a rect's top side.
* This method will return null if the line doesn't intersect the rect.
*
* Taken/Modified from: http://jeffreythompson.org/collision-detection/
*/
// check if the line has hit any of the rectangle's sides
// uses the getLineInterectPoint method below
PVector top = getLineInterectPoint(x1,y1,x2,y2, rx,ry, rx+rw,ry);
if (top != null) {
return top;
}
return null;
}
PVector getLineIntersectPointWithRectBottom(float x1, float y1, float x2, float y2, float rx, float ry, float rw, float rh) {
/*
* Calculate and return the points at which a line intersects a rect's bottom side.
* This method will return null if the line doesn't intersect the rect.
*
* Taken/Modified from: http://jeffreythompson.org/collision-detection/
*/
// check if the line has hit any of the rectangle's sides
// uses the getLineInterectPoint method below
PVector bottom = getLineInterectPoint(x1,y1,x2,y2, rx,ry+rh, rx+rw,ry+rh);
if (bottom != null) {
return bottom;
}
return null;
}
boolean lineIntersectsRect(float x1, float y1, float x2, float y2, float rx, float ry, float rw, float rh) {
/*
* Determine if a line intersects a rect.
*
* Taken/Modified from: http://jeffreythompson.org/collision-detection/
*/
// check if the line has hit any of the rectangle's sides
// uses the Line/Line function below
PVector left = getLineInterectPoint(x1,y1,x2,y2, rx,ry,rx, ry+rh);
PVector right = getLineInterectPoint(x1,y1,x2,y2, rx+rw,ry, rx+rw,ry+rh);
PVector top = getLineInterectPoint(x1,y1,x2,y2, rx,ry, rx+rw,ry);
PVector bottom = getLineInterectPoint(x1,y1,x2,y2, rx,ry+rh, rx+rw,ry+rh);
// if ANY of the above are true, the line
// has hit the rectangle
if (left != null || right != null || top != null || bottom != null) {
return true;
}
return false;
}
PVector getLineInterectPoint(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
/*
* Calculate and return the point at which 2 lines intersect.
* This method will return null if they do not intersect
*
* Taken/Modified from: http://jeffreythompson.org/collision-detection/
*/
// calculate the distance to intersection point
float uA = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
float uB = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3)) / ((y4-y3)*(x2-x1) - (x4-x3)*(y2-y1));
// if uA and uB are between 0-1, lines are colliding
if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {
// optionally, draw a circle where the lines meet
float intersectionX = x1 + (uA * (x2-x1));
float intersectionY = y1 + (uA * (y2-y1));
return new PVector(intersectionX, intersectionY);
}
return null;
}