1 package org.djutils.draw.surface;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertNotEquals;
6 import static org.junit.Assert.assertNotNull;
7 import static org.junit.Assert.assertTrue;
8 import static org.junit.Assert.fail;
9
10 import java.util.Iterator;
11 import java.util.NoSuchElementException;
12
13 import org.djutils.draw.DrawRuntimeException;
14 import org.djutils.draw.bounds.Bounds3d;
15 import org.djutils.draw.point.Point3d;
16 import org.junit.Test;
17
18
19
20
21
22
23
24
25
26
27 public class Surface3dTest
28 {
29
30
31
32 @Test
33 public void testConstructors()
34 {
35 try
36 {
37 new Surface3d(null);
38 fail("null points should have thrown a NullPointerException");
39 }
40 catch (NullPointerException npe)
41 {
42
43 }
44
45 try
46 {
47 new Surface3d(new Point3d[][] {});
48 fail("empty points should have thrown a DrawRuntimeException");
49 }
50 catch (DrawRuntimeException dre)
51 {
52
53 }
54
55 try
56 {
57 new Surface3d(new Point3d[][] { { new Point3d(1, 2, 3) } });
58 fail("triangle with only one point should have thrown a DrawRuntimeException");
59 }
60 catch (DrawRuntimeException dre)
61 {
62
63 }
64
65 try
66 {
67 new Surface3d(new Point3d[][] { { new Point3d(1, 2, 3), new Point3d(4, 5, 6) } });
68 fail("triangle with only two points should have thrown a DrawRuntimeException");
69 }
70 catch (DrawRuntimeException dre)
71 {
72
73 }
74
75 try
76 {
77 new Surface3d(new Point3d[][] {
78 { new Point3d(1, 2, 3), new Point3d(4, 5, 6), new Point3d(7, 8, 9), new Point3d(10, 11, 12) } });
79 fail("triangle with four points should have thrown a DrawRuntimeException");
80 }
81 catch (DrawRuntimeException dre)
82 {
83
84 }
85
86 try
87 {
88 new Surface3d(new Point3d[][] { { new Point3d(1, 2, 3), new Point3d(4, 5, 6), new Point3d(1, 2, 3) } });
89 fail("triangle with duplicate point should have thrown a DrawRuntimeException");
90 }
91 catch (DrawRuntimeException dre)
92 {
93
94 }
95
96 try
97 {
98 new Surface3d(new Point3d[][] { { new Point3d(1, 2, 3), new Point3d(1, 2, 3), new Point3d(7, 8, 9) } });
99 fail("triangle with duplicate point should have thrown a DrawRuntimeException");
100 }
101 catch (DrawRuntimeException dre)
102 {
103
104 }
105
106 try
107 {
108 new Surface3d(new Point3d[][] { { new Point3d(1, 2, 3), new Point3d(4, 5, 6), new Point3d(4, 5, 6) } });
109 fail("triangle with duplicate point should have thrown a DrawRuntimeException");
110 }
111 catch (DrawRuntimeException dre)
112 {
113
114 }
115
116 Point3d[][] points = new Point3d[10][];
117 for (int triangle = 0; triangle < points.length; triangle++)
118 {
119 points[triangle] = new Point3d[] { new Point3d(triangle, triangle + 1, triangle + 2),
120 new Point3d(triangle + 10, triangle + 11, triangle + 12),
121 new Point3d(triangle + 10, triangle + 11, triangle - 12) };
122 }
123 Surface3d surface3d = new Surface3d(points);
124 assertEquals("size", points.length * 3, surface3d.size());
125 Iterator<? extends Point3d> iterator = surface3d.getPoints();
126 assertNotNull("iterator is not null", iterator);
127 for (int triangle = 0; triangle < points.length; triangle++)
128 {
129 for (int i = 0; i < 3; i++)
130 {
131 assertTrue("iterator should not be exhaused yet", iterator.hasNext());
132 Object result = iterator.next();
133 assertEquals("iterator returned correct point", points[triangle][i], result);
134 }
135 }
136 assertFalse("iterator should now be exhaused", iterator.hasNext());
137 try
138 {
139 iterator.next();
140 fail("exhausted iterator should have thrown a NoSuchElementException");
141 }
142 catch (NoSuchElementException nsee)
143 {
144
145 }
146
147 iterator = new Iterator<Point3d>()
148 {
149 private int triangleIndex = 0;
150
151 private int pointIndex = 0;
152
153 @Override
154 public boolean hasNext()
155 {
156 return this.triangleIndex < points.length;
157 }
158
159 @Override
160 public Point3d next()
161 {
162 Point3d result = points[this.triangleIndex][this.pointIndex++];
163 if (this.pointIndex >= 3)
164 {
165 this.triangleIndex++;
166 this.pointIndex = 0;
167 }
168 return result;
169 }
170 };
171 Bounds3d bounds = new Bounds3d(iterator);
172 assertEquals("Bounds match", bounds, surface3d.getBounds());
173
174
175 Point3d[][] cubePoints = new Point3d[12][];
176
177 cubePoints[0] = new Point3d[] { new Point3d(-1, -1, -1), new Point3d(-1, 1, -1), new Point3d(1, 1, -1) };
178 cubePoints[1] = new Point3d[] { new Point3d(1, 1, -1), new Point3d(1, -1, -1), new Point3d(-1, -1, -1) };
179
180 cubePoints[2] = new Point3d[] { new Point3d(-1, -1, -1), new Point3d(-1, 1, -1), new Point3d(-1, 1, 1) };
181 cubePoints[3] = new Point3d[] { new Point3d(-1, 1, 1), new Point3d(-1, -1, 1), new Point3d(-1, -1, -1) };
182
183 cubePoints[4] = new Point3d[] { new Point3d(-1, -1, -1), new Point3d(1, -1, -1), new Point3d(1, -1, 1) };
184 cubePoints[5] = new Point3d[] { new Point3d(1, -1, 1), new Point3d(-1, -1, 1), new Point3d(-1, -1, -1) };
185
186 cubePoints[6] = new Point3d[] { new Point3d(-1, -1, 1), new Point3d(-1, 1, 1), new Point3d(1, 1, 1) };
187 cubePoints[7] = new Point3d[] { new Point3d(1, 1, 1), new Point3d(1, -1, 1), new Point3d(-1, -1, 1) };
188
189 cubePoints[8] = new Point3d[] { new Point3d(1, -1, -1), new Point3d(1, 1, -1), new Point3d(1, 1, 1) };
190 cubePoints[9] = new Point3d[] { new Point3d(1, 1, 1), new Point3d(1, -1, 1), new Point3d(1, -1, -1) };
191
192 cubePoints[10] = new Point3d[] { new Point3d(-1, 1, -1), new Point3d(1, 1, -1), new Point3d(1, 1, 1) };
193 cubePoints[11] = new Point3d[] { new Point3d(1, 1, 1), new Point3d(-1, 1, 1), new Point3d(-1, 1, -1) };
194 surface3d = new Surface3d(cubePoints);
195 assertEquals("size (number of points in 12 triangles) is 36", 36, surface3d.size());
196 assertEquals("bounds", new Bounds3d(-1, 1, -1, 1, -1, 1), surface3d.getBounds());
197
198 try
199 {
200 surface3d.project();
201 fail("should have thrown a DrawRuntimeException");
202 }
203 catch (DrawRuntimeException dre)
204 {
205
206 }
207
208 assertTrue("toString results starts with class name (if not suppressed)",
209 surface3d.toString().startsWith("Surface3d "));
210
211 assertEquals("toString results with argument false is default", surface3d.toString(), surface3d.toString(false));
212
213 assertTrue("toString result with argument true is substring of default result",
214 surface3d.toString().indexOf(surface3d.toString(true)) > 5);
215
216 assertEquals("toString result with argument \"%f\" is default", surface3d.toString(), surface3d.toString("%f"));
217 }
218
219
220
221
222 @SuppressWarnings("unlikely-arg-type")
223 @Test
224 public void testHashCodeAndEquals()
225 {
226 Point3d[][] referencePoints = new Point3d[][] { { new Point3d(1, 2, 3), new Point3d(4, 5, 6), new Point3d(7, 8, 9) },
227 { new Point3d(11, 12, 13), new Point3d(14, 15, 16), new Point3d(17, 18, 19) } };
228 Surface3d referenceSurface = new Surface3d(referencePoints);
229 assertTrue("Equal to itself", referenceSurface.equals(referenceSurface));
230 assertFalse("Not equal to null", referenceSurface.equals(null));
231 assertFalse("Not equal to some other object", referenceSurface.equals("some string"));
232
233 Point3d[][] otherPoints =
234 java.util.Arrays.stream(referencePoints).map(el -> el.clone()).toArray($ -> referencePoints.clone());
235 assertTrue("Equal to other Surface3d created from copy of referencePoints",
236 referenceSurface.equals(new Surface3d(otherPoints)));
237 assertEquals("hashCode is same", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
238
239 otherPoints[0][0] = new Point3d(1, 2, 3.5);
240 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
241 referenceSurface.equals(new Surface3d(otherPoints)));
242 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
243 otherPoints[0][0] = new Point3d(1, 2.5, 3);
244 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
245 referenceSurface.equals(new Surface3d(otherPoints)));
246 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
247 otherPoints[0][0] = new Point3d(1.5, 2, 3);
248 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
249 referenceSurface.equals(new Surface3d(otherPoints)));
250 otherPoints[0][0] = new Point3d(1, 2, 3);
251 otherPoints[0][1] = new Point3d(4, 5, 6.5);
252 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
253 referenceSurface.equals(new Surface3d(otherPoints)));
254 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
255 otherPoints[0][1] = new Point3d(4, 5.5, 6);
256 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
257 referenceSurface.equals(new Surface3d(otherPoints)));
258 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
259 otherPoints[0][1] = new Point3d(4.5, 5, 6);
260 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
261 referenceSurface.equals(new Surface3d(otherPoints)));
262 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
263 otherPoints[0][1] = new Point3d(4, 5, 6);
264 otherPoints[0][2] = new Point3d(7, 8, 9.5);
265 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
266 referenceSurface.equals(new Surface3d(otherPoints)));
267 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
268 otherPoints[0][2] = new Point3d(7, 8.5, 9);
269 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
270 referenceSurface.equals(new Surface3d(otherPoints)));
271 otherPoints[0][2] = new Point3d(7.5, 8, 9);
272 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
273 referenceSurface.equals(new Surface3d(otherPoints)));
274 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
275 otherPoints[0][2] = new Point3d(7, 8, 9);
276
277 otherPoints[1][2] = new Point3d(17, 18, 19.5);
278 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
279 referenceSurface.equals(new Surface3d(otherPoints)));
280 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
281 otherPoints[1][2] = new Point3d(17, 18.5, 19);
282 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
283 referenceSurface.equals(new Surface3d(otherPoints)));
284 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
285 otherPoints[1][2] = new Point3d(17.5, 18, 19);
286 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
287 referenceSurface.equals(new Surface3d(otherPoints)));
288 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
289
290 otherPoints = new Point3d[3][];
291 otherPoints[0] = referencePoints[0];
292 otherPoints[1] = referencePoints[1];
293 otherPoints[2] = referencePoints[1];
294 assertFalse("Not equal to other Surface3d created from altered copy of referencePoints",
295 referenceSurface.equals(new Surface3d(otherPoints)));
296 assertNotEquals("hashCode differs", referenceSurface.hashCode(), new Surface3d(otherPoints).hashCode());
297 }
298
299 }