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 java.util.Arrays;
25 import java.util.List;
26
27 import org.hipparchus.fraction.BigFraction;
28 import org.hipparchus.geometry.enclosing.EnclosingBall;
29 import org.hipparchus.geometry.enclosing.SupportBallGenerator;
30 import org.hipparchus.geometry.euclidean.twod.DiskGenerator;
31 import org.hipparchus.geometry.euclidean.twod.Euclidean2D;
32 import org.hipparchus.geometry.euclidean.twod.Vector2D;
33 import org.hipparchus.util.FastMath;
34
35
36
37 public class SphereGenerator implements SupportBallGenerator<Euclidean3D, Vector3D> {
38
39
40
41
42
43
44
45
46 public SphereGenerator() {
47
48 }
49
50
51 @Override
52 public EnclosingBall<Euclidean3D, Vector3D> ballOnSupport(final List<Vector3D> support) {
53
54 if (support.isEmpty()) {
55 return new EnclosingBall<>(Vector3D.ZERO, Double.NEGATIVE_INFINITY);
56 } else {
57 final Vector3D vA = support.get(0);
58 if (support.size() < 2) {
59 return new EnclosingBall<>(vA, 0, vA);
60 } else {
61 final Vector3D vB = support.get(1);
62 if (support.size() < 3) {
63
64 final Vector3D center = new Vector3D(0.5, vA, 0.5, vB);
65
66
67
68
69
70
71
72
73 final double r = FastMath.max(Vector3D.distance(vA, center),
74 Vector3D.distance(vB, center));
75 return new EnclosingBall<>(center, r, vA, vB);
76
77 } else {
78 final Vector3D vC = support.get(2);
79 if (support.size() < 4) {
80
81
82 final Plane p = new Plane(vA, vB, vC,
83 1.0e-10 * (vA.getNorm1() + vB.getNorm1() + vC.getNorm1()));
84 final EnclosingBall<Euclidean2D, Vector2D> disk =
85 new DiskGenerator().ballOnSupport(Arrays.asList(p.toSubSpace(vA),
86 p.toSubSpace(vB),
87 p.toSubSpace(vC)));
88
89
90 final Vector3D center = p.toSpace(disk.getCenter());
91
92
93
94
95
96
97
98
99 final double r = FastMath.max(Vector3D.distance(vA, center),
100 FastMath.max(Vector3D.distance(vB, center),
101 Vector3D.distance(vC, center)));
102 return new EnclosingBall<>(center, r, vA, vB, vC);
103
104 } else {
105 final Vector3D vD = support.get(3);
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 final BigFraction[] c2 = {
130 new BigFraction(vA.getX()), new BigFraction(vB.getX()),
131 new BigFraction(vC.getX()), new BigFraction(vD.getX())
132 };
133 final BigFraction[] c3 = {
134 new BigFraction(vA.getY()), new BigFraction(vB.getY()),
135 new BigFraction(vC.getY()), new BigFraction(vD.getY())
136 };
137 final BigFraction[] c4 = {
138 new BigFraction(vA.getZ()), new BigFraction(vB.getZ()),
139 new BigFraction(vC.getZ()), new BigFraction(vD.getZ())
140 };
141 final BigFraction[] c1 = {
142 c2[0].multiply(c2[0]).add(c3[0].multiply(c3[0])).add(c4[0].multiply(c4[0])),
143 c2[1].multiply(c2[1]).add(c3[1].multiply(c3[1])).add(c4[1].multiply(c4[1])),
144 c2[2].multiply(c2[2]).add(c3[2].multiply(c3[2])).add(c4[2].multiply(c4[2])),
145 c2[3].multiply(c2[3]).add(c3[3].multiply(c3[3])).add(c4[3].multiply(c4[3]))
146 };
147 final BigFraction twoM11 = minor(c2, c3, c4).multiply(2);
148 final BigFraction m12 = minor(c1, c3, c4);
149 final BigFraction m13 = minor(c1, c2, c4);
150 final BigFraction m14 = minor(c1, c2, c3);
151 final Vector3D center = new Vector3D( m12.divide(twoM11).doubleValue(),
152 -m13.divide(twoM11).doubleValue(),
153 m14.divide(twoM11).doubleValue());
154
155
156
157
158
159
160
161
162 final double r = FastMath.max(Vector3D.distance(vA, center),
163 FastMath.max(Vector3D.distance(vB, center),
164 FastMath.max(Vector3D.distance(vC, center),
165 Vector3D.distance(vD, center))));
166 return new EnclosingBall<>(center, r, vA, vB, vC, vD);
167
168 }
169 }
170 }
171 }
172 }
173
174
175
176
177
178
179
180 private BigFraction minor(final BigFraction[] c1, final BigFraction[] c2, final BigFraction[] c3) {
181 return c2[0].multiply(c3[1]).multiply(c1[2].subtract(c1[3])).
182 add(c2[0].multiply(c3[2]).multiply(c1[3].subtract(c1[1]))).
183 add(c2[0].multiply(c3[3]).multiply(c1[1].subtract(c1[2]))).
184 add(c2[1].multiply(c3[0]).multiply(c1[3].subtract(c1[2]))).
185 add(c2[1].multiply(c3[2]).multiply(c1[0].subtract(c1[3]))).
186 add(c2[1].multiply(c3[3]).multiply(c1[2].subtract(c1[0]))).
187 add(c2[2].multiply(c3[0]).multiply(c1[1].subtract(c1[3]))).
188 add(c2[2].multiply(c3[1]).multiply(c1[3].subtract(c1[0]))).
189 add(c2[2].multiply(c3[3]).multiply(c1[0].subtract(c1[1]))).
190 add(c2[3].multiply(c3[0]).multiply(c1[2].subtract(c1[1]))).
191 add(c2[3].multiply(c3[1]).multiply(c1[0].subtract(c1[2]))).
192 add(c2[3].multiply(c3[2]).multiply(c1[1].subtract(c1[0])));
193 }
194
195 }