1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.geometry.euclidean.threed;
23
24 import org.hipparchus.geometry.enclosing.EnclosingBall;
25 import org.hipparchus.random.RandomGenerator;
26 import org.hipparchus.random.UnitSphereRandomVectorGenerator;
27 import org.hipparchus.random.Well1024a;
28 import org.hipparchus.util.FastMath;
29 import org.junit.jupiter.api.Test;
30
31 import java.util.ArrayList;
32 import java.util.Arrays;
33 import java.util.List;
34
35 import static org.junit.jupiter.api.Assertions.assertEquals;
36 import static org.junit.jupiter.api.Assertions.assertFalse;
37 import static org.junit.jupiter.api.Assertions.assertTrue;
38
39
40 class SphereGeneratorTest {
41
42 @Test
43 void testSupport0Point() {
44 List<Vector3D> support = Arrays.asList(new Vector3D[0]);
45 EnclosingBall<Euclidean3D, Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
46 assertTrue(sphere.getRadius() < 0);
47 assertEquals(0, sphere.getSupportSize());
48 assertEquals(0, sphere.getSupport().length);
49 }
50
51 @Test
52 void testSupport1Point() {
53 List<Vector3D> support = Arrays.asList(new Vector3D(1, 2, 3));
54 EnclosingBall<Euclidean3D, Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
55 assertEquals(0.0, sphere.getRadius(), 1.0e-10);
56 assertTrue(sphere.contains(support.get(0)));
57 assertTrue(sphere.contains(support.get(0), 0.5));
58 assertFalse(sphere.contains(new Vector3D(support.get(0).getX() + 0.1,
59 support.get(0).getY() + 0.1,
60 support.get(0).getZ() + 0.1),
61 0.001));
62 assertTrue(sphere.contains(new Vector3D(support.get(0).getX() + 0.1,
63 support.get(0).getY() + 0.1,
64 support.get(0).getZ() + 0.1),
65 0.5));
66 assertEquals(0, support.get(0).distance(sphere.getCenter()), 1.0e-10);
67 assertEquals(1, sphere.getSupportSize());
68 assertTrue(support.get(0) == sphere.getSupport()[0]);
69 }
70
71 @Test
72 void testSupport2Points() {
73 List<Vector3D> support = Arrays.asList(new Vector3D(1, 0, 0),
74 new Vector3D(3, 0, 0));
75 EnclosingBall<Euclidean3D, Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
76 assertEquals(1.0, sphere.getRadius(), 1.0e-10);
77 int i = 0;
78 for (Vector3D v : support) {
79 assertTrue(sphere.contains(v));
80 assertEquals(1.0, v.distance(sphere.getCenter()), 1.0e-10);
81 assertTrue(v == sphere.getSupport()[i++]);
82 }
83 assertTrue(sphere.contains(new Vector3D(2, 0.9, 0)));
84 assertFalse(sphere.contains(Vector3D.ZERO));
85 assertEquals(0.0, new Vector3D(2, 0, 0).distance(sphere.getCenter()), 1.0e-10);
86 assertEquals(2, sphere.getSupportSize());
87 }
88
89 @Test
90 void testSupport3Points() {
91 List<Vector3D> support = Arrays.asList(new Vector3D(1, 0, 0),
92 new Vector3D(3, 0, 0),
93 new Vector3D(2, 2, 0));
94 EnclosingBall<Euclidean3D, Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
95 assertEquals(5.0 / 4.0, sphere.getRadius(), 1.0e-10);
96 int i = 0;
97 for (Vector3D v : support) {
98 assertTrue(sphere.contains(v));
99 assertEquals(5.0 / 4.0, v.distance(sphere.getCenter()), 1.0e-10);
100 assertTrue(v == sphere.getSupport()[i++]);
101 }
102 assertTrue(sphere.contains(new Vector3D(2, 0.9, 0)));
103 assertFalse(sphere.contains(new Vector3D(0.9, 0, 0)));
104 assertFalse(sphere.contains(new Vector3D(3.1, 0, 0)));
105 assertTrue(sphere.contains(new Vector3D(2.0, -0.499, 0)));
106 assertFalse(sphere.contains(new Vector3D(2.0, -0.501, 0)));
107 assertTrue(sphere.contains(new Vector3D(2.0, 3.0 / 4.0, -1.249)));
108 assertFalse(sphere.contains(new Vector3D(2.0, 3.0 / 4.0, -1.251)));
109 assertEquals(0.0, new Vector3D(2.0, 3.0 / 4.0, 0).distance(sphere.getCenter()), 1.0e-10);
110 assertEquals(3, sphere.getSupportSize());
111 }
112
113 @Test
114 void testSupport4Points() {
115 List<Vector3D> support = Arrays.asList(new Vector3D(17, 14, 18),
116 new Vector3D(11, 14, 22),
117 new Vector3D( 2, 22, 17),
118 new Vector3D(22, 11, -10));
119 EnclosingBall<Euclidean3D, Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
120 assertEquals(25.0, sphere.getRadius(), 1.0e-10);
121 int i = 0;
122 for (Vector3D v : support) {
123 assertTrue(sphere.contains(v));
124 assertEquals(25.0, v.distance(sphere.getCenter()), 1.0e-10);
125 assertTrue(v == sphere.getSupport()[i++]);
126 }
127 assertTrue(sphere.contains (new Vector3D(-22.999, 2, 2)));
128 assertFalse(sphere.contains(new Vector3D(-23.001, 2, 2)));
129 assertTrue(sphere.contains (new Vector3D( 26.999, 2, 2)));
130 assertFalse(sphere.contains(new Vector3D( 27.001, 2, 2)));
131 assertTrue(sphere.contains (new Vector3D(2, -22.999, 2)));
132 assertFalse(sphere.contains(new Vector3D(2, -23.001, 2)));
133 assertTrue(sphere.contains (new Vector3D(2, 26.999, 2)));
134 assertFalse(sphere.contains(new Vector3D(2, 27.001, 2)));
135 assertTrue(sphere.contains (new Vector3D(2, 2, -22.999)));
136 assertFalse(sphere.contains(new Vector3D(2, 2, -23.001)));
137 assertTrue(sphere.contains (new Vector3D(2, 2, 26.999)));
138 assertFalse(sphere.contains(new Vector3D(2, 2, 27.001)));
139 assertEquals(0.0, new Vector3D(2.0, 2.0, 2.0).distance(sphere.getCenter()), 1.0e-10);
140 assertEquals(4, sphere.getSupportSize());
141 }
142
143 @Test
144 void testRandom() {
145 final RandomGenerator random = new Well1024a(0xd015982e9f31ee04l);
146 final UnitSphereRandomVectorGenerator sr = new UnitSphereRandomVectorGenerator(3, random);
147 for (int i = 0; i < 100; ++i) {
148 double d = 25 * random.nextDouble();
149 double refRadius = 10 * random.nextDouble();
150 Vector3D refCenter = new Vector3D(d, new Vector3D(sr.nextVector()));
151 List<Vector3D> support = new ArrayList<Vector3D>();
152 for (int j = 0; j < 5; ++j) {
153 support.add(new Vector3D(1.0, refCenter, refRadius, new Vector3D(sr.nextVector())));
154 }
155 EnclosingBall<Euclidean3D, Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
156 assertEquals(0.0, refCenter.distance(sphere.getCenter()), 4e-7 * refRadius);
157 assertEquals(refRadius, sphere.getRadius(), 1e-7 * refRadius);
158 }
159
160 }
161
162 @Test
163 void testDegeneratedCase() {
164 final List<Vector3D> support =
165 Arrays.asList(new Vector3D(FastMath.scalb(-8039905610797991.0, -50),
166 FastMath.scalb(-4663475464714142.0, -48),
167 FastMath.scalb( 6592658872616184.0, -49)),
168 new Vector3D(FastMath.scalb(-8036658568968473.0, -50),
169 FastMath.scalb(-4664256346424880.0, -48),
170 FastMath.scalb( 6591357011730307.0, -49)),
171 new Vector3D(FastMath.scalb(-8037820142977230.0, -50),
172 FastMath.scalb(-4665280434237813.0, -48),
173 FastMath.scalb( 6592435966112099.0, -49)),
174 new Vector3D(FastMath.scalb(-8038007803611611.0, -50),
175 FastMath.scalb(-4664291215918380.0, -48),
176 FastMath.scalb( 6595270610894208.0, -49)));
177 EnclosingBall<Euclidean3D, Vector3D> sphere = new SphereGenerator().ballOnSupport(support);
178
179
180
181
182
183 assertEquals( -7.139325643360503322823511839511, sphere.getCenter().getX(), 1.0e-20);
184 assertEquals(-16.571096474251747245361467833760, sphere.getCenter().getY(), 1.0e-20);
185 assertEquals( 11.711945804096960876521111630800, sphere.getCenter().getZ(), 1.0e-20);
186 assertEquals( 0.003616820213530053297575846168, sphere.getRadius(), 2.0e-15);
187
188 for (Vector3D v : support) {
189 assertTrue(sphere.contains(v, 1.0e-14));
190 }
191
192 }
193
194 }