Added code documentation to _make_octa_sphere()

This commit is contained in:
Revar Desmera
2025-08-24 15:44:45 -07:00
parent f6c9916727
commit 96c7623f86

View File

@@ -3361,29 +3361,34 @@ function _dual_vertices(vnf) =
function _make_octa_sphere(r) = function _make_octa_sphere(r) =
let( let(
// Get number of triangles on each side of each octant.
subdivs = quantup(segs(r),4)/4, subdivs = quantup(segs(r),4)/4,
// Get octant edge vertices, on sphere surface, for all three octant edges.
edge1 = [for (p = [0:1:subdivs]) spherical_to_xyz(r,0,p/subdivs*90)], edge1 = [for (p = [0:1:subdivs]) spherical_to_xyz(r,0,p/subdivs*90)],
edge2 = zrot(90, p=edge1), edge2 = zrot(90, p=edge1),
edge3 = xrot(-90, p=edge1), edge3 = xrot(-90, p=edge1),
// Given two edges, calculate interior vertices by rotating along greater circles.
get_pts = function(e1, e2) [ get_pts = function(e1, e2) [
[ e1[0] ], [ e1[0] ], // shared vertex where edges meet.
for (p = [1:1:subdivs]) for (p = [1:1:subdivs])
let( let(
p1 = e1[p], p1 = e1[p], // for each matching pair of edge vertices...
p2 = e2[p], p2 = e2[p],
vec = vector_axis(p1, p2), vec = vector_axis(p1, p2), // get rotation axis...
ang = vector_angle(p1, p2) ang = vector_angle(p1, p2) // and angle between them, WRT the origin.
) [ ) [
for (t = [0:1:p]) for (t = [0:1:p]) // Subdivide this greater circle
let( let(
subang = lerp(0, ang, t/p), subang = lerp(0, ang, t/p),
pt = rot(a=subang, v=vec, p=p1) pt = rot(a=subang, v=vec, p=p1)
) pt ) pt
] ]
], ],
// Calculate all the triangular vertex arrays for all three edge pairings.
pts1 = get_pts(edge1, edge2), pts1 = get_pts(edge1, edge2),
pts2 = get_pts(reverse(edge3), reverse(edge1)), pts2 = get_pts(reverse(edge3), reverse(edge1)),
pts3 = get_pts(reverse(edge2), edge3), pts3 = get_pts(reverse(edge2), edge3),
// Rotate the calculated triangular arrays to match up.
rot_tri = function(tri) rot_tri = function(tri)
let( let(
ll = len(last(tri)) - 1 ll = len(last(tri)) - 1
@@ -3396,6 +3401,7 @@ function _make_octa_sphere(r) =
], ],
pts2b = rot_tri(rot_tri(pts2)), pts2b = rot_tri(rot_tri(pts2)),
pts3b = rot_tri(pts3), pts3b = rot_tri(pts3),
// Average the respecive vertices from each triangular array, and normalize them to the radius.
pts = [ pts = [
for (u = [0:1:subdivs]) [ for (u = [0:1:subdivs]) [
for (v = [0:1:u]) for (v = [0:1:u])
@@ -3403,21 +3409,25 @@ function _make_octa_sphere(r) =
p1 = pts1[u][v], p1 = pts1[u][v],
p2 = pts2b[u][v], p2 = pts2b[u][v],
p3 = pts3b[u][v], p3 = pts3b[u][v],
mean = (p1 + p2 + p3) / 3 mean = p1 + p2 + p3
) unit(mean) * r ) unit(mean) * r
] ]
], ],
// Calculate the triangulations of the averaged octant vertices.
octant_vnf = vnf_tri_array(pts), octant_vnf = vnf_tri_array(pts),
// Make 4 rotated copies of the octant to get the top of the sphere.
top_vnf = vnf_join([ top_vnf = vnf_join([
for (a=[0:90:359]) for (a=[0:90:359])
zrot(a, p=octant_vnf) zrot(a, p=octant_vnf)
]), ]),
// Copy the top, flipped on the Z axis to get the bottom, and put them together into one VNF.
bot_vnf = zflip(p=top_vnf), bot_vnf = zflip(p=top_vnf),
full_vnf = vnf_join([top_vnf, bot_vnf]) full_vnf = vnf_join([top_vnf, bot_vnf])
) full_vnf; ) full_vnf;
function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, orient=UP) = function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, orient=UP) =
assert(in_list(style, ["orig", "aligned", "stagger", "octa", "icosa"]))
let( let(
r = get_radius(r=r, d=d, dflt=1), r = get_radius(r=r, d=d, dflt=1),
hsides = segs(r), hsides = segs(r),
@@ -3547,7 +3557,7 @@ function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, or
] ]
) )
] ]
: /*style=="orig"?*/ : style=="orig"?
[ [
[for (i=[0:1:hsides-1]) hsides-i-1], [for (i=[0:1:hsides-1]) hsides-i-1],
[for (i=[0:1:hsides-1]) lv-hsides+i], [for (i=[0:1:hsides-1]) lv-hsides+i],
@@ -3556,6 +3566,7 @@ function spheroid(r, style="aligned", d, circum=false, anchor=CENTER, spin=0, or
[(i+1)*hsides+j, i*hsides+(j+1)%hsides, (i+1)*hsides+(j+1)%hsides], [(i+1)*hsides+j, i*hsides+(j+1)%hsides, (i+1)*hsides+(j+1)%hsides],
] ]
] ]
: assert(in_list(style,["orig","aligned","stagger","octa","icosa"]))
) [reorient(anchor,spin,orient, r=r, p=verts), faces]; ) [reorient(anchor,spin,orient, r=r, p=verts), faces];