mirror of
https://github.com/revarbat/BOSL2.git
synced 2025-08-29 07:50:51 +02:00
Removed VNF construction from octa spheroids.
This commit is contained in:
114
shapes3d.scad
114
shapes3d.scad
@@ -3370,14 +3370,20 @@ function _make_octa_sphere(r) =
|
|||||||
edge2 = zrot(90, p=edge1),
|
edge2 = zrot(90, p=edge1),
|
||||||
edge3 = xrot(-90, p=edge1),
|
edge3 = xrot(-90, p=edge1),
|
||||||
|
|
||||||
// Function to calculate greater arc point between two points
|
// Precache edge points, axes, and angles
|
||||||
greater_arc_point = function(p1, p2, u)
|
edge_pts1 = [for (i = [0:1:subdivs]) [edge1[i], edge2[i]]],
|
||||||
let(
|
edge_pts2 = [for (i = [0:1:subdivs]) [edge1[subdivs-i], edge3[subdivs-i]]],
|
||||||
vec = vector_axis(p1, p2),
|
edge_pts3 = [for (i = [0:1:subdivs]) [edge2[subdivs-i], edge3[i]]],
|
||||||
ang = vector_angle(p1, p2),
|
|
||||||
subang = lerp(0, ang, u),
|
// Precache greater circle axes
|
||||||
pt = rot(a=subang, v=vec, p=p1)
|
edge_axis1 = [UP, for (i = [1:1:subdivs]) vector_axis(edge_pts1[i][0], edge_pts1[i][1])],
|
||||||
) pt,
|
edge_axis2 = [UP, for (i = [1:1:subdivs]) vector_axis(edge_pts2[i][0], edge_pts2[i][1])],
|
||||||
|
edge_axis3 = [UP, for (i = [1:1:subdivs]) vector_axis(edge_pts3[i][0], edge_pts3[i][1])],
|
||||||
|
|
||||||
|
// Precache greater circle angles
|
||||||
|
edge_ang1 = [0, for (i = [1:1:subdivs]) vector_angle(edge_pts1[i][0], edge_pts1[i][1])],
|
||||||
|
edge_ang2 = [0, for (i = [1:1:subdivs]) vector_angle(edge_pts2[i][0], edge_pts2[i][1])],
|
||||||
|
edge_ang3 = [0, for (i = [1:1:subdivs]) vector_angle(edge_pts3[i][0], edge_pts3[i][1])],
|
||||||
|
|
||||||
// Calculate greater circle subdivisions between octant edges to get vertices.
|
// Calculate greater circle subdivisions between octant edges to get vertices.
|
||||||
pts = [
|
pts = [
|
||||||
@@ -3391,26 +3397,90 @@ function _make_octa_sphere(r) =
|
|||||||
edge3[subdivs-col] // Point on third edge is exact. (± FP rounding)
|
edge3[subdivs-col] // Point on third edge is exact. (± FP rounding)
|
||||||
else // Calculating interior point.
|
else // Calculating interior point.
|
||||||
let(
|
let(
|
||||||
p1 = greater_arc_point(edge1[row], edge2[row], col/row),
|
i1 = row,
|
||||||
p2 = greater_arc_point(edge1[row-col], edge3[row-col], col/(subdivs-row+col)),
|
i2 = subdivs - row + col,
|
||||||
p3 = greater_arc_point(edge2[col], edge3[subdivs-col], (row-col)/(subdivs-col))
|
i3 = subdivs - col,
|
||||||
|
u1 = col / i1,
|
||||||
|
u2 = col / i2,
|
||||||
|
u3 = (row - col) / i3,
|
||||||
|
p1 = rot(a=lerp(0, edge_ang1[i1], u1), v=edge_axis1[i1], p=edge_pts1[i1][0]),
|
||||||
|
p2 = rot(a=lerp(0, edge_ang2[i2], u2), v=edge_axis2[i2], p=edge_pts2[i2][0]),
|
||||||
|
p3 = rot(a=lerp(0, edge_ang3[i3], u3), v=edge_axis3[i3], p=edge_pts3[i3][0])
|
||||||
) unit(p1 + p2 + p3) * r // Average greater circle points beween the three edge pairs.
|
) unit(p1 + p2 + p3) * r // Average greater circle points beween the three edge pairs.
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
|
||||||
// Calculate the triangulations of the averaged octant vertices.
|
rows = [
|
||||||
octant_vnf = vnf_tri_array(pts),
|
[ pts[0][0] ],
|
||||||
|
|
||||||
// Make 4 rotated copies of the octant to get the top of the sphere.
|
for (row = [1:1:subdivs]) [
|
||||||
top_vnf = vnf_join([
|
for (a = [0:90:359])
|
||||||
for (a=[0:90:359])
|
each zrot(a, p=select(pts[row], [0:1:row-1]))
|
||||||
zrot(a, p=octant_vnf)
|
],
|
||||||
]),
|
|
||||||
|
|
||||||
// Copy the top, flipped on the Z axis to get the bottom, and put them together into one VNF.
|
for (row = [subdivs-1:-1:1]) [
|
||||||
bot_vnf = zflip(p=top_vnf),
|
for (a = [0:90:359])
|
||||||
full_vnf = vnf_join([top_vnf, bot_vnf])
|
each zrot(a, p=zflip(p=select(pts[row], [0:1:row-1])))
|
||||||
) full_vnf;
|
],
|
||||||
|
|
||||||
|
[ zflip(p=pts[0][0]) ]
|
||||||
|
],
|
||||||
|
verts = flatten(rows),
|
||||||
|
offsets = cumsum([0, for (row = rows) len(row)]),
|
||||||
|
faces = [
|
||||||
|
for (i = [0:1:3])
|
||||||
|
let(
|
||||||
|
l1 = len(rows[1]),
|
||||||
|
o1 = offsets[1]
|
||||||
|
)
|
||||||
|
[i+o1, 0, (i+1)%l1+o1],
|
||||||
|
|
||||||
|
for (j = [1:1:subdivs-1])
|
||||||
|
let(
|
||||||
|
l1 = len(rows[j]),
|
||||||
|
l2 = len(rows[j+1]),
|
||||||
|
o1 = offsets[j],
|
||||||
|
o2 = offsets[j+1],
|
||||||
|
q1 = len(rows[j])/4,
|
||||||
|
q2 = len(rows[j+1])/4
|
||||||
|
)
|
||||||
|
for (n = [0:1:3])
|
||||||
|
each [
|
||||||
|
[o2+q2*n, o1+q1*n, o2+(q2*n+1)%l2],
|
||||||
|
for (i = [0:1:q1-1]) each [
|
||||||
|
[o2+(i+q2*n+1)%l2, o1+(i+q1*n+1)%l1, o2+(i+q2*n+2)%l2],
|
||||||
|
[o2+(i+q2*n+1)%l2, o1+(i+q1*n)%l1, o1+(i+q1*n+1)%l1]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
for (j = [subdivs:1:2*subdivs-2])
|
||||||
|
let(
|
||||||
|
l1 = len(rows[j]),
|
||||||
|
l2 = len(rows[j+1]),
|
||||||
|
o1 = offsets[j],
|
||||||
|
o2 = offsets[j+1],
|
||||||
|
q1 = len(rows[j])/4,
|
||||||
|
q2 = len(rows[j+1])/4
|
||||||
|
)
|
||||||
|
for (n = [0:1:3])
|
||||||
|
each [
|
||||||
|
[o2+q2*n, o1+q1*n, o1+(q1*n+1)%l1],
|
||||||
|
for (i = [0:1:q1-2]) each [
|
||||||
|
[o2+(i+q2*n)%l2, o1+(i+q1*n+1)%l1, o2+(i+q2*n+1)%l2],
|
||||||
|
[o1+(i+q1*n+2)%l1, o2+(i+q2*n+1)%l2, o1+(i+q1*n+1)%l1]
|
||||||
|
]
|
||||||
|
],
|
||||||
|
|
||||||
|
for (i = [0:1:3])
|
||||||
|
let(
|
||||||
|
row = len(rows) -2,
|
||||||
|
l1 = len(rows[row]),
|
||||||
|
o1 = offsets[row],
|
||||||
|
o2 = offsets[row+1]
|
||||||
|
)
|
||||||
|
[o2, o1+i, o1+(i+1)%l1]
|
||||||
|
]
|
||||||
|
) [verts, faces];
|
||||||
|
|
||||||
|
|
||||||
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) =
|
||||||
|
Reference in New Issue
Block a user