1 package nl.tudelft.simulation.language.d2;
2
3 import java.awt.geom.Line2D;
4 import java.awt.geom.Point2D;
5
6
7
8
9
10
11
12
13
14
15
16
17
18 public class DirectionalLine extends Line2D.Double
19 {
20
21 private static final long serialVersionUID = 1L;
22
23
24 public enum Side
25 {
26
27 BACKSIDE(-1),
28
29
30 COLLINEAR(0),
31
32
33 FRONTSIDE(1),
34
35
36 SPANNING(2);
37
38
39 private final int value;
40
41
42
43
44
45 Side(final int value)
46 {
47 this.value = value;
48 }
49
50
51
52
53
54 public int getValue()
55 {
56 return this.value;
57 }
58 }
59
60
61 private double lineThickness = 1;
62
63
64 private double normalX;
65
66
67 private double normalY;
68
69
70
71
72
73
74
75
76 public DirectionalLine(final double x1, final double y1, final double x2, final double y2)
77 {
78 this.setLine(x1, y1, x2, y2);
79 }
80
81
82
83
84
85
86
87
88 public DirectionalLine(final float x1, final float y1, final float x2, final float y2)
89 {
90 this.setLine(x1, y1, x2, y2);
91 }
92
93
94
95
96 public void calcNormal()
97 {
98 this.normalX = this.y1 - this.y2;
99 this.normalY = this.x2 - this.x1;
100 }
101
102
103
104
105 public void normalize()
106 {
107 double length = Math.sqrt(this.normalX * this.normalX + this.normalY * this.normalY);
108 this.normalX /= length;
109 this.normalY /= length;
110 }
111
112
113
114
115
116
117
118
119 public void setLine(final float x1, final float y1, final float x2, final float y2)
120 {
121 super.setLine(x1, y1, x2, y2);
122 this.calcNormal();
123 }
124
125
126 @Override
127 public void setLine(final double x1, final double y1, final double x2, final double y2)
128 {
129 super.setLine(x1, y1, x2, y2);
130 this.calcNormal();
131 }
132
133
134
135
136
137 public void flip()
138 {
139 double tx = this.x1;
140 double ty = this.y1;
141 this.x1 = this.x2;
142 this.y1 = this.y2;
143 this.x2 = tx;
144 this.y2 = ty;
145 this.normalX = -this.normalX;
146 this.normalY = -this.normalY;
147 }
148
149
150
151
152
153
154 public boolean equalsCoordinates(final DirectionalLine line)
155 {
156 return (this.x1 == line.x1 && this.x2 == line.x2 && this.y1 == line.y1 && this.y2 == line.y2);
157 }
158
159
160
161
162
163
164
165
166 public boolean equalsCoordinatesIgnoreOrder(final DirectionalLine line)
167 {
168 return equalsCoordinates(line)
169 || ((this.x1 == line.x2 && this.x2 == line.x1 && this.y1 == line.y2 && this.y2 == line.y1));
170 }
171
172
173 @Override
174 public String toString()
175 {
176 return "(" + this.x1 + "," + this.y1 + ")->(" + this.x2 + "," + this.y2 + ")";
177 }
178
179
180
181
182
183
184
185
186
187 public Side getSideThick(final double x, final double y)
188 {
189 double normalX2 = this.normalX * this.lineThickness;
190 double normalY2 = this.normalY * this.lineThickness;
191
192 Side frontSide = getSideThin(x - normalX2 / 2, y - normalY2 / 2);
193 if (frontSide.equals(Side.FRONTSIDE))
194 {
195 return Side.FRONTSIDE;
196 }
197 else if (frontSide.equals(Side.BACKSIDE))
198 {
199 Side backSide = getSideThin(x + normalX2 / 2, y + normalY2 / 2);
200 if (backSide.equals(Side.BACKSIDE))
201 {
202 return Side.BACKSIDE;
203 }
204 }
205 return Side.COLLINEAR;
206 }
207
208
209
210
211
212
213
214
215
216 public Side getSideThin(final double x, final double y)
217 {
218
219 double side = (x - this.x1) * this.normalX + (y - this.y1) * this.normalY;
220 if (side < 0)
221 {
222 return Side.BACKSIDE;
223 }
224 else if (side > 0)
225 {
226 return Side.FRONTSIDE;
227 }
228 else
229 {
230 return Side.COLLINEAR;
231 }
232 }
233
234
235
236
237
238
239 public Side getSide(final Line2D.Double line)
240 {
241 if (this.x1 == line.x1 && this.x2 == line.x2 && this.y1 == line.y1 && this.y2 == line.y2)
242 {
243 return Side.COLLINEAR;
244 }
245 Side p1Side = getSideThick(line.x1, line.y1);
246 Side p2Side = getSideThick(line.x2, line.y2);
247 if (p1Side == p2Side)
248 {
249 return p1Side;
250 }
251 else if (p1Side == Side.COLLINEAR)
252 {
253 return p2Side;
254 }
255 else if (p2Side == Side.COLLINEAR)
256 {
257 return p1Side;
258 }
259 else
260 {
261 return Side.SPANNING;
262 }
263 }
264
265
266
267
268
269
270
271
272 public double getIntersection(final Line2D.Double line)
273 {
274
275
276
277
278
279
280
281 double denominator = (line.y2 - line.y1) * (this.x2 - this.x1) - (line.x2 - line.x1) * (this.y2 - this.y1);
282
283
284 if (denominator == 0)
285 {
286 return -1;
287 }
288
289 double numerator = (line.x2 - line.x1) * (this.y1 - line.y1) - (line.y2 - line.y1) * (this.x1 - line.x1);
290
291 return numerator / denominator;
292 }
293
294
295
296
297
298
299 public Point2D.Double getIntersectionPoint(final Line2D.Double line)
300 {
301 double fraction = getIntersection(line);
302 Point2D.Double intersection = new Point2D.Double();
303 intersection.setLocation(this.x1 + fraction * (this.x2 - this.x1), this.y1 + fraction * (this.y2 - this.y1));
304 return intersection;
305 }
306
307
308
309
310
311 public double getLineThickness()
312 {
313 return this.lineThickness;
314 }
315
316
317
318
319
320 public void setLineThickness(final double lineThickness)
321 {
322 this.lineThickness = lineThickness;
323 }
324
325
326
327
328 public double getNormalx()
329 {
330 return this.normalX;
331 }
332
333
334
335
336 public double getNormaly()
337 {
338 return this.normalY;
339 }
340 }