Refactored various bezier routines to use fast bezier point generation.

This commit is contained in:
Revar Desmera
2020-05-13 01:09:11 -07:00
parent 4cacebadef
commit a5fb810738
6 changed files with 252 additions and 267 deletions

View File

@@ -1,5 +1,4 @@
include <BOSL2/std.scad>
include <BOSL2/paths.scad>
include <BOSL2/beziers.scad>
@@ -28,24 +27,15 @@ function CR_corner(size, spin=0, orient=UP, trans=[0,0,0]) =
function CR_edge(size, spin=0, orient=UP, trans=[0,0,0]) =
let (
// This patch might not yet correct for continuous rounding,
// This patch might not be correct for continuous rounding,
// but it's a first approximation proof of concept.
a = 0.68,
c = 0.24,
m = -1/2,
n = -3/10,
o = -1/10,
p = 1/10,
q = 3/10,
r = 1/2,
patch = [
[[1,0,m], [1,0,n], [1,0,o], [1,0,p], [1,0,q], [1,0,r]],
[[a,0,m], [a,0,n], [a,0,o], [a,0,p], [a,0,q], [a,0,r]],
[[c,0,m], [c,0,n], [c,0,o], [c,0,p], [c,0,q], [c,0,r]],
[[0,c,m], [0,c,n], [0,c,o], [0,c,p], [0,c,q], [0,c,r]],
[[0,a,m], [0,a,n], [0,a,o], [0,a,p], [0,a,q], [0,a,r]],
[[0,1,m], [0,1,n], [0,1,o], [0,1,p], [0,1,q], [0,1,r]],
]
vvals = [1.00, 0.68, 0.24],
xyvals = [
for (x=vvals) [x,0],
for (y=reverse(vvals)) [0,y]
],
zvals = [-0.5:0.2:0.5],
patch = [for (xy=xyvals) [for (z=zvals) [each xy, z]]]
)
translate(trans,
p=rot(a=spin, from=UP, to=orient,
@@ -58,44 +48,23 @@ module CR_cube(size=[100,100,100], r=10, splinesteps=8, debug=false)
{
s = size-2*[r,r,r];
h = size/2;
corner_pat = CR_corner([r,r,r], trans=[-size.x/2, -size.y/2, -size.z/2]);
edge_pat = CR_edge([r, r, s.z], trans=[-h.x, -h.y, 0]);
face_pat = bezier_patch_flat([s.x, s.z], N=1, orient=FRONT, trans=[0, -h.y, 0]);
corners = bezier_surface([
CR_corner([r,r,r], spin=0, orient=UP, trans=[-size.x/2, -size.y/2, -size.z/2]),
CR_corner([r,r,r], spin=90, orient=UP, trans=[ size.x/2, -size.y/2, -size.z/2]),
CR_corner([r,r,r], spin=180, orient=UP, trans=[ size.x/2, size.y/2, -size.z/2]),
CR_corner([r,r,r], spin=270, orient=UP, trans=[-size.x/2, size.y/2, -size.z/2]),
CR_corner([r,r,r], spin=0, orient=DOWN, trans=[ size.x/2, -size.y/2, size.z/2]),
CR_corner([r,r,r], spin=90, orient=DOWN, trans=[-size.x/2, -size.y/2, size.z/2]),
CR_corner([r,r,r], spin=180, orient=DOWN, trans=[-size.x/2, size.y/2, size.z/2]),
CR_corner([r,r,r], spin=270, orient=DOWN, trans=[ size.x/2, size.y/2, size.z/2]),
for (yr=[0,180], zr=[0:90:270]) let(
m = yrot(yr) * zrot(zr)
) [for (row=corner_pat) apply(m, row)]
], splinesteps=splinesteps);
edges = bezier_surface([
CR_edge([r, r, s.x], spin=0, orient=RIGHT, trans=[ 0, -h.y, h.z]),
CR_edge([r, r, s.x], spin=90, orient=RIGHT, trans=[ 0, -h.y, -h.z]),
CR_edge([r, r, s.x], spin=180, orient=RIGHT, trans=[ 0, h.y, -h.z]),
CR_edge([r, r, s.x], spin=270, orient=RIGHT, trans=[ 0, h.y, h.z]),
CR_edge([r, r, s.y], spin=0, orient=BACK, trans=[-h.x, 0, h.z]),
CR_edge([r, r, s.y], spin=90, orient=BACK, trans=[ h.x, 0, h.z]),
CR_edge([r, r, s.y], spin=180, orient=BACK, trans=[ h.x, 0, -h.z]),
CR_edge([r, r, s.y], spin=270, orient=BACK, trans=[-h.x, 0, -h.z]),
CR_edge([r, r, s.z], spin=0, orient=UP, trans=[-h.x, -h.y, 0]),
CR_edge([r, r, s.z], spin=90, orient=UP, trans=[ h.x, -h.y, 0]),
CR_edge([r, r, s.z], spin=180, orient=UP, trans=[ h.x, h.y, 0]),
CR_edge([r, r, s.z], spin=270, orient=UP, trans=[-h.x, h.y, 0])
], splinesteps=[1,splinesteps]);
for (axr=[[0,0,0],[90,0,0],[0,90,0]],zr=[0:90:270]) let(
m = rot(axr) * zrot(zr)
) [for (row=edge_pat) apply(m, row)]
], splinesteps=[splinesteps,1]);
faces = bezier_surface([
// Yes, these are degree 1 bezier patches. That means just the four corner points.
// Since these are flat, it doesn't matter what degree they are, and this will reduce calculation overhead.
bezier_patch_flat([s.y, s.z], N=1, orient=RIGHT, trans=[ h.x, 0, 0]),
bezier_patch_flat([s.y, s.z], N=1, orient=LEFT, trans=[-h.x, 0, 0]),
bezier_patch_flat([s.x, s.z], N=1, orient=BACK, trans=[ 0, h.y, 0]),
bezier_patch_flat([s.x, s.z], N=1, orient=FRONT, trans=[ 0, -h.y, 0]),
bezier_patch_flat([s.x, s.y], N=1, orient=UP, trans=[ 0, 0, h.z]),
bezier_patch_flat([s.x, s.y], N=1, orient=DOWN, trans=[ 0, 0, -h.z])
for (axr=[0,90,180,270,[-90,0,0],[90,0,0]]) let(
m = rot(axr)
) [for (row=face_pat) apply(m, row)]
], splinesteps=1);
if (debug) {

View File

@@ -1,5 +1,4 @@
include <BOSL2/std.scad>
include <BOSL2/beziers.scad>
//$fa=2;
//$fs=2;

View File

@@ -1,5 +1,4 @@
include <BOSL2/std.scad>
include <BOSL2/beziers.scad>
//$fa=2;
//$fs=2;

View File

@@ -8,10 +8,10 @@ p = s * d;
q = s * 0.55 * d;
u = s * 2.5 * UP;
patch1 = [
[p[1], p[1]+q[0], p[0]+q[1], p[0] ],
[p[1]+q[2], p[1]+q[1]+u, p[0]+q[0]+u, p[0]+q[3]],
[p[2]+q[1], p[2]+q[2]+u, p[3]+q[3]+u, p[3]+q[0]],
[p[2], p[2]+q[3], p[3]+q[2], p[3] ],
[p[2]+q[1], p[2]+q[2]+u, p[3]+q[3]+u, p[3]+q[0]],
[p[1]+q[2], p[1]+q[1]+u, p[0]+q[0]+u, p[0]+q[3]],
[p[1], p[1]+q[0], p[0]+q[1], p[0] ],
];
patch2 = patch_reverse(zflip(p=patch1));
trace_bezier_patches([patch1, patch2], splinesteps=16, style="quincunx");