1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.geometry.euclidean.threed;
18
19 import org.apache.commons.geometry.core.GeometryTestUtils;
20 import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
21 import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
22 import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
23 import org.apache.commons.geometry.euclidean.threed.EmbeddingPlane.SubspaceTransform;
24 import org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;
25 import org.apache.commons.geometry.euclidean.twod.AffineTransformMatrix2D;
26 import org.apache.commons.geometry.euclidean.twod.Vector2D;
27 import org.apache.commons.numbers.angle.PlaneAngleRadians;
28 import org.junit.Assert;
29 import org.junit.Test;
30
31 public class EmbeddingPlaneTest {
32
33 private static final double TEST_EPS = 1e-10;
34
35 private static final DoublePrecisionContext TEST_PRECISION =
36 new EpsilonDoublePrecisionContext(TEST_EPS);
37
38 @Test
39 public void testFromPointAndPlaneVectors() {
40
41 final Vector3D pt = Vector3D.of(1, 2, 3);
42
43
44 checkPlane(Planes.fromPointAndPlaneVectors(pt, Vector3D.of(2, 0, 0), Vector3D.of(3, 0.1, 0), TEST_PRECISION),
45 Vector3D.of(0, 0, 3), Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y);
46
47 checkPlane(Planes.fromPointAndPlaneVectors(pt, Vector3D.of(2, 0, 0), Vector3D.of(3, -0.1, 0), TEST_PRECISION),
48 Vector3D.of(0, 0, 3), Vector3D.Unit.PLUS_X, Vector3D.Unit.MINUS_Y);
49
50 checkPlane(Planes.fromPointAndPlaneVectors(pt, Vector3D.of(0, 0.1, 0), Vector3D.of(0, -3, 1), TEST_PRECISION),
51 Vector3D.of(1, 0, 0), Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_Z);
52 }
53
54 @Test
55 public void testFromPointAndPlaneVectors_illegalArguments() {
56
57 final Vector3D pt = Vector3D.of(1, 2, 3);
58
59
60
61
62 GeometryTestUtils.assertThrows(() -> {
63 Planes.fromPointAndPlaneVectors(pt, Vector3D.of(0, 0, 1), Vector3D.of(0, 0, 1), TEST_PRECISION);
64 }, IllegalArgumentException.class);
65
66
67 GeometryTestUtils.assertThrows(() -> {
68 Planes.fromPointAndPlaneVectors(pt, Vector3D.of(0, 0, 1), Vector3D.ZERO, TEST_PRECISION);
69 }, IllegalArgumentException.class);
70
71
72 GeometryTestUtils.assertThrows(() -> {
73 Planes.fromPointAndPlaneVectors(pt, Vector3D.of(0, 0, 1), Vector3D.of(0, 0, 2), TEST_PRECISION);
74 }, IllegalArgumentException.class);
75
76
77 GeometryTestUtils.assertThrows(() -> {
78 Planes.fromPointAndPlaneVectors(pt, Vector3D.of(0, 0, 1), Vector3D.of(0, 0, -2), TEST_PRECISION);
79 }, IllegalArgumentException.class);
80 }
81
82 @Test
83 public void testGetEmbedding() {
84
85 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(Vector3D.ZERO,
86 Vector3D.Unit.PLUS_X, Vector3D.Unit.MINUS_Y, TEST_PRECISION);
87
88
89 Assert.assertSame(plane, plane.getEmbedding());
90 }
91
92 @Test
93 public void testPointAt() {
94
95 final Vector3D pt = Vector3D.of(0, 0, 1);
96 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(pt,
97 Vector3D.Unit.PLUS_Y, Vector3D.Unit.MINUS_X, TEST_PRECISION);
98
99
100 EuclideanTestUtils.assertCoordinatesEqual(pt, plane.pointAt(Vector2D.ZERO, 0), TEST_EPS);
101 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.ZERO, plane.pointAt(Vector2D.ZERO, -1), TEST_EPS);
102 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 0, -1), plane.pointAt(Vector2D.ZERO, -2), TEST_EPS);
103 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 0, 2), plane.pointAt(Vector2D.ZERO, 1), TEST_EPS);
104
105 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(-1, 2, 1), plane.pointAt(Vector2D.of(2, 1), 0), TEST_EPS);
106 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(4, -3, 6), plane.pointAt(Vector2D.of(-3, -4), 5), TEST_EPS);
107 }
108
109 @Test
110 public void testReverse() {
111
112 final Vector3D pt = Vector3D.of(0, 0, 1);
113 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(pt,
114 Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, TEST_PRECISION);
115
116
117 final EmbeddingPlane reversed = plane.reverse();
118
119
120 checkPlane(reversed, pt, Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_X);
121
122 Assert.assertTrue(reversed.contains(Vector3D.of(1, 1, 1)));
123 Assert.assertTrue(reversed.contains(Vector3D.of(-1, -1, 1)));
124 Assert.assertFalse(reversed.contains(Vector3D.ZERO));
125
126 Assert.assertEquals(1.0, reversed.offset(Vector3D.ZERO), TEST_EPS);
127 }
128
129 @Test
130 public void testTransform_rotationAroundPoint() {
131
132 final Vector3D pt = Vector3D.of(0, 0, 1);
133 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(pt, Vector3D.Unit.PLUS_Y, Vector3D.Unit.MINUS_X, TEST_PRECISION);
134
135 final AffineTransformMatrix3D mat = AffineTransformMatrix3D.createRotation(pt,
136 QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, PlaneAngleRadians.PI_OVER_TWO));
137
138
139 final EmbeddingPlane result = plane.transform(mat);
140
141
142 checkPlane(result, Vector3D.ZERO, Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_Z);
143 }
144
145 @Test
146 public void testTransform_asymmetricScaling() {
147
148 final Vector3D pt = Vector3D.of(0, 1, 0);
149 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(pt, Vector3D.Unit.MINUS_Z, Vector3D.of(-1, 1, 0), TEST_PRECISION);
150
151 final AffineTransformMatrix3D mat = AffineTransformMatrix3D.createScale(2, 1, 1);
152
153
154 final EmbeddingPlane result = plane.transform(mat);
155
156
157 final Vector3D expectedU = Vector3D.Unit.MINUS_Z;
158 final Vector3D expectedV = Vector3D.Unit.of(-2, 1, 0);
159 final Vector3D expectedNormal = Vector3D.Unit.of(1, 2, 0);
160
161 final Vector3D transformedPt = mat.apply(plane.getOrigin());
162 final Vector3D expectedOrigin = transformedPt.project(expectedNormal);
163
164 checkPlane(result, expectedOrigin, expectedU, expectedV);
165
166 Assert.assertTrue(result.contains(transformedPt));
167 Assert.assertFalse(plane.contains(transformedPt));
168 }
169
170 @Test
171 public void testTransform_negateOneComponent() {
172
173 final Vector3D pt = Vector3D.of(0, 0, 1);
174 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(pt, Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, TEST_PRECISION);
175
176 final AffineTransformMatrix3D transform = AffineTransformMatrix3D.from(v -> Vector3D.of(-v.getX(), v.getY(), v.getZ()));
177
178
179 final EmbeddingPlane result = plane.transform(transform);
180
181
182 checkPlane(result, Vector3D.of(0, 0, 1), Vector3D.Unit.MINUS_X, Vector3D.Unit.PLUS_Y);
183 }
184
185 @Test
186 public void testTransform_negateTwoComponents() {
187
188 final Vector3D pt = Vector3D.of(0, 0, 1);
189 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(pt, Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, TEST_PRECISION);
190
191 final AffineTransformMatrix3D transform = AffineTransformMatrix3D.from(v -> Vector3D.of(-v.getX(), -v.getY(), v.getZ()));
192
193
194 final EmbeddingPlane result = plane.transform(transform);
195
196
197 checkPlane(result, Vector3D.of(0, 0, 1), Vector3D.Unit.MINUS_X, Vector3D.Unit.MINUS_Y);
198 }
199
200 @Test
201 public void testTransform_negateAllComponents() {
202
203 final Vector3D pt = Vector3D.of(0, 0, 1);
204 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(pt,
205 Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, TEST_PRECISION);
206
207 final AffineTransformMatrix3D transform = AffineTransformMatrix3D.from(Vector3D::negate);
208
209
210 final EmbeddingPlane result = plane.transform(transform);
211
212
213 checkPlane(result, Vector3D.of(0, 0, -1), Vector3D.Unit.MINUS_X, Vector3D.Unit.MINUS_Y);
214 }
215
216 @Test
217 public void testTransform_consistency() {
218
219 final Vector3D pt = Vector3D.of(1, 2, 3);
220 final Vector3D normal = Vector3D.Unit.from(1, 1, 1);
221 final Vector3D u = normal.orthogonal(Vector3D.Unit.PLUS_X);
222 final Vector3D v = normal.cross(u).normalize();
223
224 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(pt, u, v, TEST_PRECISION);
225
226 final Vector3D p1 = plane.project(Vector3D.of(4, 5, 6));
227 final Vector3D p2 = plane.project(Vector3D.of(-7, -8, -9));
228 final Vector3D p3 = plane.project(Vector3D.of(10, -11, 12));
229
230 final Vector3D notOnPlane1 = plane.getOrigin().add(plane.getNormal());
231 final Vector3D notOnPlane2 = plane.getOrigin().subtract(plane.getNormal());
232
233 EuclideanTestUtils.permuteSkipZero(-4, 4, 1, (a, b, c) -> {
234 final AffineTransformMatrix3D t = AffineTransformMatrix3D.identity()
235 .rotate(Vector3D.of(-1, 2, 3),
236 QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_X, 0.3 * a))
237 .scale(Math.max(a, 1), Math.max(b, 1), Math.max(c, 1))
238 .translate(c, b, a);
239
240
241 final EmbeddingPlane result = plane.transform(t);
242
243
244 Vector3D expectedNormal = t.normalTransform().apply(plane.getNormal()).normalize();
245 if (!t.preservesOrientation()) {
246 expectedNormal = expectedNormal.negate();
247 }
248
249 EuclideanTestUtils.assertCoordinatesEqual(expectedNormal, result.getNormal(), TEST_EPS);
250
251 Assert.assertTrue(result.contains(t.apply(p1)));
252 Assert.assertTrue(result.contains(t.apply(p2)));
253 Assert.assertTrue(result.contains(t.apply(p3)));
254
255 Assert.assertFalse(result.contains(t.apply(notOnPlane1)));
256 Assert.assertFalse(result.contains(t.apply(notOnPlane2)));
257 });
258 }
259
260 @Test
261 public void testRotate() {
262
263 final Vector3D p1 = Vector3D.of(1.2, 3.4, -5.8);
264 final Vector3D p2 = Vector3D.of(3.4, -5.8, 1.2);
265 final Vector3D p3 = Vector3D.of(-2.0, 4.3, 0.7);
266 EmbeddingPlane plane = Planes.fromPoints(p1, p2, p3, TEST_PRECISION).getEmbedding();
267 final Vector3D oldNormal = plane.getNormal();
268
269
270 plane = plane.rotate(p2, QuaternionRotation.fromAxisAngle(p2.subtract(p1), 1.7));
271 Assert.assertTrue(plane.contains(p1));
272 Assert.assertTrue(plane.contains(p2));
273 Assert.assertFalse(plane.contains(p3));
274
275 plane = plane.rotate(p2, QuaternionRotation.fromAxisAngle(oldNormal, 0.1));
276 Assert.assertFalse(plane.contains(p1));
277 Assert.assertTrue(plane.contains(p2));
278 Assert.assertFalse(plane.contains(p3));
279
280 plane = plane.rotate(p1, QuaternionRotation.fromAxisAngle(oldNormal, 0.1));
281 Assert.assertFalse(plane.contains(p1));
282 Assert.assertFalse(plane.contains(p2));
283 Assert.assertFalse(plane.contains(p3));
284 }
285
286 @Test
287 public void testTranslate() {
288
289 final Vector3D p1 = Vector3D.of(1.2, 3.4, -5.8);
290 final Vector3D p2 = Vector3D.of(3.4, -5.8, 1.2);
291 final Vector3D p3 = Vector3D.of(-2.0, 4.3, 0.7);
292 EmbeddingPlane plane = Planes.fromPoints(p1, p2, p3, TEST_PRECISION).getEmbedding();
293
294
295 plane = plane.translate(Vector3D.linearCombination(2.0, plane.getU(), -1.5, plane.getV()));
296 Assert.assertTrue(plane.contains(p1));
297 Assert.assertTrue(plane.contains(p2));
298 Assert.assertTrue(plane.contains(p3));
299
300 plane = plane.translate(Vector3D.linearCombination(-1.2, plane.getNormal()));
301 Assert.assertFalse(plane.contains(p1));
302 Assert.assertFalse(plane.contains(p2));
303 Assert.assertFalse(plane.contains(p3));
304
305 plane = plane.translate(Vector3D.linearCombination(+1.2, plane.getNormal()));
306 Assert.assertTrue(plane.contains(p1));
307 Assert.assertTrue(plane.contains(p2));
308 Assert.assertTrue(plane.contains(p3));
309 }
310
311 @Test
312 public void testSubspaceTransform() {
313
314 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(Vector3D.of(0, 0, 1),
315 Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, TEST_PRECISION);
316
317
318 checkSubspaceTransform(plane.subspaceTransform(AffineTransformMatrix3D.createScale(2, 3, 4)),
319 Vector3D.of(0, 0, 4), Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y,
320 Vector3D.of(0, 0, 4), Vector3D.of(2, 0, 4), Vector3D.of(0, 3, 4));
321
322 checkSubspaceTransform(plane.subspaceTransform(AffineTransformMatrix3D.createTranslation(2, 3, 4)),
323 Vector3D.of(0, 0, 5), Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y,
324 Vector3D.of(2, 3, 5), Vector3D.of(3, 3, 5), Vector3D.of(2, 4, 5));
325
326 checkSubspaceTransform(plane.subspaceTransform(QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, PlaneAngleRadians.PI_OVER_TWO)),
327 Vector3D.of(1, 0, 0), Vector3D.Unit.MINUS_Z, Vector3D.Unit.PLUS_Y,
328 Vector3D.of(1, 0, 0), Vector3D.of(1, 0, -1), Vector3D.of(1, 1, 0));
329 }
330
331 private void checkSubspaceTransform(final SubspaceTransform st,
332 final Vector3D origin, final Vector3D u, final Vector3D v,
333 final Vector3D tOrigin, final Vector3D tU, final Vector3D tV) {
334
335 final EmbeddingPlane plane = st.getPlane();
336 final AffineTransformMatrix2D transform = st.getTransform();
337
338 checkPlane(plane, origin, u, v);
339
340 EuclideanTestUtils.assertCoordinatesEqual(tOrigin, plane.toSpace(transform.apply(Vector2D.ZERO)), TEST_EPS);
341 EuclideanTestUtils.assertCoordinatesEqual(tU, plane.toSpace(transform.apply(Vector2D.Unit.PLUS_X)), TEST_EPS);
342 EuclideanTestUtils.assertCoordinatesEqual(tV, plane.toSpace(transform.apply(Vector2D.Unit.PLUS_Y)), TEST_EPS);
343 }
344
345 @Test
346 public void testSubspaceTransform_transformsPointsCorrectly() {
347
348 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(Vector3D.of(1, 2, 3),
349 Vector3D.of(-1, -1, 1), Vector3D.of(-1, 1, 1), TEST_PRECISION);
350
351 EuclideanTestUtils.permuteSkipZero(-2, 2, 0.5, (a, b, c) -> {
352
353 final AffineTransformMatrix3D transform = AffineTransformMatrix3D.createTranslation(Vector3D.of(a, b, c))
354 .rotate(QuaternionRotation.fromAxisAngle(Vector3D.of(b, c, a), PlaneAngleRadians.PI * c))
355 .scale(0.1, 4, 8);
356
357
358 final SubspaceTransform st = plane.subspaceTransform(transform);
359
360
361 EuclideanTestUtils.permute(-5, 5, 1, (x, y) -> {
362 final Vector2D subPt = Vector2D.of(x, y);
363 final Vector3D expected = transform.apply(plane.toSpace(subPt));
364 final Vector3D actual = st.getPlane().toSpace(
365 st.getTransform().apply(subPt));
366
367 EuclideanTestUtils.assertCoordinatesEqual(expected, actual, TEST_EPS);
368 });
369 });
370 }
371
372 @Test
373 public void testEq_stdAndEmbedding() {
374
375 final Plane stdPlane = Planes.fromPointAndNormal(Vector3D.of(1, 1, 1), Vector3D.Unit.PLUS_Z, TEST_PRECISION);
376 final EmbeddingPlane embeddingPlane = Planes.fromPointAndPlaneVectors(Vector3D.of(1, 1, 1),
377 Vector3D.of(1, 1, 0), Vector3D.of(-1, 1, 0), TEST_PRECISION);
378
379 final EmbeddingPlane nonEqEmbeddingPlane = Planes.fromPointAndPlaneVectors(Vector3D.of(1, 1, 1),
380 Vector3D.of(1, 1, 1), Vector3D.of(-1, 1, 1), TEST_PRECISION);
381
382
383 Assert.assertTrue(stdPlane.eq(embeddingPlane, TEST_PRECISION));
384 Assert.assertTrue(embeddingPlane.eq(stdPlane, TEST_PRECISION));
385
386 Assert.assertFalse(stdPlane.eq(nonEqEmbeddingPlane, TEST_PRECISION));
387 Assert.assertFalse(nonEqEmbeddingPlane.eq(stdPlane, TEST_PRECISION));
388 }
389
390 @Test
391 public void testSimilarOrientation_stdAndEmbedding() {
392
393 final Plane stdPlane = Planes.fromPointAndNormal(Vector3D.of(1, 1, 1), Vector3D.Unit.PLUS_Z, TEST_PRECISION);
394 final EmbeddingPlane embeddingPlane = Planes.fromPointAndPlaneVectors(Vector3D.of(1, 1, 1),
395 Vector3D.of(1, 1, 1), Vector3D.of(-1, 1, 1), TEST_PRECISION);
396
397 final EmbeddingPlane nonSimilarEmbeddingPlane = Planes.fromPointAndPlaneVectors(Vector3D.of(1, 1, 1),
398 Vector3D.Unit.PLUS_Y, Vector3D.Unit.PLUS_X, TEST_PRECISION);
399
400
401 Assert.assertTrue(stdPlane.similarOrientation(embeddingPlane));
402 Assert.assertTrue(embeddingPlane.similarOrientation(stdPlane));
403
404 Assert.assertFalse(stdPlane.similarOrientation(nonSimilarEmbeddingPlane));
405 Assert.assertFalse(nonSimilarEmbeddingPlane.similarOrientation(stdPlane));
406 }
407
408 @Test
409 public void testHashCode() {
410
411 final Vector3D pt = Vector3D.of(1, 2, 3);
412 final Vector3D u = Vector3D.Unit.PLUS_X;
413 final Vector3D v = Vector3D.Unit.PLUS_Y;
414
415 final EmbeddingPlane a = Planes.fromPointAndPlaneVectors(pt, u, v, TEST_PRECISION);
416 final EmbeddingPlane b = Planes.fromPointAndPlaneVectors(Vector3D.of(1, 2, 4), u, v, TEST_PRECISION);
417 final EmbeddingPlane c = Planes.fromPointAndPlaneVectors(pt, Vector3D.of(1, 1, 0), v, TEST_PRECISION);
418 final EmbeddingPlane d = Planes.fromPointAndPlaneVectors(pt, u, Vector3D.Unit.MINUS_Y, TEST_PRECISION);
419 final EmbeddingPlane e = Planes.fromPointAndPlaneVectors(pt, u, v, new EpsilonDoublePrecisionContext(1e-8));
420 final EmbeddingPlane f = Planes.fromPointAndPlaneVectors(pt, u, v, TEST_PRECISION);
421
422
423 final int hash = a.hashCode();
424
425 Assert.assertEquals(hash, a.hashCode());
426
427 Assert.assertNotEquals(hash, b.hashCode());
428 Assert.assertNotEquals(hash, c.hashCode());
429 Assert.assertNotEquals(hash, d.hashCode());
430 Assert.assertNotEquals(hash, e.hashCode());
431
432 Assert.assertEquals(hash, f.hashCode());
433 }
434
435 @Test
436 public void testEquals() {
437
438 final Vector3D pt = Vector3D.of(1, 2, 3);
439 final Vector3D u = Vector3D.Unit.PLUS_X;
440 final Vector3D v = Vector3D.Unit.PLUS_Y;
441
442 final EmbeddingPlane a = Planes.fromPointAndPlaneVectors(pt, u, v, TEST_PRECISION);
443 final EmbeddingPlane b = Planes.fromPointAndPlaneVectors(Vector3D.of(1, 2, 4), u, v, TEST_PRECISION);
444 final EmbeddingPlane c = Planes.fromPointAndPlaneVectors(pt, Vector3D.Unit.MINUS_X, v, TEST_PRECISION);
445 final EmbeddingPlane d = Planes.fromPointAndPlaneVectors(pt, u, Vector3D.Unit.MINUS_Y, TEST_PRECISION);
446 final EmbeddingPlane e = Planes.fromPointAndPlaneVectors(pt, u, v, new EpsilonDoublePrecisionContext(1e-8));
447 final EmbeddingPlane f = Planes.fromPointAndPlaneVectors(pt, u, v, TEST_PRECISION);
448
449 final Plane stdPlane = Planes.fromPointAndNormal(pt, Vector3D.Unit.PLUS_Z, TEST_PRECISION);
450
451
452 Assert.assertEquals(a, a);
453
454 Assert.assertFalse(a.equals(null));
455 Assert.assertFalse(a.equals(new Object()));
456
457 Assert.assertNotEquals(a, b);
458 Assert.assertNotEquals(a, c);
459 Assert.assertNotEquals(a, d);
460 Assert.assertNotEquals(a, e);
461
462 Assert.assertEquals(a, f);
463 Assert.assertEquals(f, a);
464
465 Assert.assertNotEquals(a, stdPlane);
466 }
467
468 @Test
469 public void testToString() {
470
471 final EmbeddingPlane plane = Planes.fromPointAndPlaneVectors(Vector3D.ZERO,
472 Vector3D.Unit.PLUS_X, Vector3D.Unit.PLUS_Y, TEST_PRECISION);
473
474
475 final String str = plane.toString();
476
477
478 Assert.assertTrue(str.startsWith("EmbeddingPlane["));
479 Assert.assertTrue(str.matches(".*origin= \\(0(\\.0)?, 0(\\.0)?\\, 0(\\.0)?\\).*"));
480 Assert.assertTrue(str.matches(".*u= \\(1(\\.0)?, 0(\\.0)?\\, 0(\\.0)?\\).*"));
481 Assert.assertTrue(str.matches(".*v= \\(0(\\.0)?, 1(\\.0)?\\, 0(\\.0)?\\).*"));
482 Assert.assertTrue(str.matches(".*w= \\(0(\\.0)?, 0(\\.0)?\\, 1(\\.0)?\\).*"));
483 }
484
485 private static void checkPlane(final EmbeddingPlane plane, final Vector3D origin, Vector3D u, Vector3D v) {
486 u = u.normalize();
487 v = v.normalize();
488 final Vector3D w = u.cross(v);
489
490 EuclideanTestUtils.assertCoordinatesEqual(origin, plane.getOrigin(), TEST_EPS);
491 Assert.assertTrue(plane.contains(origin));
492
493 EuclideanTestUtils.assertCoordinatesEqual(u, plane.getU(), TEST_EPS);
494 Assert.assertEquals(1.0, plane.getU().norm(), TEST_EPS);
495
496 EuclideanTestUtils.assertCoordinatesEqual(v, plane.getV(), TEST_EPS);
497 Assert.assertEquals(1.0, plane.getV().norm(), TEST_EPS);
498
499 EuclideanTestUtils.assertCoordinatesEqual(w, plane.getW(), TEST_EPS);
500 Assert.assertEquals(1.0, plane.getW().norm(), TEST_EPS);
501
502 EuclideanTestUtils.assertCoordinatesEqual(w, plane.getNormal(), TEST_EPS);
503 Assert.assertEquals(1.0, plane.getNormal().norm(), TEST_EPS);
504
505 final double offset = plane.getOriginOffset();
506 Assert.assertEquals(Vector3D.ZERO.distance(plane.getOrigin()), Math.abs(offset), TEST_EPS);
507 EuclideanTestUtils.assertCoordinatesEqual(origin, plane.getNormal().multiply(-offset), TEST_EPS);
508 }
509 }