View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.geometry.enclosing.euclidean.twod;
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.precision.DoublePrecisionContext;
25  import org.apache.commons.geometry.core.precision.EpsilonDoublePrecisionContext;
26  import org.apache.commons.geometry.enclosing.EnclosingBall;
27  import org.apache.commons.geometry.euclidean.twod.Vector2D;
28  import org.apache.commons.rng.UniformRandomProvider;
29  import org.apache.commons.rng.sampling.UnitSphereSampler;
30  import org.apache.commons.rng.simple.RandomSource;
31  import org.junit.Assert;
32  import org.junit.Test;
33  
34  public class DiskGeneratorTest {
35  
36      private static final double TEST_EPS = 1e-10;
37  
38      private final DiskGenerator generator = new DiskGenerator();
39  
40      @Test
41      public void testSupport0Point() {
42          // arrange
43          final List<Vector2D> support = Collections.emptyList();
44  
45          // act
46          final EnclosingBall<Vector2D> disk = generator.ballOnSupport(support);
47  
48          // assert
49          Assert.assertTrue(disk.getRadius() < 0);
50          Assert.assertEquals(0, disk.getSupportSize());
51          Assert.assertEquals(0, disk.getSupport().size());
52      }
53  
54      @Test
55      public void testSupport1Point() {
56          // arrange
57          final DoublePrecisionContext lowPrecision = new EpsilonDoublePrecisionContext(0.5);
58          final DoublePrecisionContext highPrecision = new EpsilonDoublePrecisionContext(0.001);
59          final List<Vector2D> support = Collections.singletonList(Vector2D.of(1, 2));
60  
61          // act
62          final EnclosingBall<Vector2D> disk = generator.ballOnSupport(support);
63  
64          // assert
65          Assert.assertEquals(0.0, disk.getRadius(), TEST_EPS);
66          Assert.assertTrue(disk.contains(support.get(0)));
67          Assert.assertTrue(disk.contains(support.get(0), lowPrecision));
68          Assert.assertFalse(disk.contains(Vector2D.of(support.get(0).getX() + 0.1,
69                                                        support.get(0).getY() - 0.1),
70                                          highPrecision));
71          Assert.assertTrue(disk.contains(Vector2D.of(support.get(0).getX() + 0.1,
72                                                       support.get(0).getY() - 0.1),
73                                          lowPrecision));
74          Assert.assertEquals(0, support.get(0).distance(disk.getCenter()), TEST_EPS);
75          Assert.assertEquals(1, disk.getSupportSize());
76          Assert.assertEquals(support.get(0), disk.getSupport().get(0));
77      }
78  
79      @Test
80      public void testSupport2Points() {
81          // arrange
82          final List<Vector2D> support = Arrays.asList(Vector2D.of(1, 0),
83                                                 Vector2D.of(3, 0));
84  
85          // act
86          final EnclosingBall<Vector2D> disk = generator.ballOnSupport(support);
87  
88          // assert
89          Assert.assertEquals(1.0, disk.getRadius(), TEST_EPS);
90  
91          int i = 0;
92          for (final Vector2D v : support) {
93              Assert.assertTrue(disk.contains(v));
94              Assert.assertEquals(1.0, v.distance(disk.getCenter()), TEST_EPS);
95              Assert.assertEquals(v, disk.getSupport().get(i++));
96          }
97  
98          Assert.assertTrue(disk.contains(Vector2D.of(2, 0.9)));
99          Assert.assertFalse(disk.contains(Vector2D.ZERO));
100         Assert.assertEquals(0.0, Vector2D.of(2, 0).distance(disk.getCenter()), TEST_EPS);
101         Assert.assertEquals(2, disk.getSupportSize());
102     }
103 
104     @Test
105     public void testSupport3Points() {
106         // arrange
107         final List<Vector2D> support = Arrays.asList(Vector2D.of(1, 0),
108                                                Vector2D.of(3, 0),
109                                                Vector2D.of(2, 2));
110 
111         // act
112         final EnclosingBall<Vector2D> disk = generator.ballOnSupport(support);
113 
114         // assert
115         Assert.assertEquals(5.0 / 4.0, disk.getRadius(), TEST_EPS);
116 
117         int i = 0;
118         for (final Vector2D v : support) {
119             Assert.assertTrue(disk.contains(v));
120             Assert.assertEquals(5.0 / 4.0, v.distance(disk.getCenter()), TEST_EPS);
121             Assert.assertEquals(v, disk.getSupport().get(i++));
122         }
123 
124         Assert.assertTrue(disk.contains(Vector2D.of(2, 0.9)));
125         Assert.assertFalse(disk.contains(Vector2D.of(0.9,  0)));
126         Assert.assertFalse(disk.contains(Vector2D.of(3.1,  0)));
127         Assert.assertTrue(disk.contains(Vector2D.of(2.0, -0.499)));
128         Assert.assertFalse(disk.contains(Vector2D.of(2.0, -0.501)));
129         Assert.assertEquals(0.0, Vector2D.of(2.0, 3.0 / 4.0).distance(disk.getCenter()), TEST_EPS);
130         Assert.assertEquals(3, disk.getSupportSize());
131     }
132 
133     @Test
134     public void testRandom() {
135         // arrange
136         final UniformRandomProvider random = RandomSource.create(RandomSource.WELL_1024_A,
137                                                                  0x12faa818373ffe90L);
138         final UnitSphereSampler sr = new UnitSphereSampler(2, random);
139         for (int i = 0; i < 500; ++i) {
140             final double d = 25 * random.nextDouble();
141             final double refRadius = 10 * random.nextDouble();
142             final Vector2D refCenter = Vector2D.linearCombination(d, Vector2D.of(sr.nextVector()));
143             final List<Vector2D> support = new ArrayList<>();
144             for (int j = 0; j < 3; ++j) {
145                 support.add(Vector2D.linearCombination(1.0, refCenter, refRadius, Vector2D.of(sr.nextVector())));
146             }
147 
148             // act
149             final EnclosingBall<Vector2D> disk = generator.ballOnSupport(support);
150 
151             // assert
152             Assert.assertEquals(0.0, refCenter.distance(disk.getCenter()), 3e-9 * refRadius);
153             Assert.assertEquals(refRadius, disk.getRadius(), 7e-10 * refRadius);
154         }
155     }
156 }