scad-common/subdivision.scad
2019-02-23 20:33:01 +01:00

73 lines
No EOL
1.8 KiB
OpenSCAD

module print_points(vector) {
color("red")
for(i = [0:1:len(vector)-1])
translate(vector[i]) {
sphere(1);
text(str(i),size=4);
}
}
function smooth_closed(path,it=0)=
it == 0 ?
path :
smooth_closed(subdivide_closed(path),it-1);
function smooth_open(path,it=0)=
it == 0 ?
path :
smooth_open(subdivide_open(path),it-1);
function subdivide_closed(path)=
let(n=len(path))
flatten(concat([for (i=[0:1:n-1])[ path[i],
interpolateClosed(path,n,i)
]]));
function subdivide_open(path) =
let(n = len(path))
flatten(concat([for (i = [0 : 1 : n-1])
i < n-1?
// Emit the current point and the one halfway between current and next.
[path[i], interpolateOpen(path, n, i)]
:
// We're at the end, so just emit the last point.
[path[i]]
]));
weight = [-1, 8, 8, -1] / 14;
weight0 = [6, 11, -1] / 16;
weight2 = [1, 1] / 2;
// Interpolate on an open-ended path, with discontinuity at start and end.
// Returns a point between points i and i+1, weighted.
function interpolateOpen(path, n, i) =
i == 0?
n == 2?
path[i] * weight2[0] +
path[i + 1] * weight2[1]
:
path[i] * weight0[0] +
path[i + 1] * weight0[1] +
path[i + 2] * weight0[2]
: i < n - 2?
path[i - 1] * weight[0] +
path[i] * weight[1] +
path[i + 1] * weight[2] +
path[i + 2] * weight[3]
: i < n - 1?
path[i - 1] * weight0[2] +
path[i] * weight0[1] +
path[i + 1] * weight0[0]
:
path[i];
function interpolateClosed(path, n, i) =
path[(i + n - 1) % n] * weight[0] +
path[i] * weight[1] +
path[(i + 1) % n] * weight[2] +
path[(i + 2) % n] * weight[3] ;
function flatten(list) = [ for (i = list, v = i) v ];