1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.geometry.euclidean.threed.line;
18
19 import java.util.List;
20
21 import org.apache.commons.geometry.core.GeometryTestUtils;
22 import org.apache.commons.geometry.core.Transform;
23 import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
24 import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
25 import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
26 import org.apache.commons.geometry.euclidean.oned.Interval;
27 import org.apache.commons.geometry.euclidean.oned.RegionBSPTree1D;
28 import org.apache.commons.geometry.euclidean.threed.AffineTransformMatrix3D;
29 import org.apache.commons.geometry.euclidean.threed.Bounds3D;
30 import org.apache.commons.geometry.euclidean.threed.Vector3D;
31 import org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;
32 import org.apache.commons.numbers.angle.PlaneAngleRadians;
33 import org.junit.Assert;
34 import org.junit.Test;
35
36 public class EmbeddedTreeLineSubset3DTest {
37
38 private static final double TEST_EPS = 1e-10;
39
40 private static final DoublePrecisionContext TEST_PRECISION =
41 new EpsilonDoublePrecisionContext(TEST_EPS);
42
43 private final Line3D testLine = Lines3D.fromPointAndDirection(Vector3D.ZERO, Vector3D.of(1, 1, 0), TEST_PRECISION);
44
45 @Test
46 public void testCtor_default() {
47
48 final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine);
49
50
51 Assert.assertSame(testLine, sub.getLine());
52 Assert.assertTrue(sub.getSubspaceRegion().isEmpty());
53 Assert.assertEquals(0, sub.getSize(), TEST_EPS);
54 }
55
56 @Test
57 public void testCtor_true() {
58
59 final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, true);
60
61
62 Assert.assertSame(testLine, sub.getLine());
63 Assert.assertTrue(sub.getSubspaceRegion().isFull());
64 GeometryTestUtils.assertPositiveInfinity(sub.getSize());
65 }
66
67 @Test
68 public void testCtor_false() {
69
70 final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, false);
71
72
73 Assert.assertSame(testLine, sub.getLine());
74 Assert.assertTrue(sub.getSubspaceRegion().isEmpty());
75 Assert.assertEquals(0, sub.getSize(), TEST_EPS);
76 }
77
78 @Test
79 public void testCtor_lineAndRegion() {
80
81 final RegionBSPTree1D tree = RegionBSPTree1D.empty();
82
83
84 final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, tree);
85
86
87 Assert.assertSame(testLine, sub.getLine());
88 Assert.assertSame(tree, sub.getSubspaceRegion());
89 Assert.assertEquals(0, sub.getSize(), TEST_EPS);
90 }
91
92 @Test
93 public void testProperties_full() {
94
95 final EmbeddedTreeLineSubset3D full = new EmbeddedTreeLineSubset3D(testLine, true);
96
97
98 Assert.assertTrue(full.isInfinite());
99 Assert.assertFalse(full.isFinite());
100
101 GeometryTestUtils.assertPositiveInfinity(full.getSize());
102 Assert.assertNull(full.getCentroid());
103 Assert.assertNull(full.getBounds());
104 }
105
106 @Test
107 public void testProperties_empty() {
108
109 final EmbeddedTreeLineSubset3D empty = new EmbeddedTreeLineSubset3D(testLine, false);
110
111
112 Assert.assertFalse(empty.isInfinite());
113 Assert.assertTrue(empty.isFinite());
114
115 Assert.assertEquals(0, empty.getSize(), TEST_EPS);
116 Assert.assertNull(empty.getCentroid());
117 Assert.assertNull(empty.getBounds());
118 }
119
120 @Test
121 public void testProperties_half() {
122
123 final EmbeddedTreeLineSubset3D half = new EmbeddedTreeLineSubset3D(testLine, false);
124 half.getSubspaceRegion().add(Interval.min(1, TEST_PRECISION));
125
126
127 Assert.assertTrue(half.isInfinite());
128 Assert.assertFalse(half.isFinite());
129
130 GeometryTestUtils.assertPositiveInfinity(half.getSize());
131 Assert.assertNull(half.getCentroid());
132 Assert.assertNull(half.getBounds());
133 }
134
135 @Test
136 public void testProperties_finite() {
137
138 final Line3D line = Lines3D.fromPointAndDirection(Vector3D.of(0, 0, 1), Vector3D.of(1, 1, 0), TEST_PRECISION);
139 final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(line);
140
141 final double sqrt2 = Math.sqrt(2);
142 sub.getSubspaceRegion().add(Interval.of(0, sqrt2, TEST_PRECISION));
143 sub.getSubspaceRegion().add(Interval.of(-2 * sqrt2, -sqrt2, TEST_PRECISION));
144
145
146 Assert.assertFalse(sub.isInfinite());
147 Assert.assertTrue(sub.isFinite());
148
149 Assert.assertEquals(2 * sqrt2, sub.getSize(), TEST_EPS);
150 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(-0.5, -0.5, 1), sub.getCentroid(), TEST_EPS);
151
152 final Bounds3D bounds = sub.getBounds();
153 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(-2, -2, 1), bounds.getMin(), TEST_EPS);
154 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, 1, 1), bounds.getMax(), TEST_EPS);
155 }
156
157 @Test
158 public void testTransform_full() {
159
160 final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, true);
161
162 final Transform<Vector3D> transform = AffineTransformMatrix3D.identity()
163 .translate(Vector3D.of(1, 0, 0))
164 .scale(Vector3D.of(2, 1, 1))
165 .rotate(QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, PlaneAngleRadians.PI_OVER_TWO));
166
167
168 final EmbeddedTreeLineSubset3D result = sub.transform(transform);
169
170
171 final Line3D resultLine = result.getLine();
172
173 final Vector3D expectedOrigin = Lines3D.fromPoints(Vector3D.of(0, 0, -2), Vector3D.of(0, 1, -4), TEST_PRECISION)
174 .getOrigin();
175
176 EuclideanTestUtils.assertCoordinatesEqual(expectedOrigin, resultLine.getOrigin(), TEST_EPS);
177 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 1, -2).normalize(), resultLine.getDirection(), TEST_EPS);
178
179 Assert.assertTrue(result.getSubspaceRegion().isFull());
180 }
181
182 @Test
183 public void testTransform_finite() {
184
185 final RegionBSPTree1D tree = RegionBSPTree1D.empty();
186 tree.add(Interval.of(
187 testLine.toSubspace(Vector3D.of(1, 1, 0)).getX(),
188 testLine.toSubspace(Vector3D.of(2, 2, 0)).getX(), TEST_PRECISION));
189
190 final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, tree);
191
192 final Transform<Vector3D> transform = AffineTransformMatrix3D.identity()
193 .translate(Vector3D.of(1, 0, 0))
194 .scale(Vector3D.of(2, 1, 1))
195 .rotate(QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, PlaneAngleRadians.PI_OVER_TWO));
196
197
198 final EmbeddedTreeLineSubset3D result = sub.transform(transform);
199
200
201 final Line3D resultLine = result.getLine();
202
203 final Vector3D expectedOrigin = Lines3D.fromPoints(Vector3D.of(0, 0, -2), Vector3D.of(0, 1, -4), TEST_PRECISION)
204 .getOrigin();
205
206 EuclideanTestUtils.assertCoordinatesEqual(expectedOrigin, resultLine.getOrigin(), TEST_EPS);
207 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 1, -2).normalize(), resultLine.getDirection(), TEST_EPS);
208
209 Assert.assertFalse(result.getSubspaceRegion().isFull());
210
211 final List<Interval> intervals = result.getSubspaceRegion().toIntervals();
212 Assert.assertEquals(1, intervals.size());
213
214 final Interval resultInterval = intervals.get(0);
215 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 1, -4),
216 resultLine.toSpace(resultInterval.getMin()), TEST_EPS);
217 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 2, -6),
218 resultLine.toSpace(resultInterval.getMax()), TEST_EPS);
219 }
220
221 @Test
222 public void testToConvex_full() {
223
224 final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, true);
225
226
227 final List<LineConvexSubset3D> segments = sub.toConvex();
228
229
230 Assert.assertEquals(1, segments.size());
231 Assert.assertTrue(segments.get(0).getSubspaceRegion().isFull());
232 }
233
234 @Test
235 public void testToConvex_finite() {
236
237 final RegionBSPTree1D tree = RegionBSPTree1D.empty();
238 tree.add(Interval.of(
239 testLine.toSubspace(Vector3D.of(1, 1, 0)).getX(),
240 testLine.toSubspace(Vector3D.of(2, 2, 0)).getX(), TEST_PRECISION));
241
242 final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine, tree);
243
244
245 final List<LineConvexSubset3D> segments = sub.toConvex();
246
247
248 Assert.assertEquals(1, segments.size());
249
250 final LineConvexSubset3D segment = segments.get(0);
251 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, 1, 0), segment.getStartPoint(), TEST_EPS);
252 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(2, 2, 0), segment.getEndPoint(), TEST_EPS);
253 }
254
255 @Test
256 public void testToString() {
257
258 final EmbeddedTreeLineSubset3D sub = new EmbeddedTreeLineSubset3D(testLine);
259
260
261 final String str = sub.toString();
262
263
264 Assert.assertTrue(str.contains("EmbeddedTreeLineSubset3D[lineOrigin= "));
265 Assert.assertTrue(str.contains(", lineDirection= "));
266 Assert.assertTrue(str.contains(", region= "));
267 }
268 }