Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
epoxy
GitHub Repository: epoxy/proj11
Path: blob/master/SLICK_HOME/src/org/newdawn/slick/geom/Line.java
1461 views
1
package org.newdawn.slick.geom;
2
3
/**
4
* Implemenation of a bunch of maths functions to do with lines. Note
5
* that lines can't be used as dynamic shapes right now - also collision
6
* with the end of a line is undefined.
7
*
8
* @author Kevin Glass
9
*/
10
public class Line extends Shape {
11
/** The start point of the line */
12
private Vector2f start;
13
/** The end point of the line */
14
private Vector2f end;
15
/** The vector between the two points */
16
private Vector2f vec;
17
/** The length of the line squared */
18
private float lenSquared;
19
20
/** Temporary storage - declared globally to reduce GC */
21
private Vector2f loc = new Vector2f(0,0);
22
/** Temporary storage - declared globally to reduce GC */
23
private Vector2f v = new Vector2f(0,0);
24
/** Temporary storage - declared globally to reduce GC */
25
private Vector2f v2 = new Vector2f(0,0);
26
/** Temporary storage - declared globally to reduce GC */
27
private Vector2f proj = new Vector2f(0,0);
28
29
/** Temporary storage - declared globally to reduce GC */
30
private Vector2f closest = new Vector2f(0,0);
31
/** Temporary storage - declared globally to reduce GC */
32
private Vector2f other = new Vector2f(0,0);
33
34
/** True if this line blocks on the outer edge */
35
private boolean outerEdge = true;
36
/** True if this line blocks on the inner edge */
37
private boolean innerEdge = true;
38
39
/**
40
* Create a new line based on the origin and a single point
41
*
42
* @param x The end point of the line
43
* @param y The end point of the line
44
* @param inner True if this line blocks on it's inner edge
45
* @param outer True if this line blocks on it's outer edge
46
*/
47
public Line(float x, float y, boolean inner, boolean outer) {
48
this(0,0,x,y);
49
}
50
51
/**
52
* Create a new line based on the origin and a single point
53
*
54
* @param x The end point of the line
55
* @param y The end point of the line
56
*/
57
public Line(float x, float y) {
58
this(x,y,true,true);
59
}
60
61
/**
62
* Create a new line based on two points
63
*
64
* @param x1 The x coordinate of the start point
65
* @param y1 The y coordinate of the start point
66
* @param x2 The x coordinate of the end point
67
* @param y2 The y coordinate of the end point
68
*/
69
public Line(float x1, float y1, float x2, float y2) {
70
this(new Vector2f(x1,y1), new Vector2f(x2,y2));
71
}
72
73
/**
74
* Create a line with relative second point
75
*
76
* @param x1 The x coordinate of the start point
77
* @param y1 The y coordinate of the start point
78
* @param dx The x change to get to the second point
79
* @param dy The y change to get to the second point
80
* @param dummy A dummy value
81
*/
82
public Line(float x1, float y1, float dx, float dy, boolean dummy) {
83
this(new Vector2f(x1,y1), new Vector2f(x1+dx,y1+dy));
84
}
85
86
/**
87
* Create a new line based on two points
88
*
89
* @param start The start point
90
* @param end The end point
91
*/
92
public Line(Vector2f start, Vector2f end) {
93
super();
94
95
set(start,end);
96
}
97
98
/**
99
* Get the start point of the line
100
*
101
* @return The start point of the line
102
*/
103
public Vector2f getStart() {
104
return start;
105
}
106
107
/**
108
* Get the end point of the line
109
*
110
* @return The end point of the line
111
*/
112
public Vector2f getEnd() {
113
return end;
114
}
115
116
/**
117
* Find the length of the line
118
*
119
* @return The the length of the line
120
*/
121
public float length() {
122
return vec.length();
123
}
124
125
/**
126
* Find the length of the line squared (cheaper and good for comparisons)
127
*
128
* @return The length of the line squared
129
*/
130
public float lengthSquared() {
131
return vec.lengthSquared();
132
}
133
134
/**
135
* Configure the line
136
*
137
* @param start The start point of the line
138
* @param end The end point of the line
139
*/
140
public void set(Vector2f start, Vector2f end) {
141
super.pointsDirty = true;
142
if (this.start == null) {
143
this.start = new Vector2f();
144
}
145
this.start.set(start);
146
147
if (this.end == null) {
148
this.end = new Vector2f();
149
}
150
this.end.set(end);;
151
152
vec = new Vector2f(end);
153
vec.sub(start);
154
155
lenSquared = vec.lengthSquared();
156
}
157
158
/**
159
* Configure the line without garbage
160
*
161
* @param sx The x coordinate of the start
162
* @param sy The y coordinate of the start
163
* @param ex The x coordiante of the end
164
* @param ey The y coordinate of the end
165
*/
166
public void set(float sx, float sy, float ex, float ey) {
167
super.pointsDirty = true;
168
start.set(sx, sy);
169
end.set(ex,ey);
170
171
float dx = (ex-sx);
172
float dy = (ey-sy);
173
174
lenSquared = (dx*dx)+(dy*dy);
175
}
176
177
/**
178
* Get the x direction of this line
179
*
180
* @return The x direction of this line
181
*/
182
public float getDX() {
183
return end.getX() - start.getX();
184
}
185
186
/**
187
* Get the y direction of this line
188
*
189
* @return The y direction of this line
190
*/
191
public float getDY() {
192
return end.getY() - start.getY();
193
}
194
195
/**
196
* @see org.newdawn.slick.geom.Shape#getX()
197
*/
198
public float getX() {
199
return getX1();
200
}
201
202
/**
203
* @see org.newdawn.slick.geom.Shape#getY()
204
*/
205
public float getY() {
206
return getY1();
207
}
208
209
/**
210
* Get the x coordinate of the start point
211
*
212
* @return The x coordinate of the start point
213
*/
214
public float getX1() {
215
return start.getX();
216
}
217
218
/**
219
* Get the y coordinate of the start point
220
*
221
* @return The y coordinate of the start point
222
*/
223
public float getY1() {
224
return start.getY();
225
}
226
227
/**
228
* Get the x coordinate of the end point
229
*
230
* @return The x coordinate of the end point
231
*/
232
public float getX2() {
233
return end.getX();
234
}
235
236
/**
237
* Get the y coordinate of the end point
238
*
239
* @return The y coordinate of the end point
240
*/
241
public float getY2() {
242
return end.getY();
243
}
244
245
/**
246
* Get the shortest distance from a point to this line
247
*
248
* @param point The point from which we want the distance
249
* @return The distance from the line to the point
250
*/
251
public float distance(Vector2f point) {
252
return (float) Math.sqrt(distanceSquared(point));
253
}
254
255
/**
256
* Check if the given point is on the line
257
*
258
* @param point The point to check
259
* @return True if the point is on this line
260
*/
261
public boolean on(Vector2f point) {
262
getClosestPoint(point, closest);
263
264
return point.equals(closest);
265
}
266
267
/**
268
* Get the shortest distance squared from a point to this line
269
*
270
* @param point The point from which we want the distance
271
* @return The distance squared from the line to the point
272
*/
273
public float distanceSquared(Vector2f point) {
274
getClosestPoint(point, closest);
275
closest.sub(point);
276
277
float result = closest.lengthSquared();
278
279
return result;
280
}
281
282
/**
283
* Get the closest point on the line to a given point
284
*
285
* @param point The point which we want to project
286
* @param result The point on the line closest to the given point
287
*/
288
public void getClosestPoint(Vector2f point, Vector2f result) {
289
loc.set(point);
290
loc.sub(start);
291
292
float projDistance = vec.dot(loc);
293
294
projDistance /= vec.lengthSquared();
295
296
if (projDistance < 0) {
297
result.set(start);
298
return;
299
}
300
if (projDistance > 1) {
301
result.set(end);
302
return;
303
}
304
305
result.x = start.getX() + projDistance * vec.getX();
306
result.y = start.getY() + projDistance * vec.getY();
307
}
308
309
/**
310
* @see java.lang.Object#toString()
311
*/
312
public String toString() {
313
return "[Line "+start+","+end+"]";
314
}
315
316
/**
317
* Intersect this line with another
318
*
319
* @param other The other line we should intersect with
320
* @return The intersection point or null if the lines are parallel
321
*/
322
public Vector2f intersect(Line other) {
323
return intersect(other, false);
324
}
325
326
/**
327
* Intersect this line with another
328
*
329
* @param other The other line we should intersect with
330
* @param limit True if the collision is limited to the extent of the lines
331
* @return The intersection point or null if the lines don't intersect
332
*/
333
public Vector2f intersect(Line other, boolean limit) {
334
Vector2f temp = new Vector2f();
335
336
if (!intersect(other, limit, temp)) {
337
return null;
338
}
339
340
return temp;
341
}
342
343
/**
344
* Intersect this line with another
345
*
346
* @param other The other line we should intersect with
347
* @param limit True if the collision is limited to the extent of the lines
348
* @param result The resulting intersection point if any
349
* @return True if the lines intersect
350
*/
351
public boolean intersect(Line other, boolean limit, Vector2f result) {
352
float dx1 = end.getX() - start.getX();
353
float dx2 = other.end.getX() - other.start.getX();
354
float dy1 = end.getY() - start.getY();
355
float dy2 = other.end.getY() - other.start.getY();
356
float denom = (dy2 * dx1) - (dx2 * dy1);
357
358
if (denom == 0) {
359
return false;
360
}
361
362
float ua = (dx2 * (start.getY() - other.start.getY())) - (dy2 * (start.getX() - other.start.getX()));
363
ua /= denom;
364
float ub = (dx1 * (start.getY() - other.start.getY())) - (dy1 * (start.getX() - other.start.getX()));
365
ub /= denom;
366
367
if ((limit) && ((ua < 0) || (ua > 1) || (ub < 0) || (ub > 1))) {
368
return false;
369
}
370
371
float u = ua;
372
373
float ix = start.getX() + (u * (end.getX() - start.getX()));
374
float iy = start.getY() + (u * (end.getY() - start.getY()));
375
376
result.set(ix,iy);
377
return true;
378
}
379
380
/**
381
* @see org.newdawn.slick.geom.Shape#createPoints()
382
*/
383
protected void createPoints() {
384
points = new float[4];
385
points[0] = getX1();
386
points[1] = getY1();
387
points[2] = getX2();
388
points[3] = getY2();
389
}
390
391
/**
392
* @see org.newdawn.slick.geom.Shape#transform(org.newdawn.slick.geom.Transform)
393
*/
394
public Shape transform(Transform transform) {
395
float[] temp = new float[4];
396
createPoints();
397
transform.transform(points, 0, temp, 0, 2);
398
399
return new Line(temp[0],temp[1],temp[2],temp[3]);
400
}
401
402
/**
403
* @see org.newdawn.slick.geom.Shape#closed()
404
*/
405
public boolean closed() {
406
return false;
407
}
408
}
409
410