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.GeometryTestUtils;
20 import org.apache.commons.geometry.core.RegionLocation;
21 import org.apache.commons.geometry.core.partitioning.Split;
22 import org.apache.commons.geometry.euclidean.EuclideanTestUtils;
23 import org.apache.commons.geometry.euclidean.oned.Interval;
24 import org.apache.commons.numbers.core.Precision;
25 import org.junit.jupiter.api.Assertions;
26 import org.junit.jupiter.api.Test;
27
28 class LineSpanningSubsetTest {
29
30 private static final double TEST_EPS = 1e-10;
31
32 private static final Precision.DoubleEquivalence TEST_PRECISION =
33 Precision.doubleEquivalenceOfEpsilon(TEST_EPS);
34
35 @Test
36 void testProperties() {
37
38 final Line line = Lines.fromPoints(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION);
39
40
41 final LineSpanningSubset result = new LineSpanningSubset(line);
42
43
44 Assertions.assertSame(line, result.getHyperplane());
45 Assertions.assertSame(line, result.getLine());
46
47 Assertions.assertTrue(result.isFull());
48 Assertions.assertFalse(result.isEmpty());
49 Assertions.assertTrue(result.isInfinite());
50 Assertions.assertFalse(result.isFinite());
51
52 GeometryTestUtils.assertPositiveInfinity(result.getSize());
53 Assertions.assertNull(result.getCentroid());
54 Assertions.assertNull(result.getBounds());
55
56 Assertions.assertNull(result.getStartPoint());
57 GeometryTestUtils.assertNegativeInfinity(result.getSubspaceStart());
58 Assertions.assertNull(result.getEndPoint());
59 GeometryTestUtils.assertPositiveInfinity(result.getSubspaceEnd());
60 }
61
62 @Test
63 void testTransform() {
64
65 final AffineTransformMatrix2D t = AffineTransformMatrix2D.createRotation(-0.5 * Math.PI)
66 .translate(Vector2D.Unit.PLUS_X)
67 .scale(1, -1);
68
69 final LineConvexSubset span =
70 Lines.fromPointAndDirection(Vector2D.of(1, 0), Vector2D.Unit.PLUS_X, TEST_PRECISION).span();
71
72
73 final LineConvexSubset result = span.transform(t);
74
75
76 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.PLUS_Y, result.getLine().getDirection(), TEST_EPS);
77 }
78
79 @Test
80 void testReverse() {
81
82 final LineConvexSubset span =
83 Lines.fromPointAndDirection(Vector2D.of(1, 2), Vector2D.Unit.PLUS_X, TEST_PRECISION).span();
84
85
86 final LineConvexSubset rev = span.reverse();
87
88
89 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 2), rev.getLine().getOrigin(), TEST_EPS);
90 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.Unit.MINUS_X, rev.getLine().getDirection(), TEST_EPS);
91 }
92
93 @Test
94 void testClosest() {
95
96 final Vector2D p1 = Vector2D.of(0, -1);
97 final Vector2D p2 = Vector2D.of(0, 1);
98 final LineConvexSubset span =
99 Lines.fromPointAndDirection(p1, p1.directionTo(p2), TEST_PRECISION).span();
100
101
102 EuclideanTestUtils.assertCoordinatesEqual(p1, span.closest(p1), TEST_EPS);
103 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, -2), span.closest(Vector2D.of(0, -2)), TEST_EPS);
104 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, -2), span.closest(Vector2D.of(2, -2)), TEST_EPS);
105 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, -1), span.closest(Vector2D.of(-1, -1)), TEST_EPS);
106
107 EuclideanTestUtils.assertCoordinatesEqual(p2, span.closest(p2), TEST_EPS);
108 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 2), span.closest(Vector2D.of(0, 2)), TEST_EPS);
109 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 2), span.closest(Vector2D.of(-2, 2)), TEST_EPS);
110 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 1), span.closest(Vector2D.of(-1, 1)), TEST_EPS);
111
112 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.ZERO, span.closest(Vector2D.ZERO), TEST_EPS);
113 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, 0.5), span.closest(Vector2D.of(1, 0.5)), TEST_EPS);
114 EuclideanTestUtils.assertCoordinatesEqual(Vector2D.of(0, -0.5), span.closest(Vector2D.of(-2, -0.5)), TEST_EPS);
115 }
116
117 @Test
118 void testClassify() {
119
120 final LineConvexSubset span =
121 Lines.fromPointAndDirection(Vector2D.of(1, 1), Vector2D.Unit.PLUS_X, TEST_PRECISION).span();
122
123
124 for (double x = -10; x <= 10; x += 1) {
125 EuclideanTestUtils.assertRegionLocation(span, RegionLocation.INSIDE, Vector2D.of(x, 1 + 1e-11));
126
127 EuclideanTestUtils.assertRegionLocation(span, RegionLocation.OUTSIDE,
128 Vector2D.of(x, 0), Vector2D.of(x, 2));
129 }
130 }
131
132 @Test
133 void testSplit() {
134
135 final Vector2D pt = Vector2D.of(1, 1);
136
137 final LineConvexSubset span = Lines.fromPointAndDirection(pt, Vector2D.Unit.PLUS_X, TEST_PRECISION).span();
138
139
140 Split<LineConvexSubset> split;
141
142
143 split = span.split(Lines.fromPointAndAngle(Vector2D.of(2, 2), 0, TEST_PRECISION));
144 Assertions.assertNull(split.getMinus());
145 Assertions.assertSame(span, split.getPlus());
146
147 split = span.split(Lines.fromPointAndAngle(Vector2D.of(2, 2), Math.PI, TEST_PRECISION));
148 Assertions.assertSame(span, split.getMinus());
149 Assertions.assertNull(split.getPlus());
150
151
152 split = span.split(Lines.fromPointAndDirection(pt, Vector2D.Unit.PLUS_X, TEST_PRECISION));
153 Assertions.assertNull(split.getMinus());
154 Assertions.assertNull(split.getPlus());
155
156
157 checkSplit(span.split(Lines.fromPointAndAngle(pt, 1, TEST_PRECISION)),
158 null, pt,
159 pt, null);
160 checkSplit(span.split(Lines.fromPointAndAngle(pt, -1, TEST_PRECISION)),
161 pt, null,
162 null, pt);
163 }
164
165 @Test
166 void testGetInterval() {
167
168 final LineConvexSubset span =
169 Lines.fromPointAndDirection(Vector2D.of(2, -1), Vector2D.Unit.PLUS_X, TEST_PRECISION).span();
170
171
172 final Interval interval = span.getInterval();
173
174
175 GeometryTestUtils.assertNegativeInfinity(interval.getMin());
176 GeometryTestUtils.assertPositiveInfinity(interval.getMax());
177 }
178
179 @Test
180 void testToString() {
181
182 final LineConvexSubset span =
183 Lines.fromPointAndDirection(Vector2D.ZERO, Vector2D.Unit.PLUS_X, TEST_PRECISION).span();
184
185
186 final String str = span.toString();
187
188
189 GeometryTestUtils.assertContains("LineSpanningSubset[origin= (0", str);
190 GeometryTestUtils.assertContains(", direction= (1", str);
191 }
192
193 private static void checkSplit(final Split<LineConvexSubset> split, final Vector2D minusStart, final Vector2D minusEnd,
194 final Vector2D plusStart, final Vector2D plusEnd) {
195
196 final LineConvexSubset minus = split.getMinus();
197 if (minusStart == null && minusEnd == null) {
198 Assertions.assertNull(minus);
199 } else {
200 checkPoint(minusStart, minus.getStartPoint());
201 checkPoint(minusEnd, minus.getEndPoint());
202 }
203
204
205 final LineConvexSubset plus = split.getPlus();
206 if (plusStart == null && plusEnd == null) {
207 Assertions.assertNull(plus);
208 } else {
209 checkPoint(plusStart, plus.getStartPoint());
210 checkPoint(plusEnd, plus.getEndPoint());
211 }
212 }
213
214 private static void checkPoint(final Vector2D expected, final Vector2D pt) {
215 if (expected == null) {
216 Assertions.assertNull(pt);
217 } else {
218 EuclideanTestUtils.assertCoordinatesEqual(expected, pt, TEST_EPS);
219 }
220 }
221 }