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 java.util.ArrayList;
20 import java.util.List;
21
22 import org.apache.commons.geometry.core.precision.DoublePrecisionContext;
23 import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
24 import org.apache.commons.geometry.euclidean.threed.line.Line3D;
25 import org.apache.commons.geometry.euclidean.threed.line.LineConvexSubset3D;
26 import org.apache.commons.geometry.euclidean.threed.line.LinecastPoint3D;
27 import org.apache.commons.geometry.euclidean.threed.line.Linecastable3D;
28 import org.junit.Assert;
29
30
31
32 class LinecastChecker3D {
33
34 private static final double TEST_EPS = 1e-10;
35
36 private static final DoublePrecisionContext TEST_PRECISION =
37 new EpsilonDoublePrecisionContext(TEST_EPS);
38
39
40 private final Linecastable3D target;
41
42
43 private final List<ExpectedResult> expectedResults = new ArrayList<>();
44
45
46
47
48
49 LinecastChecker3D(final Linecastable3D target) {
50 this.target = target;
51 }
52
53
54
55
56
57
58 public LinecastChecker3D expectNothing() {
59 expectedResults.clear();
60
61 return this;
62 }
63
64
65
66
67
68
69
70
71 public LinecastChecker3D expect(final Vector3D point, final Vector3D normal) {
72 expectedResults.add(new ExpectedResult(point, normal));
73
74 return this;
75 }
76
77
78
79
80
81
82 public LinecastChecker3D and(final Vector3D point, final Vector3D normal) {
83 return expect(point, normal);
84 }
85
86
87
88
89
90
91 public void whenGiven(final Line3D line) {
92 checkLinecastResults(target.linecast(line), line);
93 checkLinecastFirstResult(target.linecastFirst(line), line);
94 }
95
96
97
98
99
100
101 public void whenGiven(final LineConvexSubset3D segment) {
102 final Line3D line = segment.getLine();
103
104 checkLinecastResults(target.linecast(segment), line);
105 checkLinecastFirstResult(target.linecastFirst(segment), line);
106 }
107
108
109
110
111
112 private void checkLinecastResults(final List<LinecastPoint3D> results, final Line3D line) {
113 Assert.assertNotNull("Linecast result list cannot be null", results);
114 Assert.assertEquals("Unexpected result size for linecast", expectedResults.size(), results.size());
115
116 for (int i = 0; i < expectedResults.size(); ++i) {
117 final LinecastPoint3D expected = toLinecastPoint(expectedResults.get(i), line);
118 final LinecastPoint3D actual = results.get(i);
119
120 if (!eq(expected, actual)) {
121 Assert.fail("Unexpected linecast point at index " + i + " expected " + expected +
122 " but was " + actual);
123 }
124 }
125 }
126
127
128
129
130
131 private void checkLinecastFirstResult(final LinecastPoint3D result, final Line3D line) {
132 if (expectedResults.isEmpty()) {
133 Assert.assertNull("Expected linecastFirst result to be null", result);
134 } else {
135 final LinecastPoint3D expected = toLinecastPoint(expectedResults.get(0), line);
136
137 Assert.assertNotNull("Expected linecastFirst result to not be null", result);
138
139 if (!eq(expected, result)) {
140 Assert.fail("Unexpected result from linecastFirst: expected " + expected +
141 " but was " + result);
142 }
143 }
144 }
145
146
147
148
149
150 public static LinecastChecker3D with(final Linecastable3D src) {
151 return new LinecastChecker3D(src);
152 }
153
154
155
156
157
158
159 private static boolean eq(final LinecastPoint3D a, final LinecastPoint3D b) {
160 return a.getPoint().eq(b.getPoint(), TEST_PRECISION) &&
161 a.getNormal().eq(b.getNormal(), TEST_PRECISION) &&
162 a.getLine().equals(b.getLine()) &&
163 TEST_PRECISION.eq(a.getAbscissa(), b.getAbscissa());
164 }
165
166
167
168
169
170
171
172 private static LinecastPoint3D toLinecastPoint(final ExpectedResult expected, final Line3D line) {
173 return new LinecastPoint3D(expected.getPoint(), expected.getNormal(), line);
174 }
175
176
177
178 private static final class ExpectedResult {
179 private final Vector3D point;
180 private final Vector3D normal;
181
182 ExpectedResult(final Vector3D point, final Vector3D normal) {
183 this.point = point;
184 this.normal = normal;
185 }
186
187 public Vector3D getPoint() {
188 return point;
189 }
190
191 public Vector3D getNormal() {
192 return normal;
193 }
194 }
195 }