1 package org.opentrafficsim.core.geometry;
2
3 import java.awt.geom.Line2D;
4 import java.awt.geom.Path2D;
5 import java.awt.geom.Point2D;
6 import java.awt.geom.Rectangle2D;
7 import java.util.ArrayList;
8 import java.util.Arrays;
9 import java.util.List;
10
11 import javax.media.j3d.BoundingBox;
12 import javax.vecmath.Point3d;
13
14 import nl.tudelft.simulation.language.d3.DirectedPoint;
15
16 import com.vividsolutions.jts.geom.Coordinate;
17 import com.vividsolutions.jts.geom.Geometry;
18 import com.vividsolutions.jts.geom.LineString;
19
20
21
22
23
24
25
26
27
28
29
30 public class OTSShape extends OTSLine3D
31 {
32
33 private static final long serialVersionUID = 20160331;
34
35
36 private Path2D shape = null;
37
38
39
40
41
42
43
44 public OTSShape(final OTSPoint3D... points) throws OTSGeometryException
45 {
46 super(points);
47 }
48
49
50
51
52
53
54
55 public OTSShape(final Coordinate[] coordinates) throws OTSGeometryException
56 {
57 super(coordinates);
58 }
59
60
61
62
63
64
65
66 public OTSShape(final LineString lineString) throws OTSGeometryException
67 {
68 super(lineString);
69 }
70
71
72
73
74
75
76
77 public OTSShape(final Geometry geometry) throws OTSGeometryException
78 {
79 super(geometry);
80 }
81
82
83
84
85
86
87
88 public OTSShape(final List<OTSPoint3D> pointList) throws OTSGeometryException
89 {
90 super(pointList);
91 }
92
93
94
95
96
97
98
99 public OTSShape(final Path2D path) throws OTSGeometryException
100 {
101 super(path);
102 }
103
104
105
106
107 public final Path2D getShape()
108 {
109 if (this.shape == null)
110 {
111 calculateShape();
112 }
113 return this.shape;
114 }
115
116
117
118
119 private void calculateShape()
120 {
121 this.shape = new Path2D.Double();
122 this.shape.moveTo(getPoints()[0].x, getPoints()[0].y);
123 for (int i = 1; i < getPoints().length; i++)
124 {
125 this.shape.lineTo(getPoints()[i].x, getPoints()[i].y);
126 }
127 this.shape.closePath();
128 }
129
130
131
132
133
134 public final boolean contains(final OTSPoint3D point)
135 {
136 return getShape().contains(point.x, point.y);
137 }
138
139
140
141
142
143 public final boolean intersects(final OTSShape otsShape)
144 {
145
146 if (!getBoundingRectangle().intersects(otsShape.getBoundingRectangle()))
147 {
148 return false;
149 }
150
151
152 for (int i = 1; i < getPoints().length; i++)
153 {
154 if (otsShape.contains(getPoints()[i]))
155 {
156 return true;
157 }
158 }
159
160
161 for (int i = 1; i < otsShape.getPoints().length; i++)
162 {
163 if (contains(otsShape.getPoints()[i]))
164 {
165 return true;
166 }
167 }
168
169
170 for (int i = 0; i < getPoints().length - 1; i++)
171 {
172 Line2D.Double line1 = new Line2D.Double(this.getPoints()[i].getPoint2D(), this.getPoints()[i + 1].getPoint2D());
173 for (int j = 0; j < otsShape.getPoints().length - 1; j++)
174 {
175 Line2D.Double line2 =
176 new Line2D.Double(otsShape.getPoints()[j].getPoint2D(), otsShape.getPoints()[j + 1].getPoint2D());
177
178 if (line1.intersectsLine(line2))
179 {
180 double p1x = line1.getX1(), p1y = line1.getY1(), d1x = line1.getX2() - p1x, d1y = line1.getY2() - p1y;
181 double p2x = line2.getX1(), p2y = line2.getY1(), d2x = line2.getX2() - p2x, d2y = line2.getY2() - p2y;
182
183 double det = d2x * d1y - d2y * d1x;
184 if (det == 0)
185 {
186
187
188
189
190
191
192 Point2D p1s = line1.getP1(), p1e = line1.getP2(), p2s = line2.getP1(), p2e = line2.getP2();
193 if ((p1s.equals(p2s) && p1e.equals(p2e)) || (p1s.equals(p2e) && p1e.equals(p2s)))
194 {
195 return true;
196 }
197 if (p1s.equals(p2s) && line1.ptLineDist(p2e) > 0 && line2.ptLineDist(p1e) > 0)
198 {
199 return true;
200 }
201 if (p1e.equals(p2e) && line1.ptLineDist(p2s) > 0 && line2.ptLineDist(p1s) > 0)
202 {
203 return true;
204 }
205 if (p1s.equals(p2e) && line1.ptLineDist(p2s) > 0 && line2.ptLineDist(p1e) > 0)
206 {
207 return true;
208 }
209 if (p1e.equals(p2s) && line1.ptLineDist(p2e) > 0 && line2.ptLineDist(p1s) > 0)
210 {
211 return true;
212 }
213 }
214 else
215 {
216 double z = (d2x * (p2y - p1y) + d2y * (p1x - p2x)) / det;
217 if (Math.abs(z) < 10.0 * Math.ulp(1.0) || Math.abs(z - 1.0) < 10.0 * Math.ulp(1.0))
218 {
219 return true;
220 }
221 }
222
223 }
224 }
225 }
226 return false;
227 }
228
229
230
231
232
233
234
235 public static OTSShape createAndCleanOTSShape(final OTSPoint3D[] points) throws OTSGeometryException
236 {
237 if (points.length < 2)
238 {
239 throw new OTSGeometryException("Degenerate OTSLine3D; has " + points.length + " point"
240 + (points.length != 1 ? "s" : ""));
241 }
242 return createAndCleanOTSShape(new ArrayList<>(Arrays.asList(points)));
243 }
244
245
246
247
248
249
250
251
252 public static OTSShape createAndCleanOTSShape(final List<OTSPoint3D> pointList) throws OTSGeometryException
253 {
254
255 int i = 1;
256 while (i < pointList.size())
257 {
258 if (pointList.get(i - 1).equals(pointList.get(i)))
259 {
260 pointList.remove(i);
261 }
262 else
263 {
264 i++;
265 }
266 }
267 return new OTSShape(pointList);
268 }
269
270
271
272
273
274
275 public static void main(final String[] args) throws OTSGeometryException
276 {
277 OTSShape s1 = new OTSShape(new OTSPoint3D(0, 0), new OTSPoint3D(10, 0), new OTSPoint3D(10, 10), new OTSPoint3D(0, 10));
278 OTSShape s2 = new OTSShape(new OTSPoint3D(5, 5), new OTSPoint3D(15, 5), new OTSPoint3D(15, 15), new OTSPoint3D(5, 15));
279 System.out.println("s1.intersect(s2): " + s1.intersects(s2));
280 System.out.println("s1.intersect(s1): " + s1.intersects(s1));
281 OTSShape s3 =
282 new OTSShape(new OTSPoint3D(25, 25), new OTSPoint3D(35, 25), new OTSPoint3D(35, 35), new OTSPoint3D(25, 35));
283 System.out.println("s1.intersect(s3): " + s1.intersects(s3));
284 }
285 }