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 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.oned.Interval;
24 import org.apache.commons.geometry.euclidean.threed.AffineTransformMatrix3D;
25 import org.apache.commons.geometry.euclidean.threed.Vector3D;
26 import org.apache.commons.geometry.euclidean.threed.rotation.QuaternionRotation;
27 import org.junit.Assert;
28 import org.junit.Test;
29
30 public class ReverseRay3DTest {
31
32 private static final double TEST_EPS = 1e-10;
33
34 private static final DoublePrecisionContext TEST_PRECISION =
35 new EpsilonDoublePrecisionContext(TEST_EPS);
36
37 @Test
38 public void testFromPointAndDirection() {
39
40 final Vector3D pt = Vector3D.of(1, 1, 2);
41
42
43 final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(pt, Vector3D.Unit.PLUS_Z, TEST_PRECISION);
44
45
46 Assert.assertTrue(revRay.isInfinite());
47 Assert.assertFalse(revRay.isFinite());
48
49 Assert.assertNull(revRay.getStartPoint());
50 EuclideanTestUtils.assertCoordinatesEqual(pt, revRay.getEndPoint(), TEST_EPS);
51
52 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.PLUS_Z, revRay.getLine().getDirection(), TEST_EPS);
53
54 GeometryTestUtils.assertNegativeInfinity(revRay.getSubspaceStart());
55 Assert.assertEquals(2, revRay.getSubspaceEnd(), TEST_EPS);
56
57 GeometryTestUtils.assertPositiveInfinity(revRay.getSize());
58
59 Assert.assertNull(revRay.getCentroid());
60 Assert.assertNull(revRay.getBounds());
61 }
62
63 @Test
64 public void testFromPointAndDirection_invalidArgs() {
65
66 final Vector3D pt = Vector3D.of(0, 2, 4);
67 final Vector3D dir = Vector3D.of(1e-11, 0, 0);
68
69
70 GeometryTestUtils.assertThrows(() -> {
71 Lines3D.reverseRayFromPointAndDirection(pt, dir, TEST_PRECISION);
72 }, IllegalArgumentException.class, "Line direction cannot be zero");
73 }
74
75 @Test
76 public void testFromPoint() {
77
78 final Vector3D pt = Vector3D.of(-2, -1, 2);
79
80 final Line3D line = Lines3D.fromPointAndDirection(Vector3D.of(1, 0, 2), Vector3D.Unit.PLUS_Y, TEST_PRECISION);
81
82
83 final ReverseRay3D revRay = Lines3D.reverseRayFromPoint(line, pt);
84
85
86 Assert.assertTrue(revRay.isInfinite());
87 Assert.assertFalse(revRay.isFinite());
88
89 Assert.assertNull(revRay.getStartPoint());
90 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(1, -1, 2), revRay.getEndPoint(), TEST_EPS);
91
92 GeometryTestUtils.assertNegativeInfinity(revRay.getSubspaceStart());
93 Assert.assertEquals(-1, revRay.getSubspaceEnd(), TEST_EPS);
94
95 GeometryTestUtils.assertPositiveInfinity(revRay.getSize());
96
97 Assert.assertNull(revRay.getCentroid());
98 Assert.assertNull(revRay.getBounds());
99 }
100
101 @Test
102 public void testFromPoint_invalidArgs() {
103
104 final Line3D line = Lines3D.fromPointAndDirection(Vector3D.ZERO, Vector3D.Unit.PLUS_X, TEST_PRECISION);
105
106
107 GeometryTestUtils.assertThrows(() -> {
108 Lines3D.reverseRayFromPoint(line, Vector3D.NaN);
109 }, IllegalArgumentException.class, "Invalid reverse ray end location: NaN");
110
111 GeometryTestUtils.assertThrows(() -> {
112 Lines3D.reverseRayFromPoint(line, Vector3D.NEGATIVE_INFINITY);
113 }, IllegalArgumentException.class, "Invalid reverse ray end location: NaN");
114
115 GeometryTestUtils.assertThrows(() -> {
116 Lines3D.reverseRayFromPoint(line, Vector3D.POSITIVE_INFINITY);
117 }, IllegalArgumentException.class, "Invalid reverse ray end location: NaN");
118 }
119
120 @Test
121 public void testFromLocation() {
122
123 final Line3D line = Lines3D.fromPointAndDirection(Vector3D.of(-1, 0, 0), Vector3D.Unit.PLUS_Z, TEST_PRECISION);
124
125
126 final ReverseRay3D revRay = Lines3D.reverseRayFromLocation(line, -1);
127
128
129 Assert.assertTrue(revRay.isInfinite());
130 Assert.assertFalse(revRay.isFinite());
131
132 Assert.assertNull(revRay.getStartPoint());
133 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(-1, 0, -1), revRay.getEndPoint(), TEST_EPS);
134
135 GeometryTestUtils.assertNegativeInfinity(revRay.getSubspaceStart());
136 Assert.assertEquals(-1, revRay.getSubspaceEnd(), TEST_EPS);
137
138 GeometryTestUtils.assertPositiveInfinity(revRay.getSize());
139
140 Assert.assertNull(revRay.getCentroid());
141 Assert.assertNull(revRay.getBounds());
142 }
143
144 @Test
145 public void testTransform() {
146
147 final AffineTransformMatrix3D t = QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, 0.5 * Math.PI)
148 .toMatrix()
149 .translate(Vector3D.Unit.PLUS_Y);
150
151 final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(Vector3D.of(1, 0, 0), Vector3D.Unit.PLUS_X, TEST_PRECISION);
152
153
154 final ReverseRay3D result = revRay.transform(t);
155
156
157 Assert.assertNull(result.getStartPoint());
158 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 1, -1), result.getEndPoint(), TEST_EPS);
159
160 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.MINUS_Z, result.getLine().getDirection(), TEST_EPS);
161 }
162
163 @Test
164 public void testTransform_reflection() {
165
166 final AffineTransformMatrix3D t = QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Y, 0.5 * Math.PI)
167 .toMatrix()
168 .translate(Vector3D.Unit.PLUS_Y)
169 .scale(1, 1, -2);
170
171 final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(Vector3D.of(1, 0, 0), Vector3D.Unit.PLUS_X, TEST_PRECISION);
172
173
174 final ReverseRay3D result = revRay.transform(t);
175
176
177 Assert.assertNull(result.getStartPoint());
178 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.of(0, 1, 2), result.getEndPoint(), TEST_EPS);
179
180 EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.PLUS_Z, result.getLine().getDirection(), TEST_EPS);
181 }
182
183 @Test
184 public void testContains() {
185
186 final Vector3D p0 = Vector3D.of(1, 1, 1);
187
188 final Vector3D delta = Vector3D.of(1e-12, 1e-12, 1e-12);
189
190 final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(Vector3D.of(1, 1, 1), Vector3D.Unit.PLUS_X, TEST_PRECISION);
191
192
193 Assert.assertFalse(revRay.contains(Vector3D.of(2, 2, 2)));
194 Assert.assertFalse(revRay.contains(Vector3D.of(1.1, 1, 1)));
195 Assert.assertFalse(revRay.contains(Vector3D.of(100, 1, 1)));
196
197 Assert.assertTrue(revRay.contains(p0));
198 Assert.assertTrue(revRay.contains(p0.add(delta)));
199
200 Assert.assertTrue(revRay.contains(Vector3D.of(-1000, 1, 1)));
201 }
202
203 @Test
204 public void testGetInterval() {
205
206 final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(Vector3D.of(2, -1, 3), Vector3D.Unit.PLUS_Y, TEST_PRECISION);
207
208
209 final Interval interval = revRay.getInterval();
210
211
212 GeometryTestUtils.assertNegativeInfinity(interval.getMin());
213 Assert.assertEquals(-1, interval.getMax(), TEST_EPS);
214
215 Assert.assertSame(revRay.getLine().getPrecision(), interval.getMaxBoundary().getPrecision());
216 }
217
218 @Test
219 public void testToString() {
220
221 final ReverseRay3D revRay = Lines3D.reverseRayFromPointAndDirection(Vector3D.ZERO, Vector3D.Unit.PLUS_X, TEST_PRECISION);
222
223
224 final String str = revRay.toString();
225
226
227 GeometryTestUtils.assertContains("ReverseRay3D[direction= (1", str);
228 GeometryTestUtils.assertContains(", endPoint= (0", str);
229 }
230 }