mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-29 18:09:50 +02:00
Added code documentation to _make_octa_sphere()
This commit is contained in:
@@ -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];
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user