1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.geometry.core.partitioning;
18
19 import java.util.ArrayList;
20 import java.util.Arrays;
21 import java.util.Collections;
22 import java.util.List;
23
24 import org.apache.commons.geometry.core.GeometryTestUtils;
25 import org.apache.commons.geometry.core.Region;
26 import org.apache.commons.geometry.core.RegionLocation;
27 import org.apache.commons.geometry.core.Transform;
28 import org.apache.commons.geometry.core.partitioning.test.PartitionTestUtils;
29 import org.apache.commons.geometry.core.partitioning.test.TestLine;
30 import org.apache.commons.geometry.core.partitioning.test.TestLineSegment;
31 import org.apache.commons.geometry.core.partitioning.test.TestPoint2D;
32 import org.apache.commons.geometry.core.partitioning.test.TestTransform2D;
33 import org.junit.Assert;
34 import org.junit.Test;
35
36 public class AbstractConvexHyperplaneBoundedRegionTest {
37
38 @Test
39 public void testBoundaries_areUnmodifiable() {
40
41 final StubRegion region = new StubRegion(new ArrayList<>());
42
43
44 GeometryTestUtils.assertThrows(() -> {
45 region.getBoundaries().add(TestLine.X_AXIS.span());
46 }, UnsupportedOperationException.class);
47 }
48
49 @Test
50 public void testFull() {
51
52 final StubRegion region = new StubRegion(Collections.emptyList());
53
54
55 Assert.assertTrue(region.isFull());
56 Assert.assertFalse(region.isEmpty());
57 }
58
59 @Test
60 public void testGetBoundarySize() {
61
62 final TestPoint2D p1 = new TestPoint2D(1, 0);
63 final TestPoint2D p2 = new TestPoint2D(2, 0);
64 final TestPoint2D p3 = new TestPoint2D(1, 1);
65
66
67 Assert.assertEquals(0, new StubRegion(Collections.emptyList()).getBoundarySize(), PartitionTestUtils.EPS);
68 GeometryTestUtils.assertPositiveInfinity(new StubRegion(Collections.singletonList(TestLine.X_AXIS.span())).getBoundarySize());
69 Assert.assertEquals(2 + Math.sqrt(2), new StubRegion(Arrays.asList(
70 new TestLineSegment(p1, p2),
71 new TestLineSegment(p2, p3),
72 new TestLineSegment(p3, p1)
73 )).getBoundarySize(), PartitionTestUtils.EPS);
74 }
75
76 @Test
77 public void testClassify() {
78
79 final TestPoint2D p1 = new TestPoint2D(1, 0);
80 final TestPoint2D p2 = new TestPoint2D(2, 0);
81 final TestPoint2D p3 = new TestPoint2D(1, 1);
82
83 final StubRegion full = new StubRegion(Collections.emptyList());
84 final StubRegion halfSpace = new StubRegion(Collections.singletonList(TestLine.X_AXIS.span()));
85 final StubRegion triangle = new StubRegion(Arrays.asList(
86 new TestLineSegment(p1, p2),
87 new TestLineSegment(p2, p3),
88 new TestLineSegment(p3, p1)
89 ));
90
91
92 checkClassify(full, RegionLocation.INSIDE, TestPoint2D.ZERO, p1, p2, p3);
93
94 checkClassify(halfSpace, RegionLocation.INSIDE, new TestPoint2D(0, 1));
95 checkClassify(halfSpace, RegionLocation.OUTSIDE, new TestPoint2D(0, -1));
96 checkClassify(halfSpace, RegionLocation.BOUNDARY,
97 new TestPoint2D(-1, 0), new TestPoint2D(0, 0), new TestPoint2D(1, 0));
98
99 checkClassify(triangle, RegionLocation.INSIDE, new TestPoint2D(1.25, 0.25));
100 checkClassify(triangle, RegionLocation.OUTSIDE, new TestPoint2D(-1, 0), new TestPoint2D(0, 0), new TestPoint2D(3, 0));
101 checkClassify(triangle, RegionLocation.BOUNDARY, p1, p2, p3);
102 }
103
104 @Test
105 public void testProject() {
106
107 final TestPoint2D p1 = new TestPoint2D(1, 0);
108 final TestPoint2D p2 = new TestPoint2D(2, 0);
109 final TestPoint2D p3 = new TestPoint2D(1, 1);
110
111 final StubRegion full = new StubRegion(Collections.emptyList());
112 final StubRegion halfSpace = new StubRegion(Collections.singletonList(TestLine.X_AXIS.span()));
113 final StubRegion triangle = new StubRegion(Arrays.asList(
114 new TestLineSegment(p1, p2),
115 new TestLineSegment(p2, p3),
116 new TestLineSegment(p3, p1)
117 ));
118
119
120 Assert.assertNull(full.project(TestPoint2D.ZERO));
121 Assert.assertNull(full.project(new TestPoint2D(1, 1)));
122
123 PartitionTestUtils.assertPointsEqual(TestPoint2D.ZERO, halfSpace.project(new TestPoint2D(0, 1)));
124 PartitionTestUtils.assertPointsEqual(TestPoint2D.ZERO, halfSpace.project(new TestPoint2D(0, 0)));
125 PartitionTestUtils.assertPointsEqual(TestPoint2D.ZERO, halfSpace.project(new TestPoint2D(0, -1)));
126
127 PartitionTestUtils.assertPointsEqual(new TestPoint2D(1.25, 0), triangle.project(new TestPoint2D(1.25, 0.1)));
128 PartitionTestUtils.assertPointsEqual(p1, triangle.project(TestPoint2D.ZERO));
129 PartitionTestUtils.assertPointsEqual(p3, triangle.project(new TestPoint2D(0, 10)));
130 }
131
132 @Test
133 public void testTrim() {
134
135 final TestPoint2D p1 = new TestPoint2D(1, 0);
136 final TestPoint2D p2 = new TestPoint2D(2, 0);
137 final TestPoint2D p3 = new TestPoint2D(2, 1);
138 final TestPoint2D p4 = new TestPoint2D(1, 1);
139
140 final StubRegion full = new StubRegion(Collections.emptyList());
141 final StubRegion halfSpace = new StubRegion(Collections.singletonList(TestLine.Y_AXIS.span()));
142 final StubRegion square = new StubRegion(Arrays.asList(
143 new TestLineSegment(p1, p2),
144 new TestLineSegment(p2, p3),
145 new TestLineSegment(p3, p4),
146 new TestLineSegment(p4, p1)
147 ));
148
149 final TestLineSegment segment = new TestLineSegment(new TestPoint2D(-1, 0.5), new TestPoint2D(4, 0.5));
150
151
152 Assert.assertSame(segment, full.trim(segment));
153
154 final TestLineSegment trimmedA = halfSpace.trim(segment);
155 PartitionTestUtils.assertPointsEqual(new TestPoint2D(-1, 0.5), trimmedA.getStartPoint());
156 PartitionTestUtils.assertPointsEqual(new TestPoint2D(0, 0.5), trimmedA.getEndPoint());
157
158 final TestLineSegment trimmedB = square.trim(segment);
159 PartitionTestUtils.assertPointsEqual(new TestPoint2D(1, 0.5), trimmedB.getStartPoint());
160 PartitionTestUtils.assertPointsEqual(new TestPoint2D(2, 0.5), trimmedB.getEndPoint());
161 }
162
163 @Test
164 public void testSplit_full() {
165
166 final StubRegion region = new StubRegion(Collections.emptyList());
167
168 final TestLine splitter = TestLine.X_AXIS;
169
170
171 final Split<StubRegion> split = region.split(splitter);
172
173
174 Assert.assertEquals(SplitLocation.BOTH, split.getLocation());
175
176 final StubRegion minus = split.getMinus();
177 Assert.assertEquals(1, minus.getBoundaries().size());
178 checkClassify(minus, RegionLocation.INSIDE, new TestPoint2D(0, 1));
179 checkClassify(minus, RegionLocation.BOUNDARY, new TestPoint2D(0, 0));
180 checkClassify(minus, RegionLocation.OUTSIDE, new TestPoint2D(0, -1));
181
182 final StubRegion plus = split.getPlus();
183 Assert.assertEquals(1, plus.getBoundaries().size());
184 checkClassify(plus, RegionLocation.OUTSIDE, new TestPoint2D(0, 1));
185 checkClassify(plus, RegionLocation.BOUNDARY, new TestPoint2D(0, 0));
186 checkClassify(plus, RegionLocation.INSIDE, new TestPoint2D(0, -1));
187 }
188
189 @Test
190 public void testSplit_parallel_splitterIsOutside_plusOnly() {
191
192 final StubRegion region = new StubRegion(
193 Collections.singletonList(new TestLineSegment(new TestPoint2D(0, 1), new TestPoint2D(1, 1))));
194
195 final TestLine splitter = TestLine.X_AXIS.reverse();
196
197
198 final Split<StubRegion> split = region.split(splitter);
199
200
201 Assert.assertEquals(SplitLocation.PLUS, split.getLocation());
202
203 Assert.assertNull(split.getMinus());
204 Assert.assertSame(region, split.getPlus());
205 }
206
207 @Test
208 public void testSplit_parallel_splitterIsOutside_minusOnly() {
209
210 final StubRegion region = new StubRegion(
211 Collections.singletonList(new TestLineSegment(new TestPoint2D(0, 1), new TestPoint2D(1, 1))));
212
213 final TestLine splitter = TestLine.X_AXIS;
214
215
216 final Split<StubRegion> split = region.split(splitter);
217
218
219 Assert.assertEquals(SplitLocation.MINUS, split.getLocation());
220
221 Assert.assertSame(region, split.getMinus());
222 Assert.assertNull(split.getPlus());
223 }
224
225 @Test
226 public void testSplit_parallel_splitterIsInside() {
227
228 final StubRegion region = new StubRegion(
229 Collections.singletonList(new TestLineSegment(new TestPoint2D(1, 1), new TestPoint2D(0, 1))));
230
231 final TestLine splitter = TestLine.X_AXIS;
232
233
234 final Split<StubRegion> split = region.split(splitter);
235
236
237 Assert.assertEquals(SplitLocation.BOTH, split.getLocation());
238
239 final TestPoint2D p1 = new TestPoint2D(0, 1.5);
240 final TestPoint2D p2 = new TestPoint2D(0, 0.5);
241 final TestPoint2D p3 = new TestPoint2D(0, -0.5);
242
243 final StubRegion minus = split.getMinus();
244 Assert.assertEquals(2, minus.getBoundaries().size());
245 checkClassify(minus, RegionLocation.INSIDE, p2);
246 checkClassify(minus, RegionLocation.OUTSIDE, p1, p3);
247
248 final StubRegion plus = split.getPlus();
249 Assert.assertEquals(1, plus.getBoundaries().size());
250 checkClassify(plus, RegionLocation.INSIDE, p3);
251 checkClassify(plus, RegionLocation.OUTSIDE, p1, p2);
252 }
253
254 @Test
255 public void testSplit_coincident_sameOrientation() {
256
257 final StubRegion region = new StubRegion(Collections.singletonList(TestLine.X_AXIS.span()));
258
259 final TestLine splitter = TestLine.X_AXIS;
260
261
262 final Split<StubRegion> split = region.split(splitter);
263
264
265 Assert.assertEquals(SplitLocation.MINUS, split.getLocation());
266
267 Assert.assertSame(region, split.getMinus());
268 Assert.assertNull(split.getPlus());
269 }
270
271 @Test
272 public void testSplit_coincident_oppositeOrientation() {
273
274 final StubRegion region = new StubRegion(Collections.singletonList(TestLine.X_AXIS.span()));
275
276 final TestLine splitter = TestLine.X_AXIS.reverse();
277
278
279 final Split<StubRegion> split = region.split(splitter);
280
281
282 Assert.assertEquals(SplitLocation.PLUS, split.getLocation());
283
284 Assert.assertNull(split.getMinus());
285 Assert.assertSame(region, split.getPlus());
286 }
287
288 @Test
289 public void testSplit_finite_both() {
290
291 final TestPoint2D p1 = new TestPoint2D(1, -0.5);
292 final TestPoint2D p2 = new TestPoint2D(2, -0.5);
293 final TestPoint2D p3 = new TestPoint2D(2, 0.5);
294 final TestPoint2D p4 = new TestPoint2D(1, 0.5);
295
296 final StubRegion region = new StubRegion(Arrays.asList(
297 new TestLineSegment(p1, p2),
298 new TestLineSegment(p2, p3),
299 new TestLineSegment(p3, p4),
300 new TestLineSegment(p4, p1)
301 ));
302
303 final TestLine splitter = TestLine.X_AXIS;
304
305
306 final Split<StubRegion> split = region.split(splitter);
307
308
309 Assert.assertEquals(SplitLocation.BOTH, split.getLocation());
310
311 final StubRegion minus = split.getMinus();
312 Assert.assertEquals(4, minus.getBoundaries().size());
313 checkClassify(minus, RegionLocation.INSIDE, new TestPoint2D(1.5, 0.25));
314 checkClassify(minus, RegionLocation.BOUNDARY, new TestPoint2D(1.5, 0));
315 checkClassify(minus, RegionLocation.OUTSIDE, new TestPoint2D(1.5, -0.25));
316
317 final StubRegion plus = split.getPlus();
318 Assert.assertEquals(4, plus.getBoundaries().size());
319 checkClassify(plus, RegionLocation.OUTSIDE, new TestPoint2D(1.5, 0.25));
320 checkClassify(plus, RegionLocation.BOUNDARY, new TestPoint2D(1.5, 0));
321 checkClassify(plus, RegionLocation.INSIDE, new TestPoint2D(1.5, -0.25));
322 }
323
324
325
326
327
328
329
330
331 @Test
332 public void testSplit_inconsistentBoundarySplitLocations_minus() {
333
334 final TestLine a = new TestLine(new TestPoint2D(0, 0), new TestPoint2D(1, 1));
335 final TestLine b = new TestLine(new TestPoint2D(-1, 1), new TestPoint2D(0, 0));
336
337 final StubRegion region = new StubRegion(Arrays.asList(
338 new TestLineSegment(-1e-8, Double.POSITIVE_INFINITY, a),
339 new TestLineSegment(Double.NEGATIVE_INFINITY, 1e-8, b)
340 ));
341
342 final List<TestLineSegment> segments = region.getBoundaries();
343 PartitionTestUtils.assertPointsEqual(segments.get(0).getStartPoint(), segments.get(1).getEndPoint());
344
345 final TestLine splitter = new TestLine(new TestPoint2D(0, 0), new TestPoint2D(1, 0));
346
347
348 final Split<StubRegion> split = region.split(splitter);
349
350
351 Assert.assertEquals(SplitLocation.MINUS, split.getLocation());
352 Assert.assertSame(region, split.getMinus());
353 Assert.assertNull(split.getPlus());
354 }
355
356 @Test
357 public void testSplit_inconsistentBoundarySplitLocations_plus() {
358
359 final TestLine a = new TestLine(new TestPoint2D(0, 0), new TestPoint2D(1, 1));
360 final TestLine b = new TestLine(new TestPoint2D(-1, 1), new TestPoint2D(0, 0));
361
362 final StubRegion region = new StubRegion(Arrays.asList(
363 new TestLineSegment(-1e-8, Double.POSITIVE_INFINITY, a),
364 new TestLineSegment(Double.NEGATIVE_INFINITY, 1e-8, b)
365 ));
366
367 final List<TestLineSegment> segments = region.getBoundaries();
368 PartitionTestUtils.assertPointsEqual(segments.get(0).getStartPoint(), segments.get(1).getEndPoint());
369
370 final TestLine splitter = new TestLine(new TestPoint2D(1, 0), new TestPoint2D(0, 0));
371
372
373 final Split<StubRegion> split = region.split(splitter);
374
375
376 Assert.assertEquals(SplitLocation.PLUS, split.getLocation());
377 Assert.assertNull(split.getMinus());
378 Assert.assertSame(region, split.getPlus());
379 }
380
381 @Test
382 public void testSplit_inconsistentBoundarySplitLocations_trimmedNotNull_minus() {
383
384 final TestLine a = new TestLine(new TestPoint2D(1e-8, 0), new TestPoint2D(1, 1));
385 final TestLine b = new TestLine(new TestPoint2D(-1, 1), new TestPoint2D(-1e-8, 0));
386
387 final StubRegion region = new StubRegion(Arrays.asList(
388 new TestLineSegment(1e-8, Double.POSITIVE_INFINITY, a),
389 new TestLineSegment(Double.NEGATIVE_INFINITY, -1e-8, b)
390 ));
391
392 final List<TestLineSegment> segments = region.getBoundaries();
393 PartitionTestUtils.assertPointsEqual(segments.get(0).getStartPoint(), segments.get(1).getEndPoint());
394
395 final TestLine splitter = new TestLine(new TestPoint2D(0, 0), new TestPoint2D(1, 0));
396
397
398 final Split<StubRegion> split = region.split(splitter);
399
400
401 Assert.assertEquals(SplitLocation.MINUS, split.getLocation());
402 Assert.assertSame(region, split.getMinus());
403 Assert.assertNull(split.getPlus());
404 }
405
406 @Test
407 public void testSplit_inconsistentBoundarySplitLocations_trimmedNotNull_plus() {
408
409 final TestLine a = new TestLine(new TestPoint2D(1e-8, 0), new TestPoint2D(1, 1));
410 final TestLine b = new TestLine(new TestPoint2D(-1, 1), new TestPoint2D(-1e-8, 0));
411
412 final StubRegion region = new StubRegion(Arrays.asList(
413 new TestLineSegment(1e-8, Double.POSITIVE_INFINITY, a),
414 new TestLineSegment(Double.NEGATIVE_INFINITY, -1e-8, b)
415 ));
416
417 final List<TestLineSegment> segments = region.getBoundaries();
418 PartitionTestUtils.assertPointsEqual(segments.get(0).getStartPoint(), segments.get(1).getEndPoint());
419
420 final TestLine splitter = new TestLine(new TestPoint2D(0, 0), new TestPoint2D(-1, 0));
421
422
423 final Split<StubRegion> split = region.split(splitter);
424
425
426 Assert.assertEquals(SplitLocation.PLUS, split.getLocation());
427 Assert.assertNull(split.getMinus());
428 Assert.assertSame(region, split.getPlus());
429 }
430
431 @Test
432 public void testSplit_inconsistentBoundarySplitLocations_trimmedNotNull_neither() {
433
434 final TestLine a = new TestLine(new TestPoint2D(1e-8, 0), new TestPoint2D(1, 1));
435 final TestLine b = new TestLine(new TestPoint2D(-1, 1), new TestPoint2D(-1e-8, 0));
436
437 final StubRegion region = new StubRegion(Arrays.asList(
438 new TestLineSegment(0, 0, a),
439 new TestLineSegment(0, 0, b)
440 ));
441
442 final List<TestLineSegment> segments = region.getBoundaries();
443 PartitionTestUtils.assertPointsEqual(segments.get(0).getStartPoint(), segments.get(1).getEndPoint());
444
445 final TestLine splitter = new TestLine(new TestPoint2D(0, 0), new TestPoint2D(1, 0));
446
447
448 final Split<StubRegion> split = region.split(splitter);
449
450
451 Assert.assertEquals(SplitLocation.NEITHER, split.getLocation());
452 Assert.assertNull(split.getMinus());
453 Assert.assertNull(split.getPlus());
454 }
455
456 @Test
457 public void testTransform_full() {
458
459 final StubRegion region = new StubRegion(Collections.emptyList());
460
461 final Transform<TestPoint2D> transform = new TestTransform2D(p -> new TestPoint2D(p.getX() + 1, p.getY() + 2));
462
463
464 final StubRegion transformed = region.transform(transform);
465
466
467 Assert.assertTrue(transformed.isFull());
468 Assert.assertFalse(transformed.isEmpty());
469 }
470
471 @Test
472 public void testTransform_infinite() {
473
474 final TestLine line = TestLine.Y_AXIS;
475
476 final StubRegion region = new StubRegion(Collections.singletonList(line.span()));
477
478 final Transform<TestPoint2D> transform = new TestTransform2D(p -> new TestPoint2D(p.getX() + 1, p.getY() + 2));
479
480
481 final StubRegion transformed = region.transform(transform);
482
483
484 final List<TestLineSegment> boundaries = transformed.getBoundaries();
485
486 Assert.assertEquals(1, boundaries.size());
487
488 final TestLineSegment a = boundaries.get(0);
489 final TestLine aLine = a.getHyperplane();
490 PartitionTestUtils.assertPointsEqual(aLine.getOrigin(), new TestPoint2D(1, 0));
491 Assert.assertEquals(0.0, aLine.getDirectionX(), PartitionTestUtils.EPS);
492 Assert.assertEquals(1.0, aLine.getDirectionY(), PartitionTestUtils.EPS);
493
494 GeometryTestUtils.assertNegativeInfinity(a.getStart());
495 GeometryTestUtils.assertPositiveInfinity(a.getEnd());
496 }
497
498 @Test
499 public void testTransform_finite() {
500
501 final TestPoint2D p1 = new TestPoint2D(1, 0);
502 final TestPoint2D p2 = new TestPoint2D(2, 0);
503 final TestPoint2D p3 = new TestPoint2D(1, 1);
504
505 final StubRegion region = new StubRegion(Arrays.asList(
506 new TestLineSegment(p1, p2),
507 new TestLineSegment(p2, p3),
508 new TestLineSegment(p3, p1)
509 ));
510
511 final Transform<TestPoint2D> transform = new TestTransform2D(p -> new TestPoint2D(p.getX() + 1, p.getY() + 2));
512
513
514 final StubRegion transformed = region.transform(transform);
515
516
517 final List<TestLineSegment> boundaries = transformed.getBoundaries();
518
519 Assert.assertEquals(3, boundaries.size());
520
521 final TestLineSegment a = boundaries.get(0);
522 PartitionTestUtils.assertPointsEqual(new TestPoint2D(2, 2), a.getStartPoint());
523 PartitionTestUtils.assertPointsEqual(new TestPoint2D(3, 2), a.getEndPoint());
524
525 final TestLineSegment b = boundaries.get(1);
526 PartitionTestUtils.assertPointsEqual(new TestPoint2D(3, 2), b.getStartPoint());
527 PartitionTestUtils.assertPointsEqual(new TestPoint2D(2, 3), b.getEndPoint());
528
529 final TestLineSegment c = boundaries.get(2);
530 PartitionTestUtils.assertPointsEqual(new TestPoint2D(2, 3), c.getStartPoint());
531 PartitionTestUtils.assertPointsEqual(new TestPoint2D(2, 2), c.getEndPoint());
532 }
533
534 @Test
535 public void testTransform_reflection() {
536
537 final TestPoint2D p1 = new TestPoint2D(1, 0);
538 final TestPoint2D p2 = new TestPoint2D(2, 0);
539 final TestPoint2D p3 = new TestPoint2D(1, 1);
540
541 final StubRegion region = new StubRegion(Arrays.asList(
542 new TestLineSegment(p1, p2),
543 new TestLineSegment(p2, p3),
544 new TestLineSegment(p3, p1)
545 ));
546
547 final Transform<TestPoint2D> transform = new TestTransform2D(p -> new TestPoint2D(-p.getX(), p.getY()));
548
549
550 final StubRegion transformed = region.transform(transform);
551
552
553 final List<TestLineSegment> boundaries = transformed.getBoundaries();
554
555 Assert.assertEquals(3, boundaries.size());
556
557 final TestLineSegment a = boundaries.get(0);
558 PartitionTestUtils.assertPointsEqual(new TestPoint2D(-2, 0), a.getStartPoint());
559 PartitionTestUtils.assertPointsEqual(new TestPoint2D(-1, 0), a.getEndPoint());
560
561 final TestLineSegment b = boundaries.get(1);
562 PartitionTestUtils.assertPointsEqual(new TestPoint2D(-1, 1), b.getStartPoint());
563 PartitionTestUtils.assertPointsEqual(new TestPoint2D(-2, 0), b.getEndPoint());
564
565 final TestLineSegment c = boundaries.get(2);
566 PartitionTestUtils.assertPointsEqual(new TestPoint2D(-1, 0), c.getStartPoint());
567 PartitionTestUtils.assertPointsEqual(new TestPoint2D(-1, 1), c.getEndPoint());
568 }
569
570 @Test
571 public void testConvexRegionBoundaryBuilder_full() {
572
573 final StubRegion region = StubRegion.fromBounds(Collections.emptyList());
574
575
576 Assert.assertSame(StubRegion.FULL, region);
577 }
578
579 @Test
580 public void testConvexRegionBoundaryBuilder_singleLine() {
581
582 final StubRegion region = StubRegion.fromBounds(Collections.singletonList(TestLine.Y_AXIS));
583
584
585 Assert.assertEquals(1, region.getBoundaries().size());
586
587 checkClassify(region, RegionLocation.INSIDE, new TestPoint2D(-1, 0));
588 checkClassify(region, RegionLocation.BOUNDARY, new TestPoint2D(0, 0));
589 checkClassify(region, RegionLocation.OUTSIDE, new TestPoint2D(1, 0));
590 }
591
592 @Test
593 public void testConvexRegionBoundaryBuilder_multipleLines() {
594
595 final StubRegion region = StubRegion.fromBounds(Arrays.asList(
596 TestLine.X_AXIS,
597 new TestLine(new TestPoint2D(1, 0), new TestPoint2D(0, 1)),
598 TestLine.Y_AXIS.reverse()
599 ));
600
601
602 Assert.assertEquals(3, region.getBoundaries().size());
603
604 checkClassify(region, RegionLocation.INSIDE, new TestPoint2D(0.25, 0.25));
605
606 checkClassify(region, RegionLocation.BOUNDARY,
607 TestPoint2D.ZERO, new TestPoint2D(1, 0), new TestPoint2D(1, 0), new TestPoint2D(0.5, 0.5));
608
609 checkClassify(region, RegionLocation.OUTSIDE,
610 new TestPoint2D(-1, 0.5), new TestPoint2D(1, 0.5),
611 new TestPoint2D(0.5, 1), new TestPoint2D(0.5, -1));
612 }
613
614 @Test
615 public void testConvexRegionBoundaryBuilder_duplicateLines() {
616
617 final StubRegion region = StubRegion.fromBounds(Arrays.asList(
618 TestLine.Y_AXIS,
619 TestLine.Y_AXIS,
620 new TestLine(new TestPoint2D(0, 0), new TestPoint2D(0, 1)),
621 TestLine.Y_AXIS));
622
623
624 Assert.assertEquals(1, region.getBoundaries().size());
625
626 checkClassify(region, RegionLocation.INSIDE, new TestPoint2D(-1, 0));
627 checkClassify(region, RegionLocation.BOUNDARY, new TestPoint2D(0, 0));
628 checkClassify(region, RegionLocation.OUTSIDE, new TestPoint2D(1, 0));
629 }
630
631 @Test
632 public void testConvexRegionBoundaryBuilder() {
633
634 GeometryTestUtils.assertThrows(() -> {
635 StubRegion.fromBounds(Arrays.asList(TestLine.X_AXIS, TestLine.X_AXIS.reverse()));
636 }, IllegalArgumentException.class);
637
638 GeometryTestUtils.assertThrows(() -> {
639 StubRegion.fromBounds(Arrays.asList(
640 TestLine.X_AXIS,
641 TestLine.Y_AXIS,
642 new TestLine(new TestPoint2D(1, 0), new TestPoint2D(0, -1)),
643 new TestLine(new TestPoint2D(1, 0), new TestPoint2D(0, -2))));
644 }, IllegalArgumentException.class);
645 }
646
647 @Test
648 public void testToString() {
649
650 final StubRegion region = new StubRegion(Collections.emptyList());
651
652
653 final String str = region.toString();
654
655
656 Assert.assertTrue(str.contains("StubRegion"));
657 Assert.assertTrue(str.contains("boundaries= "));
658 }
659
660 private static void checkClassify(final Region<TestPoint2D> region, final RegionLocation loc, final TestPoint2D... pts) {
661 for (final TestPoint2D pt : pts) {
662 Assert.assertEquals("Unexpected location for point " + pt, loc, region.classify(pt));
663 }
664 }
665
666 private static final class StubRegion extends AbstractConvexHyperplaneBoundedRegion<TestPoint2D, TestLineSegment> {
667
668 private static final StubRegion FULL = new StubRegion(Collections.emptyList());
669
670 StubRegion(final List<TestLineSegment> boundaries) {
671 super(boundaries);
672 }
673
674 public StubRegion transform(final Transform<TestPoint2D> transform) {
675 return transformInternal(transform, this, TestLineSegment.class, StubRegion::new);
676 }
677
678 @Override
679 public Split<StubRegion> split(final Hyperplane<TestPoint2D> splitter) {
680 return splitInternal(splitter, this, TestLineSegment.class, StubRegion::new);
681 }
682
683 @Override
684 public TestLineSegment trim(final HyperplaneConvexSubset<TestPoint2D> subset) {
685 return (TestLineSegment) super.trim(subset);
686 }
687
688 @Override
689 public double getSize() {
690 throw new UnsupportedOperationException();
691 }
692
693 @Override
694 public TestPoint2D getCentroid() {
695 throw new UnsupportedOperationException();
696 }
697
698 public static StubRegion fromBounds(final Iterable<TestLine> boundingLines) {
699 final List<TestLineSegment> segments = new ConvexRegionBoundaryBuilder<>(TestLineSegment.class)
700 .build(boundingLines);
701 return segments.isEmpty() ? FULL : new StubRegion(segments);
702 }
703 }
704 }