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 org.apache.commons.geometry.core.precision.DoublePrecisionContext;
20 import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
21 import org.apache.commons.geometry.euclidean.twod.shape.Parallelogram;
22 import org.junit.Test;
23
24 public class BoundarySourceLinecaster2DTest {
25
26 private static final double TEST_EPS = 1e-10;
27
28 private static final DoublePrecisionContext TEST_PRECISION =
29 new EpsilonDoublePrecisionContext(TEST_EPS);
30
31 private static final BoundarySource2D UNIT_SQUARE =
32 Parallelogram.axisAligned(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION);
33
34 @Test
35 public void testLinecast_line_simple() {
36
37 final BoundarySourceLinecaster2D linecaster = new BoundarySourceLinecaster2D(UNIT_SQUARE);
38
39
40
41
42 LinecastChecker2D.with(linecaster)
43 .expectNothing()
44 .whenGiven(Lines.fromPointAndDirection(Vector2D.of(0, 4), Vector2D.Unit.MINUS_X, TEST_PRECISION));
45
46
47 LinecastChecker2D.with(linecaster)
48 .expect(Vector2D.of(0, 0.5), Vector2D.Unit.MINUS_X)
49 .and(Vector2D.of(1, 0.5), Vector2D.Unit.PLUS_X)
50 .whenGiven(Lines.fromPointAndDirection(Vector2D.of(0.5, 0.5), Vector2D.Unit.PLUS_X, TEST_PRECISION));
51
52 LinecastChecker2D.with(linecaster)
53 .expect(Vector2D.of(1, 0.5), Vector2D.Unit.PLUS_X)
54 .and(Vector2D.of(0, 0.5), Vector2D.Unit.MINUS_X)
55 .whenGiven(Lines.fromPointAndDirection(Vector2D.of(0.5, 0.5), Vector2D.Unit.MINUS_X, TEST_PRECISION));
56 }
57
58 @Test
59 public void testLinecast_line_alongFace() {
60
61 final BoundarySourceLinecaster2D linecaster = new BoundarySourceLinecaster2D(UNIT_SQUARE);
62
63
64 LinecastChecker2D.with(linecaster)
65 .expect(Vector2D.of(0, 1), Vector2D.Unit.MINUS_X)
66 .and(Vector2D.of(1, 1), Vector2D.Unit.PLUS_X)
67 .whenGiven(Lines.fromPointAndDirection(Vector2D.of(0, 1), Vector2D.Unit.PLUS_X, TEST_PRECISION));
68 }
69
70 @Test
71 public void testLinecast_line_corners() {
72
73 final BoundarySourceLinecaster2D linecaster = new BoundarySourceLinecaster2D(UNIT_SQUARE);
74
75
76
77
78 LinecastChecker2D.with(linecaster)
79 .expect(Vector2D.of(1, 1), Vector2D.Unit.PLUS_Y)
80 .and(Vector2D.of(1, 1), Vector2D.Unit.PLUS_X)
81 .whenGiven(Lines.fromPointAndDirection(Vector2D.of(0, 2), Vector2D.of(1, -1), TEST_PRECISION));
82
83
84 LinecastChecker2D.with(linecaster)
85 .expect(Vector2D.ZERO, Vector2D.Unit.MINUS_X)
86 .and(Vector2D.ZERO, Vector2D.Unit.MINUS_Y)
87 .and(Vector2D.of(1, 1), Vector2D.Unit.PLUS_Y)
88 .and(Vector2D.of(1, 1), Vector2D.Unit.PLUS_X)
89 .whenGiven(Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION));
90 }
91
92 @Test
93 public void testLinecast_line_removesDuplicatePoints() {
94
95 final BoundarySource2D src = BoundarySource2D.from(
96 Lines.segmentFromPoints(Vector2D.of(-1, -1), Vector2D.ZERO, TEST_PRECISION),
97 Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION)
98 );
99 final BoundarySourceLinecaster2D linecaster = new BoundarySourceLinecaster2D(src);
100
101
102 LinecastChecker2D.with(linecaster)
103 .expect(Vector2D.ZERO, Vector2D.Unit.from(1, -1))
104 .whenGiven(Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION));
105 }
106
107 @Test
108 public void testLinecast_segment_simple() {
109
110 final BoundarySourceLinecaster2D linecaster = new BoundarySourceLinecaster2D(UNIT_SQUARE);
111
112
113
114
115 LinecastChecker2D.with(linecaster)
116 .expectNothing()
117 .whenGiven(Lines.fromPointAndDirection(Vector2D.of(0, 4), Vector2D.Unit.MINUS_X, TEST_PRECISION)
118 .segment(-10, 10));
119
120
121 LinecastChecker2D.with(linecaster)
122 .expectNothing()
123 .whenGiven(Lines.fromPointAndDirection(Vector2D.of(0.5, 0.5), Vector2D.Unit.PLUS_X, TEST_PRECISION)
124 .segment(2, 10));
125
126
127 LinecastChecker2D.with(linecaster)
128 .expect(Vector2D.of(0, 0.5), Vector2D.Unit.MINUS_X)
129 .and(Vector2D.of(1, 0.5), Vector2D.Unit.PLUS_X)
130 .whenGiven(Lines.fromPointAndDirection(Vector2D.of(0.5, 0.5), Vector2D.Unit.PLUS_X, TEST_PRECISION)
131 .segment(-10, 10));
132
133 LinecastChecker2D.with(linecaster)
134 .expect(Vector2D.of(1, 0.5), Vector2D.Unit.PLUS_X)
135 .and(Vector2D.of(0, 0.5), Vector2D.Unit.MINUS_X)
136 .whenGiven(Lines.fromPointAndDirection(Vector2D.of(0.5, 0.5), Vector2D.Unit.MINUS_X, TEST_PRECISION)
137 .segment(-10, 10));
138 }
139
140 @Test
141 public void testLinecast_segment_boundaryExcluded() {
142
143 final BoundarySourceLinecaster2D linecaster = new BoundarySourceLinecaster2D(UNIT_SQUARE);
144
145
146 final Vector2D center = Vector2D.of(0.5, 0.5);
147 LinecastChecker2D.with(linecaster)
148 .expect(Vector2D.of(1, 0.5), Vector2D.Unit.PLUS_X)
149 .whenGiven(Lines.fromPointAndDirection(center, Vector2D.Unit.PLUS_X, TEST_PRECISION)
150 .rayFrom(center));
151
152 LinecastChecker2D.with(linecaster)
153 .expect(Vector2D.of(1, 0.5), Vector2D.Unit.PLUS_X)
154 .whenGiven(Lines.fromPointAndDirection(center, Vector2D.Unit.MINUS_X, TEST_PRECISION)
155 .reverseRayTo(center));
156 }
157
158 @Test
159 public void testLinecast_segment_startEndPointsOnBoundaries() {
160
161 final BoundarySourceLinecaster2D linecaster = new BoundarySourceLinecaster2D(UNIT_SQUARE);
162
163
164 LinecastChecker2D.with(linecaster)
165 .expect(Vector2D.of(1, 0.5), Vector2D.Unit.PLUS_X)
166 .and(Vector2D.of(0, 0.5), Vector2D.Unit.MINUS_X)
167 .whenGiven(Lines.segmentFromPoints(Vector2D.of(1, 0.5), Vector2D.of(0, 0.5), TEST_PRECISION));
168 }
169
170 @Test
171 public void testLinecast_segment_alongFace() {
172
173 final BoundarySourceLinecaster2D linecaster = new BoundarySourceLinecaster2D(UNIT_SQUARE);
174
175
176
177
178 LinecastChecker2D.with(linecaster)
179 .expect(Vector2D.of(0, 1), Vector2D.Unit.MINUS_X)
180 .and(Vector2D.of(1, 1), Vector2D.Unit.PLUS_X)
181 .whenGiven(Lines.segmentFromPoints(Vector2D.of(-1, 1), Vector2D.of(2, 1), TEST_PRECISION));
182
183
184 LinecastChecker2D.with(linecaster)
185 .expect(Vector2D.of(1, 1), Vector2D.Unit.PLUS_X)
186 .whenGiven(Lines.segmentFromPoints(Vector2D.of(0.25, 1), Vector2D.of(2, 1), TEST_PRECISION));
187
188
189 LinecastChecker2D.with(linecaster)
190 .expectNothing()
191 .whenGiven(Lines.segmentFromPoints(Vector2D.of(0.25, 1), Vector2D.of(0.75, 1), TEST_PRECISION));
192 }
193
194 @Test
195 public void testLinecast_segment_corners() {
196
197 final BoundarySourceLinecaster2D linecaster = new BoundarySourceLinecaster2D(UNIT_SQUARE);
198
199
200
201
202 LinecastChecker2D.with(linecaster)
203 .expect(Vector2D.of(1, 1), Vector2D.Unit.PLUS_Y)
204 .and(Vector2D.of(1, 1), Vector2D.Unit.PLUS_X)
205 .whenGiven(Lines.segmentFromPoints(Vector2D.of(0, 2), Vector2D.of(2, 0), TEST_PRECISION));
206
207
208 LinecastChecker2D.with(linecaster)
209 .expect(Vector2D.of(1, 1), Vector2D.Unit.PLUS_Y)
210 .and(Vector2D.of(1, 1), Vector2D.Unit.PLUS_X)
211 .whenGiven(Lines.segmentFromPoints(Vector2D.of(1, 1), Vector2D.of(2, 0), TEST_PRECISION));
212
213
214 LinecastChecker2D.with(linecaster)
215 .expect(Vector2D.of(1, 1), Vector2D.Unit.PLUS_Y)
216 .and(Vector2D.of(1, 1), Vector2D.Unit.PLUS_X)
217 .whenGiven(Lines.segmentFromPoints(Vector2D.of(0, 2), Vector2D.of(1, 1), TEST_PRECISION));
218 }
219
220 @Test
221 public void testLinecast_segment_removesDuplicatePoints() {
222
223 final BoundarySource2D src = BoundarySource2D.from(
224 Lines.segmentFromPoints(Vector2D.of(-1, -1), Vector2D.ZERO, TEST_PRECISION),
225 Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.of(1, 1), TEST_PRECISION)
226 );
227 final BoundarySourceLinecaster2D linecaster = new BoundarySourceLinecaster2D(src);
228
229
230 LinecastChecker2D.with(linecaster)
231 .expect(Vector2D.ZERO, Vector2D.Unit.from(1, -1))
232 .whenGiven(Lines.segmentFromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION));
233 }
234 }
235