3434package eu .mihosoft .vrl .v3d ;
3535
3636import java .util .ArrayList ;
37+ import java .util .Arrays ;
38+ import java .util .HashMap ;
3739import java .util .List ;
40+ import java .util .Map ;
41+ import java .util .function .Function ;
42+
43+ import eu .mihosoft .vrl .v3d .ext .quickhull3d .HullUtil ;
3844
3945// Auto-generated Javadoc
4046/**
@@ -163,48 +169,48 @@ private void init() {
163169 private Vertex sphereVertex (Vector3d c , double r , double theta , double phi ) {
164170 theta *= Math .PI * 2 ;
165171 phi *= Math .PI ;
172+
173+ // Clamp poles to exact values to avoid sin(PI) floating point error
174+ if (phi <= 0 )
175+ return new Vertex (c .plus (new Vector3d (0 , r , 0 )));
176+ if (phi >= Math .PI )
177+ return new Vertex (c .plus (new Vector3d (0 , -r , 0 )));
178+
166179 Vector3d dir = new Vector3d (Math .cos (theta ) * Math .sin (phi ), Math .cos (phi ), Math .sin (theta ) * Math .sin (phi ));
167180 return new Vertex (c .plus (dir .times (r )));
168181 }
169182
170- /*
171- * (non-Javadoc)
172- *
173- * @see eu.mihosoft.vrl.v3d.Primitive#toPolygons()
174- */
175- @ Override
176183 public List <Polygon > toPolygons () {
177- if (radius <= 0 )
178- throw new NumberFormatException ("radius can not be negative" );
179- List <Polygon > polygons = new ArrayList <>();
180- for (int i = 0 ; i < numSlices ; i ++) {
181- for (int j = 0 ; j < numStacks ; j ++) {
182-
183- Vertex v0 = sphereVertex (center , radius , i / (double ) numSlices , j / (double ) numStacks );
184- Vertex v1 = sphereVertex (center , radius , (i + 1 ) / (double ) numSlices , j / (double ) numStacks );
185- Vertex v2 = sphereVertex (center , radius , (i + 1 ) / (double ) numSlices , (j + 1 ) / (double ) numStacks );
186- Vertex v3 = sphereVertex (center , radius , i / (double ) numSlices , (j + 1 ) / (double ) numStacks );
187-
188- if (j == 0 ) {
189- addPolygon (polygons , v0 , v3 , v2 );
190- } else if (j == numStacks - 1 ) {
191- addPolygon (polygons , v0 , v2 , v1 );
192- } else {
193- addPolygon (polygons , v0 , v3 , v1 );
194- addPolygon (polygons , v1 , v3 , v2 );
195- }
184+ List <Vector3d > points = new ArrayList <>();
185+
186+ // 1. Add the Poles explicitly (avoiding the loop to ensure they are clean)
187+ points .add (new Vector3d (center .x , center .y + radius , center .z )); // North
188+ points .add (new Vector3d (center .x , center .y - radius , center .z )); // South
189+
190+ // 2. Generate the rings (excluding the pole stacks)
191+ for (int j = 1 ; j < numStacks ; j ++) {
192+ double phi = Math .PI * j / numStacks ;
193+ double y = Math .cos (phi );
194+ double rRing = Math .sin (phi );
195+
196+ for (int i = 0 ; i < numSlices ; i ++) {
197+ double theta = 2.0 * Math .PI * i / numSlices ;
198+
199+ double x = Math .cos (theta ) * rRing ;
200+ double z = Math .sin (theta ) * rRing ;
201+
202+ // Micro-snapping to zero for stability
203+ if (Math .abs (x ) < 1e-12 )
204+ x = 0 ;
205+ if (Math .abs (z ) < 1e-12 )
206+ z = 0 ;
207+
208+ points .add (new Vector3d (center .x + x * radius , center .y + y * radius , center .z + z * radius ));
196209 }
197210 }
198- return polygons ;
211+ return HullUtil . hull ( points , getProperties ()). getPolygons () ;
199212 }
200213
201- private void addPolygon (List <Polygon > polygons , Vertex ... verts ) {
202- try {
203- polygons .add (new Polygon (List .of (verts ), getProperties ()));
204- } catch (ColinearPointsException e ) {
205- e .printStackTrace ();
206- }
207- }
208214
209215 /**
210216 * Gets the center.
@@ -262,8 +268,8 @@ public int getNumSlices() {
262268 * the numSlices to set
263269 */
264270 public Sphere setNumSlices (int numSlices ) {
265- if (numSlices > (NUM_SLICES * 4 ))
266- System .out .println ("Very large sphere! this may crash!" );
271+ // if (numSlices > (NUM_SLICES * 4))
272+ // System.out.println("Very large sphere! this may crash!");
267273 this .numSlices = numSlices ;
268274 return this ;
269275 }
@@ -284,8 +290,8 @@ public int getNumStacks() {
284290 * the numStacks to set
285291 */
286292 public Sphere setNumStacks (int numStacks ) {
287- if (numStacks > (NUM_STACKS * 4 ))
288- System .out .println ("Very large sphere! this may crash!" );
293+ // if (numStacks > (NUM_STACKS * 4))
294+ // System.out.println("Very large sphere! this may crash!");
289295 this .numStacks = numStacks ;
290296 return this ;
291297 }
0 commit comments