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