I ended up here after realizing a cylinder extruded from the cross-section of a quad sphere made with the Extra Objects addon does not have equal sides. I was dismayed. DISMAYED.
Here is a comparison of it to a normal circle (orange):
The ideal you are asking for appears to be possible. While I have no formal proof in favor or against, your samples have a lot going for them, and can be approximated with code.
Looking at add_mesh_round_cube.py
of the Extra Objects addon, one can see that its idea of a quad sphere is a specific parameterization of a more general mathematical formalism. Apparently not one designed to get equal edge lengths.
To find the math which would do the job, I studied your sample quad spheres for a bit. One thing I thought is noteworthy is that the ring segments on each of the 6 "sides" each appear to have their vertices within a plane, just as other quad spheres do. (There is a bit of inaccuracy in the samples, which I am not sure whether it is safe to ignore.) From there, we can construct the three axis-aligned circles as well as the twelve 45°-angled circle segments, using some known math to determine the angle between (1, 1, -1) and (1, 1, 1) as well as rotate vertices around an axis.
To get the positions of the remaining vertices, it is important to notice that the circle segments between the axis-aligned circle segments and the 45°-angled circle segments have a smaller radius than 1. This is because the plane in which they lie demonstrably does not intersect the center of the quad sphere. While there is nothing unusual about this (given other quad spheres), we need to know the exact radii to figure out the angle spanned by each circle segment. To do this we can use two opposing points p0
and p1
of two 45°-angled circle segments of one "side" of the quad sphere as well as the center point halfway in between pCenter
. This gives us a vector with the correct direction of the center of the circle segment's arc as w = pCenter - 0.5 * (p0 + p1)
. This can then be used to calculate the axis-aligned slant angle of the circle segment and determine a rotation axis rotAxis
perpendicular to the circle segment's plane. Then math:
circleSegmentDist = pCenter.dot(rotAxis)
circleSegmentRadius = sqrt(1.0 - circleSegmentDist * circleSegmentDist) # equal to sin(acos(abs(circleSegmentDist)))
arcAngle = 2 * w.angle(p0 - (pCenter - ringSegmentRadius * w.normalized()))
The rest is a loop which finds the vertices by rotating p0
around rotAxis
using angles between 0.0
and arcAngle
.
This gives us this result (which matches your samples quite well):
However, by rotating a copy of the sphere around its center by 90°, we can show that there still is some error, revealing the math turns out slightly differently depending on whether we rotate vertices in x- or in y-direction within a "side":
I am not sure right now where the problem comes from. I suspect the assumption about the circle segment vertices lying within a plane might be wrong. I believe the error is too large to be caused by floating point arithmetic.
Either way, you can get it on Github: https://github.com/Zyl9393/even_quad_sphere