mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 08:19:43 +00:00
Added in range step of 1 to avoid errors.
This commit is contained in:
parent
44ed576e07
commit
f378b70151
23 changed files with 171 additions and 171 deletions
|
@ -14,7 +14,7 @@
|
|||
// Description: Create an `n` by `n` identity matrix.
|
||||
// Arguments:
|
||||
// n = The size of the identity matrix square, `n` by `n`.
|
||||
function ident(n) = [for (i = [0:n-1]) [for (j = [0:n-1]) (i==j)?1:0]];
|
||||
function ident(n) = [for (i = [0:1:n-1]) [for (j = [0:1:n-1]) (i==j)?1:0]];
|
||||
|
||||
|
||||
// Function: affine2d_to_affine3d()
|
||||
|
|
46
arrays.scad
46
arrays.scad
|
@ -34,9 +34,9 @@
|
|||
// replist(0, [2,2,3]); // Returns [[[0,0,0],[0,0,0]], [[0,0,0],[0,0,0]]]
|
||||
// replist([1,2,3],3); // Returns [[1,2,3], [1,2,3], [1,2,3]]
|
||||
function replist(val, n, i=0) =
|
||||
is_num(n)? [for(j=[1:n]) val] :
|
||||
is_num(n)? [for(j=[1:1:n]) val] :
|
||||
(i>=len(n))? val :
|
||||
[for (j=[1:n[i]]) replist(val, n, i+1)];
|
||||
[for (j=[1:1:n[i]]) replist(val, n, i+1)];
|
||||
|
||||
|
||||
// Function: in_list()
|
||||
|
@ -69,7 +69,7 @@ function in_list(x,l,idx=undef) = search([x], l, num_returns_per_match=1, index_
|
|||
function slice(arr,st,end) = let(
|
||||
s=st<0?(len(arr)+st):st,
|
||||
e=end<0?(len(arr)+end+1):end
|
||||
) (s==e)? [] : [for (i=[s:e-1]) if (e>s) arr[i]];
|
||||
) [for (i=[s:1:e-1]) if (e>s) arr[i]];
|
||||
|
||||
|
||||
// Function: select()
|
||||
|
@ -106,8 +106,8 @@ function select(list, start, end=undef) =
|
|||
) : (
|
||||
let(s=(start%l+l)%l, e=(end%l+l)%l)
|
||||
(s<=e)?
|
||||
[for (i = [s:e]) list[i]] :
|
||||
concat([for (i = [s:l-1]) list[i]], [for (i = [0:e]) list[i]])
|
||||
[for (i = [s:1:e]) list[i]] :
|
||||
concat([for (i = [s:1:l-1]) list[i]], [for (i = [0:1:e]) list[i]])
|
||||
);
|
||||
|
||||
|
||||
|
@ -136,8 +136,8 @@ function select(list, start, end=undef) =
|
|||
// list_range(s=4, e=8, step=2); // Returns [4,6,8]
|
||||
// list_range(n=4, s=[3,4], step=[2,3]); // Returns [[3,4], [5,7], [7,10], [9,13]]
|
||||
function list_range(n=undef, s=0, e=undef, step=1) =
|
||||
(n!=undef && e!=undef)? [for (i=[0:n-1]) let(v=s+step*i) if (v<=e) v] :
|
||||
(n!=undef)? [for (i=[0:n-1]) let(v=s+step*i) v] :
|
||||
(n!=undef && e!=undef)? [for (i=[0:1:n-1]) let(v=s+step*i) if (v<=e) v] :
|
||||
(n!=undef)? [for (i=[0:1:n-1]) let(v=s+step*i) v] :
|
||||
(e!=undef)? [for (v=[s:step:e]) v] :
|
||||
assert(e!=undef||n!=undef, "Must supply one of `n` or `e`.");
|
||||
|
||||
|
@ -160,7 +160,7 @@ function reverse(list) = [ for (i = [len(list)-1 : -1 : 0]) list[i] ];
|
|||
// list = The list to remove items from.
|
||||
// elements = The list of indexes of items to remove.
|
||||
function list_remove(list, elements) = [
|
||||
for (i = [0:len(list)-1]) if (!search(i, elements)) list[i]
|
||||
for (i = [0:1:len(list)-1]) if (!search(i, elements)) list[i]
|
||||
];
|
||||
|
||||
|
||||
|
@ -173,7 +173,7 @@ function list_insert(list, pos, elements) =
|
|||
concat(
|
||||
slice(list,0,pos),
|
||||
elements,
|
||||
(pos<len(list)? slide(list,pos,-1) : [])
|
||||
(pos<len(list)? slice(list,pos,-1) : [])
|
||||
);
|
||||
|
||||
|
||||
|
@ -203,7 +203,7 @@ function list_longest(vecs) =
|
|||
// minlen = The minimum length to pad the list to.
|
||||
// fill = The value to pad the list with.
|
||||
function list_pad(v, minlen, fill=undef) =
|
||||
let(l=len(v)) [for (i=[0:max(l,minlen)-1]) i<l? v[i] : fill];
|
||||
let(l=len(v)) [for (i=[0:1:max(l,minlen)-1]) i<l? v[i] : fill];
|
||||
|
||||
|
||||
// Function: list_trim()
|
||||
|
@ -213,7 +213,7 @@ function list_pad(v, minlen, fill=undef) =
|
|||
// v = A list.
|
||||
// minlen = The minimum length to pad the list to.
|
||||
function list_trim(v, maxlen) =
|
||||
maxlen<1? [] : [for (i=[0:min(len(v),maxlen)-1]) v[i]];
|
||||
maxlen<1? [] : [for (i=[0:1:min(len(v),maxlen)-1]) v[i]];
|
||||
|
||||
|
||||
// Function: list_fit()
|
||||
|
@ -242,8 +242,8 @@ function list_fit(v, length, fill) =
|
|||
function enumerate(l,idx=undef) =
|
||||
(l==[])? [] :
|
||||
(idx==undef)?
|
||||
[for (i=[0:len(l)-1]) [i,l[i]]] :
|
||||
[for (i=[0:len(l)-1]) concat([i], [for (j=idx) l[i][j]])];
|
||||
[for (i=[0:1:len(l)-1]) [i,l[i]]] :
|
||||
[for (i=[0:1:len(l)-1]) concat([i], [for (j=idx) l[i][j]])];
|
||||
|
||||
|
||||
// Function: sort()
|
||||
|
@ -268,9 +268,9 @@ function sort(arr, idx=undef) =
|
|||
cmp = compare_vals(val, pivotval)
|
||||
) cmp
|
||||
],
|
||||
lesser = [ for (i = [0:len(arr)-1]) if (compare[i] < 0) arr[i] ],
|
||||
equal = [ for (i = [0:len(arr)-1]) if (compare[i] ==0) arr[i] ],
|
||||
greater = [ for (i = [0:len(arr)-1]) if (compare[i] > 0) arr[i] ]
|
||||
lesser = [ for (i = [0:1:len(arr)-1]) if (compare[i] < 0) arr[i] ],
|
||||
equal = [ for (i = [0:1:len(arr)-1]) if (compare[i] ==0) arr[i] ],
|
||||
greater = [ for (i = [0:1:len(arr)-1]) if (compare[i] > 0) arr[i] ]
|
||||
)
|
||||
concat(sort(lesser,idx), equal, sort(greater,idx));
|
||||
|
||||
|
@ -316,7 +316,7 @@ function unique(arr) =
|
|||
len(arr)<=1? arr : let(
|
||||
sorted = sort(arr)
|
||||
) [
|
||||
for (i=[0:len(sorted)-1])
|
||||
for (i=[0:1:len(sorted)-1])
|
||||
if (i==0 || (sorted[i] != sorted[i-1]))
|
||||
sorted[i]
|
||||
];
|
||||
|
@ -353,7 +353,7 @@ function subindex(v, idx) = [
|
|||
// Example:
|
||||
// l = ["A","B","C",D"];
|
||||
// echo([for (p=pair(l)) str(p.y,p.x)]); // Outputs: ["BA", "CB", "DC"]
|
||||
function pair(v) = [for (i=[0:len(v)-2]) [v[i],v[i+1]]];
|
||||
function pair(v) = [for (i=[0:1:len(v)-2]) [v[i],v[i+1]]];
|
||||
|
||||
|
||||
// Function: pair_wrap()
|
||||
|
@ -364,7 +364,7 @@ function pair(v) = [for (i=[0:len(v)-2]) [v[i],v[i+1]]];
|
|||
// Example:
|
||||
// l = ["A","B","C",D"];
|
||||
// echo([for (p=pair_wrap(l)) str(p.y,p.x)]); // Outputs: ["BA", "CB", "DC", "AD"]
|
||||
function pair_wrap(v) = [for (i=[0:len(v)-1]) [v[i],v[(i+1)%len(v)]]];
|
||||
function pair_wrap(v) = [for (i=[0:1:len(v)-1]) [v[i],v[(i+1)%len(v)]]];
|
||||
|
||||
|
||||
// Function: zip()
|
||||
|
@ -402,8 +402,8 @@ function zip(vecs, v2, v3, fit=false, fill=undef) =
|
|||
maxlen = list_longest(vecs),
|
||||
dummy2 = (fit==false)? assert(minlen==maxlen, "Input vectors must have the same length") : 0
|
||||
) (fit == "long")?
|
||||
[for(i=[0:maxlen-1]) [for(v=vecs) for(x=(i<len(v)? v[i] : (fill==undef)? [fill] : fill)) x] ] :
|
||||
[for(i=[0:minlen-1]) [for(v=vecs) for(x=v[i]) x] ];
|
||||
[for(i=[0:1:maxlen-1]) [for(v=vecs) for(x=(i<len(v)? v[i] : (fill==undef)? [fill] : fill)) x] ] :
|
||||
[for(i=[0:1:minlen-1]) [for(v=vecs) for(x=v[i]) x] ];
|
||||
|
||||
|
||||
|
||||
|
@ -420,7 +420,7 @@ function zip(vecs, v2, v3, fit=false, fill=undef) =
|
|||
// array_group(v,2) returns [[1,2], [3,4], [5,6]]
|
||||
// array_group(v,3) returns [[1,2,3], [4,5,6]]
|
||||
// array_group(v,4,0) returns [[1,2,3,4], [5,6,0,0]]
|
||||
function array_group(v, cnt=2, dflt=0) = [for (i = [0:cnt:len(v)-1]) [for (j = [0:cnt-1]) default(v[i+j], dflt)]];
|
||||
function array_group(v, cnt=2, dflt=0) = [for (i = [0:cnt:len(v)-1]) [for (j = [0:1:cnt-1]) default(v[i+j], dflt)]];
|
||||
|
||||
|
||||
// Function: flatten()
|
||||
|
@ -508,7 +508,7 @@ function array_dim(v, depth=undef) =
|
|||
// transpose([3,4,5]); // Returns: [3,4,5]
|
||||
function transpose(arr) =
|
||||
arr==[]? [] :
|
||||
is_list(arr[0])? [for (i=[0:len(arr[0])-1]) [for (j=[0:len(arr)-1]) arr[j][i]]] : arr;
|
||||
is_list(arr[0])? [for (i=[0:1:len(arr[0])-1]) [for (j=[0:1:len(arr)-1]) arr[j][i]]] : arr;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -280,7 +280,7 @@ module orient_and_anchor(
|
|||
{
|
||||
if ($children>1 && chain) {
|
||||
if(shown && !hidden) {
|
||||
color($color) for (i=[0:$children-2]) children(i);
|
||||
color($color) for (i=[0:1:$children-2]) children(i);
|
||||
}
|
||||
children($children-1);
|
||||
} else {
|
||||
|
@ -294,7 +294,7 @@ module orient_and_anchor(
|
|||
{
|
||||
if ($children>1 && chain) {
|
||||
if(shown && !hidden) {
|
||||
color($color) for (i=[0:$children-2]) children(i);
|
||||
color($color) for (i=[0:1:$children-2]) children(i);
|
||||
}
|
||||
children($children-1);
|
||||
} else {
|
||||
|
|
50
beziers.scad
50
beziers.scad
|
@ -64,7 +64,7 @@ function bez_point(curve,u)=
|
|||
(len(curve) <= 1) ?
|
||||
curve[0] :
|
||||
bez_point(
|
||||
[for(i=[0:len(curve)-2]) curve[i]*(1-u)+curve[i+1]*u],
|
||||
[for(i=[0:1:len(curve)-2]) curve[i]*(1-u)+curve[i+1]*u],
|
||||
u
|
||||
);
|
||||
|
||||
|
@ -239,7 +239,7 @@ function bezier_path_closest_point(path, pt, N=3, max_err=0.01, seg=0, min_seg=u
|
|||
// max_deflect = The largest amount of deflection from the true curve to allow for approximation.
|
||||
function bezier_path_length(path, N=3, max_deflect=0.001) =
|
||||
sum([
|
||||
for (seg=[0:(len(path)-1)/N-1]) (
|
||||
for (seg=[0:1:(len(path)-1)/N-1]) (
|
||||
bezier_segment_length(
|
||||
select(path, seg*N, (seg+1)*N),
|
||||
max_deflect=max_deflect
|
||||
|
@ -270,7 +270,7 @@ function bezier_path_length(path, N=3, max_deflect=0.001) =
|
|||
function bezier_polyline(bezier, splinesteps=16, N=3) = let(
|
||||
segs = (len(bezier)-1)/N
|
||||
) concat(
|
||||
[for (seg = [0:segs-1], i = [0:splinesteps-1]) bezier_path_point(bezier, seg, i/splinesteps, N=N)],
|
||||
[for (seg = [0:1:segs-1], i = [0:1:splinesteps-1]) bezier_path_point(bezier, seg, i/splinesteps, N=N)],
|
||||
[bezier_path_point(bezier, segs-1, 1, N=N)]
|
||||
);
|
||||
|
||||
|
@ -293,7 +293,7 @@ function bezier_polyline(bezier, splinesteps=16, N=3) = let(
|
|||
function fillet_path(pts, fillet, maxerr=0.1) = concat(
|
||||
[pts[0], pts[0]],
|
||||
(len(pts) < 3)? [] : [
|
||||
for (p = [1 : len(pts)-2]) let(
|
||||
for (p = [1:1:len(pts)-2]) let(
|
||||
p1 = pts[p],
|
||||
p0 = (pts[p-1]+p1)/2,
|
||||
p2 = (pts[p+1]+p1)/2
|
||||
|
@ -326,15 +326,15 @@ function bezier_close_to_axis(bezier, N=3, axis="X") =
|
|||
sp = bezier[0],
|
||||
ep = bezier[bezend]
|
||||
) (axis=="X")? concat(
|
||||
[for (i=[0:N-1]) lerp([sp.x,0], sp, i/N)],
|
||||
[for (i=[0:1:N-1]) lerp([sp.x,0], sp, i/N)],
|
||||
bezier,
|
||||
[for (i=[1:N]) lerp(ep, [ep.x,0], i/N)],
|
||||
[for (i=[1:N]) lerp([ep.x,0], [sp.x,0], i/N)]
|
||||
[for (i=[1:1:N]) lerp(ep, [ep.x,0], i/N)],
|
||||
[for (i=[1:1:N]) lerp([ep.x,0], [sp.x,0], i/N)]
|
||||
) : (axis=="Y")? concat(
|
||||
[for (i=[0:N-1]) lerp([0,sp.y], sp, i/N)],
|
||||
[for (i=[0:1:N-1]) lerp([0,sp.y], sp, i/N)],
|
||||
bezier,
|
||||
[for (i=[1:N]) lerp(ep, [0,ep.y], i/N)],
|
||||
[for (i=[1:N]) lerp([0,ep.y], [0,sp.y], i/N)]
|
||||
[for (i=[1:1:N]) lerp(ep, [0,ep.y], i/N)],
|
||||
[for (i=[1:1:N]) lerp([0,ep.y], [0,sp.y], i/N)]
|
||||
) : (
|
||||
assert_in_list("axis", axis, ["X","Y"])
|
||||
);
|
||||
|
@ -364,9 +364,9 @@ function bezier_offset(inset, bezier, N=3, axis="X") =
|
|||
bezend = len(bezier)-1
|
||||
) concat(
|
||||
bezier,
|
||||
[for (i=[1:N-1]) lerp(bezier[bezend], backbez[0], i/N)],
|
||||
[for (i=[1:1:N-1]) lerp(bezier[bezend], backbez[0], i/N)],
|
||||
backbez,
|
||||
[for (i=[1:N]) lerp(backbez[bezend], bezier[0], i/N)]
|
||||
[for (i=[1:1:N]) lerp(backbez[bezend], bezier[0], i/N)]
|
||||
);
|
||||
|
||||
|
||||
|
@ -685,9 +685,9 @@ function bezier_triangle_point(tri, u, v) =
|
|||
len(tri) == 1 ? tri[0][0] :
|
||||
let(
|
||||
n = len(tri)-1,
|
||||
Pu = [for(i=[0:n-1]) [for (j=[1:len(tri[i])-1]) tri[i][j]]],
|
||||
Pv = [for(i=[0:n-1]) [for (j=[0:len(tri[i])-2]) tri[i][j]]],
|
||||
Pw = [for(i=[1:len(tri)-1]) tri[i]]
|
||||
Pu = [for(i=[0:1:n-1]) [for (j=[1:1:len(tri[i])-1]) tri[i][j]]],
|
||||
Pv = [for(i=[0:1:n-1]) [for (j=[0:1:len(tri[i])-2]) tri[i][j]]],
|
||||
Pw = [for(i=[1:1:len(tri)-1]) tri[i]]
|
||||
)
|
||||
bezier_triangle_point(u*Pu + v*Pv + (1-u-v)*Pw, u, v);
|
||||
|
||||
|
@ -721,12 +721,12 @@ function bezier_triangle_point(tri, u, v) =
|
|||
function bezier_patch(patch, splinesteps=16, vertices=[], faces=[]) =
|
||||
let(
|
||||
base = len(vertices),
|
||||
pts = [for (v=[0:splinesteps], u=[0:splinesteps]) bezier_patch_point(patch, u/splinesteps, v/splinesteps)],
|
||||
pts = [for (v=[0:1:splinesteps], u=[0:1:splinesteps]) bezier_patch_point(patch, u/splinesteps, v/splinesteps)],
|
||||
new_vertices = concat(vertices, pts),
|
||||
new_faces = [
|
||||
for (
|
||||
v=[0:splinesteps-1],
|
||||
u=[0:splinesteps-1],
|
||||
v=[0:1:splinesteps-1],
|
||||
u=[0:1:splinesteps-1],
|
||||
i=[0,1]
|
||||
) let (
|
||||
v1 = u+v*(splinesteps+1) + base,
|
||||
|
@ -771,8 +771,8 @@ function bezier_triangle(tri, splinesteps=16, vertices=[], faces=[]) =
|
|||
base = len(vertices),
|
||||
pts = [
|
||||
for (
|
||||
u=[0:splinesteps],
|
||||
v=[0:splinesteps-u]
|
||||
u=[0:1:splinesteps],
|
||||
v=[0:1:splinesteps-u]
|
||||
) bezier_triangle_point(tri, u/splinesteps, v/splinesteps)
|
||||
],
|
||||
new_vertices = concat(vertices, pts),
|
||||
|
@ -780,8 +780,8 @@ function bezier_triangle(tri, splinesteps=16, vertices=[], faces=[]) =
|
|||
tricnt = _tri_count(splinesteps+1),
|
||||
new_faces = [
|
||||
for (
|
||||
u=[0:splinesteps-1],
|
||||
v=[0:splinesteps-u-1]
|
||||
u=[0:1:splinesteps-1],
|
||||
v=[0:1:splinesteps-u-1]
|
||||
) let (
|
||||
v1 = v + (tricnt - _tri_count(splinesteps+1-u)) + base,
|
||||
v2 = v1 + 1,
|
||||
|
@ -812,7 +812,7 @@ function bezier_triangle(tri, splinesteps=16, vertices=[], faces=[]) =
|
|||
// trace_bezier_patches([patch], size=1, showcps=true);
|
||||
function bezier_patch_flat(size=[100,100], N=4, spin=0, orient=UP, trans=[0,0,0]) =
|
||||
let(
|
||||
patch = [for (x=[0:N]) [for (y=[0:N]) vmul(point3d(size),[x/N-0.5, 0.5-y/N, 0])]]
|
||||
patch = [for (x=[0:1:N]) [for (y=[0:1:N]) vmul(point3d(size),[x/N-0.5, 0.5-y/N, 0])]]
|
||||
) [for (row=patch)
|
||||
translate_points(v=trans,
|
||||
rotate_points3d(a=spin, from=UP, to=orient, row)
|
||||
|
@ -1014,7 +1014,7 @@ module trace_bezier_patches(patches=[], tris=[], size=1, showcps=false, splinest
|
|||
for (patch = patches) {
|
||||
place_copies(flatten(patch)) color("red") sphere(d=size*2);
|
||||
color("cyan")
|
||||
for (i=[0:len(patch)-1], j=[0:len(patch[i])-1]) {
|
||||
for (i=[0:1:len(patch)-1], j=[0:1:len(patch[i])-1]) {
|
||||
if (i<len(patch)-1) extrude_from_to(patch[i][j], patch[i+1][j]) circle(d=size);
|
||||
if (j<len(patch[i])-1) extrude_from_to(patch[i][j], patch[i][j+1]) circle(d=size);
|
||||
}
|
||||
|
@ -1024,7 +1024,7 @@ module trace_bezier_patches(patches=[], tris=[], size=1, showcps=false, splinest
|
|||
for (patch = tris) {
|
||||
place_copies(flatten(patch)) color("red") sphere(d=size*2);
|
||||
color("cyan")
|
||||
for (i=[0:len(patch)-2], j=[0:len(patch[i])-2]) {
|
||||
for (i=[0:1:len(patch)-2], j=[0:1:len(patch[i])-2]) {
|
||||
extrude_from_to(patch[i][j], patch[i+1][j]) circle(d=size);
|
||||
extrude_from_to(patch[i][j], patch[i][j+1]) circle(d=size);
|
||||
extrude_from_to(patch[i+1][j], patch[i][j+1]) circle(d=size);
|
||||
|
|
|
@ -86,7 +86,7 @@ function translate_points(pts, v=[0,0,0]) = [for (pt = pts) pt+v];
|
|||
// pts = List of points to scale.
|
||||
// v = A vector with a scaling factor for each axis.
|
||||
// cp = Centerpoint to scale around.
|
||||
function scale_points(pts, v=[0,0,0], cp=[0,0,0]) = [for (pt = pts) [for (i = [0:len(pt)-1]) (pt[i]-cp[i])*v[i]+cp[i]]];
|
||||
function scale_points(pts, v=[0,0,0], cp=[0,0,0]) = [for (pt = pts) [for (i = [0:1:len(pt)-1]) (pt[i]-cp[i])*v[i]+cp[i]]];
|
||||
|
||||
|
||||
// Function: rotate_points2d()
|
||||
|
|
|
@ -31,7 +31,7 @@ module debug_vertices(vertices, size=1, disabled=false) {
|
|||
if (!disabled) {
|
||||
echo(vertices=vertices);
|
||||
color("blue") {
|
||||
for (i = [0:len(vertices)-1]) {
|
||||
for (i = [0:1:len(vertices)-1]) {
|
||||
v = vertices[i];
|
||||
translate(v) {
|
||||
up(size/8) zrot($vpr[2]) xrot(90) {
|
||||
|
@ -76,7 +76,7 @@ module debug_faces(vertices, faces, size=1, disabled=false) {
|
|||
if (!disabled) {
|
||||
vlen = len(vertices);
|
||||
color("red") {
|
||||
for (i = [0:len(faces)-1]) {
|
||||
for (i = [0:1:len(faces)-1]) {
|
||||
face = faces[i];
|
||||
if (face[0] < 0 || face[1] < 0 || face[2] < 0 || face[0] >= vlen || face[1] >= vlen || face[2] >= vlen) {
|
||||
echo("BAD FACE: ", vlen=vlen, face=face);
|
||||
|
|
|
@ -229,7 +229,7 @@ function in_front_of_plane(plane, point) =
|
|||
// eps = Largest positional variance allowed. Default: `EPSILON` (1-e9)
|
||||
function simplify_path(path, eps=EPSILON) =
|
||||
len(path)<=2? path : let(
|
||||
indices = concat([0], [for (i=[1:len(path)-2]) if (!collinear_indexed(path, i-1, i, i+1, eps=eps)) i], [len(path)-1])
|
||||
indices = concat([0], [for (i=[1:1:len(path)-2]) if (!collinear_indexed(path, i-1, i, i+1, eps=eps)) i], [len(path)-1])
|
||||
) [for (i = indices) path[i]];
|
||||
|
||||
|
||||
|
@ -246,7 +246,7 @@ function simplify_path(path, eps=EPSILON) =
|
|||
// eps = Largest angle variance allowed. Default: EPSILON (1-e9) degrees.
|
||||
function simplify_path_indexed(points, path, eps=EPSILON) =
|
||||
len(path)<=2? path : let(
|
||||
indices = concat([0], [for (i=[1:len(path)-2]) if (!collinear_indexed(points, path[i-1], path[i], path[i+1], eps=eps)) i], [len(path)-1])
|
||||
indices = concat([0], [for (i=[1:1:len(path)-2]) if (!collinear_indexed(points, path[i-1], path[i], path[i+1], eps=eps)) i], [len(path)-1])
|
||||
) [for (i = indices) path[i]];
|
||||
|
||||
|
||||
|
@ -269,9 +269,9 @@ function simplify_path_indexed(points, path, eps=EPSILON) =
|
|||
// path = The list of 2D path points forming the perimeter of the polygon.
|
||||
function point_in_polygon(point, path) =
|
||||
// Does the point lie on any edges? If so return 0.
|
||||
sum([for(i=[0:len(path)-1]) point_on_segment2d(point, select(path, i, i+1))?1:0])>0 ? 0 :
|
||||
sum([for(i=[0:1:len(path)-1]) point_on_segment2d(point, select(path, i, i+1))?1:0])>0 ? 0 :
|
||||
// Otherwise compute winding number and return 1 for interior, -1 for exterior
|
||||
sum([for(i=[0:len(path)-1]) _point_above_below_segment(point, select(path, i, i+1))]) != 0 ? 1 : -1;
|
||||
sum([for(i=[0:1:len(path)-1]) _point_above_below_segment(point, select(path, i, i+1))]) != 0 ? 1 : -1;
|
||||
|
||||
|
||||
// Function: pointlist_bounds()
|
||||
|
|
16
hull.scad
16
hull.scad
|
@ -57,7 +57,7 @@ module hull_points(points, fast=false) {
|
|||
} else {
|
||||
extra = len(points)%3;
|
||||
faces = concat(
|
||||
[[for(i=[0:extra+2])i]],
|
||||
[[for(i=[0:1:extra+2])i]],
|
||||
[for(i=[extra+3:3:len(points)-3])[i,i+1,i+2]]
|
||||
);
|
||||
hull() polyhedron(points=points, faces=faces);
|
||||
|
@ -90,7 +90,7 @@ function hull2d_path(points) =
|
|||
a=0, b=1,
|
||||
c = _find_first_noncollinear([a,b], points, 2)
|
||||
) (c == len(points))? _hull2d_collinear(points) : let(
|
||||
remaining = [ for (i = [2:len(points)-1]) if (i != c) i ],
|
||||
remaining = [ for (i = [2:1:len(points)-1]) if (i != c) i ],
|
||||
ccw = triangle_area2d(points[a], points[b], points[c]) > 0,
|
||||
polygon = ccw? [a,b,c] : [a,c,b]
|
||||
) _hull2d_iterative(points, polygon, remaining);
|
||||
|
@ -127,7 +127,7 @@ function _find_first_noncollinear(line, points, i) =
|
|||
|
||||
|
||||
function _find_conflicting_segments(points, polygon, point) = [
|
||||
for (i = [0:len(polygon)-1]) let(
|
||||
for (i = [0:1:len(polygon)-1]) let(
|
||||
j = (i+1) % len(polygon),
|
||||
p1 = points[polygon[i]],
|
||||
p2 = points[polygon[j]],
|
||||
|
@ -139,12 +139,12 @@ function _find_conflicting_segments(points, polygon, point) = [
|
|||
// remove the conflicting segments from the polygon
|
||||
function _remove_conflicts_and_insert_point(polygon, conflicts, point) =
|
||||
(conflicts[0] == 0)? let(
|
||||
nonconflicting = [ for(i = [0:len(polygon)-1]) if (!in_list(i, conflicts)) i ],
|
||||
nonconflicting = [ for(i = [0:1:len(polygon)-1]) if (!in_list(i, conflicts)) i ],
|
||||
new_indices = concat(nonconflicting, (nonconflicting[len(nonconflicting)-1]+1) % len(polygon)),
|
||||
polygon = concat([ for (i = new_indices) polygon[i] ], point)
|
||||
) polygon : let(
|
||||
before_conflicts = [ for(i = [0:min(conflicts)]) polygon[i] ],
|
||||
after_conflicts = (max(conflicts) >= (len(polygon)-1))? [] : [ for(i = [max(conflicts)+1:len(polygon)-1]) polygon[i] ],
|
||||
before_conflicts = [ for(i = [0:1:min(conflicts)]) polygon[i] ],
|
||||
after_conflicts = (max(conflicts) >= (len(polygon)-1))? [] : [ for(i = [max(conflicts)+1:1:len(polygon)-1]) polygon[i] ],
|
||||
polygon = concat(before_conflicts, point, after_conflicts)
|
||||
) polygon;
|
||||
|
||||
|
@ -176,7 +176,7 @@ function hull3d_faces(points) =
|
|||
pts2d = [ for (p = points) xyz_to_planar(p, points[a], points[b], points[c]) ],
|
||||
hull2d = hull2d_path(pts2d)
|
||||
) hull2d : let(
|
||||
remaining = [for (i = [3:len(points)-1]) if (i != d) i],
|
||||
remaining = [for (i = [3:1:len(points)-1]) if (i != d) i],
|
||||
// Build an initial tetrahedron.
|
||||
// Swap b, c if d is in front of triangle t.
|
||||
ifop = in_front_of_plane(plane, points[d]),
|
||||
|
@ -232,7 +232,7 @@ function _remove_internal_edges(halfedges) = [
|
|||
|
||||
|
||||
function _find_conflicts(point, planes) = [
|
||||
for (i = [0:len(planes)-1])
|
||||
for (i = [0:1:len(planes)-1])
|
||||
if (in_front_of_plane(planes[i], point))
|
||||
i
|
||||
];
|
||||
|
|
|
@ -214,7 +214,7 @@ module gear2d(
|
|||
r = root_radius(mm_per_tooth, number_of_teeth, clearance, interior);
|
||||
ang = 360/number_of_teeth/2;
|
||||
union() {
|
||||
for (i = [0:number_of_teeth-teeth_to_hide-1] ) {
|
||||
for (i = [0:1:number_of_teeth-teeth_to_hide-1] ) {
|
||||
rotate(i*360/number_of_teeth) {
|
||||
translate([0,r,0]) {
|
||||
gear_tooth_profile(
|
||||
|
@ -404,7 +404,7 @@ module rack(
|
|||
orient_and_anchor([l, 2*abs(a-height), thickness], orient, anchor, spin=spin, anchors=anchors, chain=true) {
|
||||
left((number_of_teeth-1)*mm_per_tooth/2) {
|
||||
linear_extrude(height = thickness, center = true, convexity = 10) {
|
||||
for (i = [0:number_of_teeth-1] ) {
|
||||
for (i = [0:1:number_of_teeth-1] ) {
|
||||
translate([i*mm_per_tooth,0,0]) {
|
||||
polygon(
|
||||
points=[
|
||||
|
|
|
@ -338,7 +338,7 @@ module joiner_pair(spacing=100, h=40, w=10, l=10, a=30, n=2, alternate=true, scr
|
|||
}
|
||||
orient_and_anchor([spacing+w, 2*l, h], orient, anchor, spin=spin) {
|
||||
left((n-1)*spacing/2) {
|
||||
for (i=[0:n-1]) {
|
||||
for (i=[0:1:n-1]) {
|
||||
right(i*spacing) {
|
||||
yrot(180 + (alternate? (i*180+(alternate=="alt"?180:0))%360 : 0)) {
|
||||
joiner(h=h, w=w, l=l, a=a, screwsize=screwsize, guides=guides, slop=slop);
|
||||
|
|
|
@ -565,8 +565,8 @@ module rounding_angled_edge_mask(h=1.0, r=1.0, ang=90, anchor=CENTER, spin=0, or
|
|||
linear_extrude(height=h, convexity=4, center=true) {
|
||||
polygon(
|
||||
points=concat(
|
||||
[for (i = [0:n]) let (a=90+ang+i*sweep/n) [r*cos(a)+x, r*sin(a)+r]],
|
||||
[for (i = [0:n]) let (a=90+i*sweep/n) [r*cos(a)+x, r*sin(a)-r]],
|
||||
[for (i = [0:1:n]) let (a=90+ang+i*sweep/n) [r*cos(a)+x, r*sin(a)+r]],
|
||||
[for (i = [0:1:n]) let (a=90+i*sweep/n) [r*cos(a)+x, r*sin(a)-r]],
|
||||
[
|
||||
[min(-1, r*cos(270-ang)+x-1), r*sin(270-ang)-r],
|
||||
[min(-1, r*cos(90+ang)+x-1), r*sin(90+ang)+r],
|
||||
|
|
36
paths.scad
36
paths.scad
|
@ -48,7 +48,7 @@ function simplify3d_path(path, eps=1e-6) = simplify_path(path, eps=eps);
|
|||
// echo(path_length(path));
|
||||
function path_length(path) =
|
||||
len(path)<2? 0 :
|
||||
sum([for (i = [0:len(path)-2]) norm(path[i+1]-path[i])]);
|
||||
sum([for (i = [0:1:len(path)-2]) norm(path[i+1]-path[i])]);
|
||||
|
||||
|
||||
// Function: path2d_regular_ngon()
|
||||
|
@ -68,7 +68,7 @@ function path2d_regular_ngon(n=6, r=undef, d=undef, cp=[0,0], scale=[1,1]) =
|
|||
let(
|
||||
rr=get_radius(r=r, d=d, dflt=100)
|
||||
) [
|
||||
for (i=[0:n-1])
|
||||
for (i=[0:1:n-1])
|
||||
rr * [cos(i*360/n)*scale.x, sin(i*360/n)*scale.y] + cp
|
||||
];
|
||||
|
||||
|
@ -93,7 +93,7 @@ function path3d_spiral(turns=3, h=100, n=12, r=undef, d=undef, cp=[0,0], scale=[
|
|||
cnt=floor(turns*n),
|
||||
dz=h/cnt
|
||||
) [
|
||||
for (i=[0:cnt]) [
|
||||
for (i=[0:1:cnt]) [
|
||||
rr * cos(i*360/n) * scale.x + cp.x,
|
||||
rr * sin(i*360/n) * scale.y + cp.y,
|
||||
i*dz
|
||||
|
@ -133,7 +133,7 @@ function points_along_path3d(
|
|||
roth = Q_Mul(hrot, q),
|
||||
rotm = Q_Mul(arot, q)
|
||||
) concat(
|
||||
[for (i = [0:len(polyline)-1]) Q_Rot_Vector(point3d(polyline[i]),roth) + path[n]],
|
||||
[for (i = [0:1:len(polyline)-1]) Q_Rot_Vector(point3d(polyline[i]),roth) + path[n]],
|
||||
(n == end)? [] : points_along_path3d(polyline, path, rotm, n+1)
|
||||
);
|
||||
|
||||
|
@ -243,7 +243,7 @@ module extrude_2dpath_along_spiral(polyline, h, r, twist=360, center=undef, anch
|
|||
|
||||
poly_points = [
|
||||
for (
|
||||
p = [0:steps]
|
||||
p = [0:1:steps]
|
||||
) let (
|
||||
a = twist * (p/steps),
|
||||
dx = r*cos(a),
|
||||
|
@ -260,11 +260,11 @@ module extrude_2dpath_along_spiral(polyline, h, r, twist=360, center=undef, anch
|
|||
];
|
||||
|
||||
poly_faces = concat(
|
||||
[[for (b = [0:pline_count-1]) b]],
|
||||
[[for (b = [0:1:pline_count-1]) b]],
|
||||
[
|
||||
for (
|
||||
p = [0:steps-1],
|
||||
b = [0:pline_count-1],
|
||||
p = [0:1:steps-1],
|
||||
b = [0:1:pline_count-1],
|
||||
i = [0:1]
|
||||
) let (
|
||||
b2 = (b == pline_count-1)? 0 : b+1,
|
||||
|
@ -309,11 +309,11 @@ module extrude_2dpath_along_3dpath(polyline, path, ang=0, convexity=10) {
|
|||
poly_points = points_along_path3d(polyline, path);
|
||||
|
||||
poly_faces = concat(
|
||||
[[for (b = [0:pline_count-1]) b]],
|
||||
[[for (b = [0:1:pline_count-1]) b]],
|
||||
[
|
||||
for (
|
||||
p = [0:path_count-2],
|
||||
b = [0:pline_count-1],
|
||||
p = [0:1:path_count-2],
|
||||
b = [0:1:pline_count-1],
|
||||
i = [0:1]
|
||||
) let (
|
||||
b2 = (b == pline_count-1)? 0 : b+1,
|
||||
|
@ -357,7 +357,7 @@ module extrude_2d_shapes_along_3dpath(path, convexity=10, clipsize=100) {
|
|||
epsilon = 0.0001; // Make segments ever so slightly too long so they overlap.
|
||||
ptcount = len(path);
|
||||
pquats = polyquats(path);
|
||||
for (i = [0 : ptcount-2]) {
|
||||
for (i = [0:1:ptcount-2]) {
|
||||
pt1 = path[i];
|
||||
pt2 = path[i+1];
|
||||
dist = pquats[i][0];
|
||||
|
@ -400,7 +400,7 @@ module extrude_2d_shapes_along_3dpath(path, convexity=10, clipsize=100) {
|
|||
// trace_polyline(polyline, showpts=true, size=0.5, color="lightgreen");
|
||||
module trace_polyline(pline, N=1, showpts=false, size=1, color="yellow") {
|
||||
if (showpts) {
|
||||
for (i = [0:len(pline)-1]) {
|
||||
for (i = [0:1:len(pline)-1]) {
|
||||
translate(pline[i]) {
|
||||
if (i%N == 0) {
|
||||
color("blue") sphere(d=size*2.5, $fn=8);
|
||||
|
@ -414,7 +414,7 @@ module trace_polyline(pline, N=1, showpts=false, size=1, color="yellow") {
|
|||
}
|
||||
}
|
||||
}
|
||||
for (i = [0:len(pline)-2]) {
|
||||
for (i = [0:1:len(pline)-2]) {
|
||||
if (N!=3 || (i%N) != 1) {
|
||||
color(color) extrude_from_to(pline[i], pline[i+1]) circle(d=size/2);
|
||||
}
|
||||
|
@ -441,13 +441,13 @@ module trace_polyline(pline, N=1, showpts=false, size=1, color="yellow") {
|
|||
// );
|
||||
module debug_polygon(points, paths=undef, convexity=2, size=1)
|
||||
{
|
||||
pths = is_undef(paths)? [for (i=[0:len(points)-1]) i] : is_num(paths[0])? [paths] : paths;
|
||||
pths = is_undef(paths)? [for (i=[0:1:len(points)-1]) i] : is_num(paths[0])? [paths] : paths;
|
||||
echo(points=points);
|
||||
echo(paths=paths);
|
||||
linear_extrude(height=0.01, convexity=convexity, center=true) {
|
||||
polygon(points=points, paths=paths, convexity=convexity);
|
||||
}
|
||||
for (i = [0:len(points)-1]) {
|
||||
for (i = [0:1:len(points)-1]) {
|
||||
color("red") {
|
||||
up(0.2) {
|
||||
translate(points[i]) {
|
||||
|
@ -458,7 +458,7 @@ module debug_polygon(points, paths=undef, convexity=2, size=1)
|
|||
}
|
||||
}
|
||||
}
|
||||
for (j = [0:len(paths)-1]) {
|
||||
for (j = [0:1:len(paths)-1]) {
|
||||
path = paths[j];
|
||||
translate(points[path[0]]) {
|
||||
color("cyan") up(0.1) cylinder(d=size*1.5, h=0.01, center=false, $fn=12);
|
||||
|
@ -466,7 +466,7 @@ module debug_polygon(points, paths=undef, convexity=2, size=1)
|
|||
translate(points[path[len(path)-1]]) {
|
||||
color("pink") up(0.11) cylinder(d=size*1.5, h=0.01, center=false, $fn=4);
|
||||
}
|
||||
for (i = [0:len(path)-1]) {
|
||||
for (i = [0:1:len(path)-1]) {
|
||||
midpt = (points[path[i]] + points[path[(i+1)%len(path)]])/2;
|
||||
color("blue") {
|
||||
up(0.2) {
|
||||
|
|
|
@ -22,7 +22,7 @@ include <BOSL2/hull.scad>
|
|||
// Groups entries in "arr" into groups of equal values and returns index lists of those groups
|
||||
|
||||
function _unique_groups(m) = [
|
||||
for (i=[0:len(m)-1]) let(
|
||||
for (i=[0:1:len(m)-1]) let(
|
||||
s = search([m[i]], m, 0)[0]
|
||||
) if (s[0]==i) s
|
||||
];
|
||||
|
@ -333,7 +333,7 @@ module regular_polyhedron(
|
|||
}
|
||||
if ($children>0) {
|
||||
maxrange = repeat ? len(faces)-1 : $children-1;
|
||||
for(i=[0:maxrange]) {
|
||||
for(i=[0:1:maxrange]) {
|
||||
// Would like to orient so an edge (longest edge?) is parallel to x axis
|
||||
facepts = translate_points(select(scaled_points, faces[i]), translation);
|
||||
center = mean(facepts);
|
||||
|
@ -622,7 +622,7 @@ function regular_polyhedron_info(
|
|||
stellate = stellate_index==[] ? stellate : _stellated_polyhedra_[stellate_index][2],
|
||||
indexlist = (
|
||||
name=="trapezohedron" ? [0] : [ // dumy list of one item
|
||||
for(i=[0:len(_polyhedra_)-1]) (
|
||||
for(i=[0:1:len(_polyhedra_)-1]) (
|
||||
if (
|
||||
(is_undef(name) || _polyhedra_[i][pname]==name) &&
|
||||
(is_undef(type) || _polyhedra_[i][class]==type) &&
|
||||
|
@ -712,10 +712,10 @@ function stellate_faces(scalefactor,stellate,vertices,faces_normals) =
|
|||
(stellate == false || stellate == 0)? concat(faces_normals,[vertices]) :
|
||||
let(
|
||||
faces = [for(face=faces_normals[0]) select(face,hull(select(vertices,face)))],
|
||||
direction = [for(i=[0:len(faces)-1]) _facenormal(vertices, faces[i])*faces_normals[1][i]>0 ? 1 : -1],
|
||||
direction = [for(i=[0:1:len(faces)-1]) _facenormal(vertices, faces[i])*faces_normals[1][i]>0 ? 1 : -1],
|
||||
maxvertex = len(vertices),
|
||||
newpts = [for(i=[0:len(faces)-1]) mean(select(vertices,faces[i]))+stellate*scalefactor*faces_normals[1][i]],
|
||||
newfaces = [for(i=[0:len(faces)-1], j=[0:len(faces[i])-1]) concat([i+maxvertex],select(faces[i], [j, j+direction[i]]))],
|
||||
newpts = [for(i=[0:1:len(faces)-1]) mean(select(vertices,faces[i]))+stellate*scalefactor*faces_normals[1][i]],
|
||||
newfaces = [for(i=[0:1:len(faces)-1], j=[0:len(faces[i])-1]) concat([i+maxvertex],select(faces[i], [j, j+direction[i]]))],
|
||||
allpts = concat(vertices, newpts),
|
||||
normals = [for(face=newfaces) _facenormal(allpts,face)]
|
||||
) [newfaces, normals, allpts];
|
||||
|
@ -744,8 +744,8 @@ function trapezohedron(faces, r, side, longside, h) =
|
|||
!is_undef(side) ? sqrt((sqr(separation) - sqr(side))/2/(cos(180/N)-1)) :
|
||||
sqrt(sqr(longside) - sqr(h-separation/2))
|
||||
),
|
||||
top = [for(i=[0:N-1]) [r*cos(360/N*i), r*sin(360/N*i),separation/2]],
|
||||
bot = [for(i=[0:N-1]) [r*cos(180/N+360/N*i), r*sin(180/N+360/N*i),-separation/2]],
|
||||
top = [for(i=[0:1:N-1]) [r*cos(360/N*i), r*sin(360/N*i),separation/2]],
|
||||
bot = [for(i=[0:1:N-1]) [r*cos(180/N+360/N*i), r*sin(180/N+360/N*i),-separation/2]],
|
||||
vertices = concat([[0,0,h],[0,0,-h]],top,bot)
|
||||
) [
|
||||
"trapezohedron", "trapezohedron", faces, [4],
|
||||
|
|
|
@ -74,7 +74,7 @@ function square(size, center=undef, anchor=FRONT+LEFT, spin=0) =
|
|||
module circle(r=undef, d=undef, anchor=CENTER, spin=0) {
|
||||
r = get_radius(r=r, d=d, dflt=1);
|
||||
sides = segs(r);
|
||||
pts = [for (a=[0:360/sides:360-EPSILON]) r*[cos(a),sin(a)]];
|
||||
pts = [for (i=[0:1:sides-1]) let(a=360-i*360/sides) r*[cos(a),sin(a)]];
|
||||
orient_and_anchor([2*r,2*r,0], UP, anchor, spin=spin, geometry="cylinder", two_d=true, chain=true) {
|
||||
polygon(pts);
|
||||
children();
|
||||
|
|
|
@ -154,7 +154,7 @@ function round_corners(path, curve, type, all=undef, closed=true) =
|
|||
// dk will be a list of parameters, for the "smooth" type the distance and curvature parameter pair,
|
||||
// and for the circle type, distance and radius.
|
||||
dk = [
|
||||
for(i=[0:len(points)-1]) let(
|
||||
for(i=[0:1:len(points)-1]) let(
|
||||
angle = pathangle(select(points,i-1,i+1))/2,
|
||||
parm0 = is_list(parm[i]) ? parm[i][0] : parm[i],
|
||||
k = (curve=="circle" && type=="radius")? parm0 :
|
||||
|
@ -167,9 +167,9 @@ function round_corners(path, curve, type, all=undef, closed=true) =
|
|||
(curve=="smooth" && type=="joint")? [parm0,k] :
|
||||
[8*parm0/cos(angle)/(1+4*k),k]
|
||||
],
|
||||
lengths = [for(i=[0:len(points)]) norm(select(points,i)-select(points,i-1))],
|
||||
lengths = [for(i=[0:1:len(points)]) norm(select(points,i)-select(points,i-1))],
|
||||
scalefactors = [
|
||||
for(i=[0:len(points)-1])
|
||||
for(i=[0:1:len(points)-1])
|
||||
min(
|
||||
lengths[i]/sum(subindex(select(dk,i-1,i),0)),
|
||||
lengths[i+1]/sum(subindex(select(dk,i,i+1),0))
|
||||
|
@ -179,7 +179,7 @@ function round_corners(path, curve, type, all=undef, closed=true) =
|
|||
echo("Roundover scale factors:",scalefactors)
|
||||
assert(min(scalefactors)>=1,"Curves are too big for the path")
|
||||
[
|
||||
for(i=[0:len(points)-1]) each
|
||||
for(i=[0:1:len(points)-1]) each
|
||||
(dk[i][0] == 0)? [points[i]] :
|
||||
(curve=="smooth")? bezcorner(select(points,i-1,i+1), dk[i]) :
|
||||
circlecorner(select(points,i-1,i+1), dk[i])
|
||||
|
@ -235,7 +235,7 @@ function circular_arc(center, p1, p2, N) =
|
|||
)
|
||||
assert(dir != 0, "Colinear inputs don't define a unique arc")
|
||||
[
|
||||
for(i=[0:N-1]) let(
|
||||
for(i=[0:1:N-1]) let(
|
||||
theta=atan2(v1.y,v1.x)+i*dir*angle/(N-1)
|
||||
) r*[cos(theta),sin(theta)]+center
|
||||
]
|
||||
|
@ -243,14 +243,14 @@ function circular_arc(center, p1, p2, N) =
|
|||
let(axis = cross(v1,v2))
|
||||
assert(axis != [0,0,0], "Colinear inputs don't define a unique arc")
|
||||
[
|
||||
for(i=[0:N-1])
|
||||
for(i=[0:1:N-1])
|
||||
matrix3_rot_by_axis(axis, i*angle/(N-1)) * v1 + center
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
function bezier_curve(P,N) =
|
||||
[for(i=[0:N-1]) bez_point(P, i/(N-1))];
|
||||
[for(i=[0:1:N-1]) bez_point(P, i/(N-1))];
|
||||
|
||||
|
||||
function pathangle(pts) = vector_angle(pts[0]-pts[1], pts[2]-pts[1]);
|
||||
|
|
|
@ -898,7 +898,7 @@ module staggered_sphere(r=undef, d=undef, circum=false, anchor=CENTER, spin=0, o
|
|||
pts = concat(
|
||||
[[0,0,rr]],
|
||||
[
|
||||
for (p = [1:vsides-2], t = [0:sides-1]) let(
|
||||
for (p = [1:1:vsides-2], t = [0:1:sides-1]) let(
|
||||
ta = (t+(p%2/2))*step,
|
||||
pa = p*vstep
|
||||
) spherical_to_xyz(rr, ta, pa)
|
||||
|
@ -908,13 +908,13 @@ module staggered_sphere(r=undef, d=undef, circum=false, anchor=CENTER, spin=0, o
|
|||
pcnt = len(pts);
|
||||
faces = concat(
|
||||
[
|
||||
for (i = [1:sides]) each [
|
||||
for (i = [1:1:sides]) each [
|
||||
[0, i%sides+1, i],
|
||||
[pcnt-1, pcnt-1-(i%sides+1), pcnt-1-i]
|
||||
]
|
||||
],
|
||||
[
|
||||
for (p = [0:vsides-4], i = [0:sides-1]) let(
|
||||
for (p = [0:1:vsides-4], i = [0:1:sides-1]) let(
|
||||
b1 = 1+p*sides,
|
||||
b2 = 1+(p+1)*sides,
|
||||
v1 = b1+i,
|
||||
|
|
|
@ -103,7 +103,7 @@ function pie_slice2d(r=undef, d=undef, ang=30) =
|
|||
sides = ceil(segs(r)*ang/360)
|
||||
) concat(
|
||||
[[0,0]],
|
||||
[for (i=[0:sides]) let(a=i*ang/sides) r*[cos(a),sin(a)]]
|
||||
[for (i=[0:1:sides]) let(a=i*ang/sides) r*[cos(a),sin(a)]]
|
||||
);
|
||||
|
||||
|
||||
|
@ -313,10 +313,10 @@ function glued_circles(r=undef, d=undef, spread=10, tangent=30) =
|
|||
arcsegs = ceil(segs(r2)*abs(subarc)/360),
|
||||
arcstep = subarc / arcsegs
|
||||
) concat(
|
||||
[for (i=[0:lobesegs]) let(a=sa1+i*lobestep) r * [cos(a),sin(a)] - cp1],
|
||||
tangent==0? [] : [for (i=[0:arcsegs]) let(a=ea2-i*arcstep+180) r2 * [cos(a),sin(a)] - cp2],
|
||||
[for (i=[0:lobesegs]) let(a=sa1+i*lobestep+180) r * [cos(a),sin(a)] + cp1],
|
||||
tangent==0? [] : [for (i=[0:arcsegs]) let(a=ea2-i*arcstep) r2 * [cos(a),sin(a)] + cp2]
|
||||
[for (i=[0:1:lobesegs]) let(a=sa1+i*lobestep) r * [cos(a),sin(a)] - cp1],
|
||||
tangent==0? [] : [for (i=[0:1:arcsegs]) let(a=ea2-i*arcstep+180) r2 * [cos(a),sin(a)] - cp2],
|
||||
[for (i=[0:1:lobesegs]) let(a=sa1+i*lobestep+180) r * [cos(a),sin(a)] + cp1],
|
||||
tangent==0? [] : [for (i=[0:1:arcsegs]) let(a=ea2-i*arcstep) r2 * [cos(a),sin(a)] + cp2]
|
||||
);
|
||||
|
||||
|
||||
|
@ -360,7 +360,7 @@ function star(n, r, d, ir, id, step, realign=false) =
|
|||
ir = get_radius(r=ir, d=id, dflt=stepr),
|
||||
offset = 90+(realign? 180/n : 0)
|
||||
)
|
||||
[for(i=[0:2*n-1]) let(theta=180*i/n+offset, radius=(i%2)?ir:r) radius*[cos(theta), sin(theta)]];
|
||||
[for(i=[0:1:2*n-1]) let(theta=180*i/n+offset, radius=(i%2)?ir:r) radius*[cos(theta), sin(theta)]];
|
||||
|
||||
|
||||
module star(n, r, d, ir, id, step, realign=false)
|
||||
|
|
|
@ -140,10 +140,10 @@ module trapezoidal_threaded_rod(
|
|||
poly_points = concat(
|
||||
[
|
||||
for (
|
||||
start = [0 : starts-1],
|
||||
part = [0 : parts-1],
|
||||
thread = [0 : threads-1],
|
||||
astep = [0 : asteps-1]
|
||||
start = [0:1:starts-1],
|
||||
part = [0:1:parts-1],
|
||||
thread = [0:1:threads-1],
|
||||
astep = [0:1:asteps-1]
|
||||
) let (
|
||||
ppt = profile[part] * pitch,
|
||||
dz = ppt.x,
|
||||
|
@ -161,10 +161,10 @@ module trapezoidal_threaded_rod(
|
|||
// Thread surfaces
|
||||
[
|
||||
for (
|
||||
start = [0 : starts-1],
|
||||
part = [0 : parts-2],
|
||||
thread = [0 : threads-1],
|
||||
astep = [0 : asteps-1],
|
||||
start = [0:1:starts-1],
|
||||
part = [0:1:parts-2],
|
||||
thread = [0:1:threads-1],
|
||||
astep = [0:1:asteps-1],
|
||||
trinum = [0, 1]
|
||||
) let (
|
||||
p0 = _thread_pt(thread, threads, start, starts, astep, asteps, part, parts),
|
||||
|
@ -179,9 +179,9 @@ module trapezoidal_threaded_rod(
|
|||
// Thread trough bottom
|
||||
[
|
||||
for (
|
||||
start = [0 : starts-1],
|
||||
thread = [0 : threads-1],
|
||||
astep = [0 : asteps-1],
|
||||
start = [0:1:starts-1],
|
||||
thread = [0:1:threads-1],
|
||||
astep = [0:1:asteps-1],
|
||||
trinum = [0, 1]
|
||||
) let (
|
||||
p0 = _thread_pt(thread, threads, start, starts, astep, asteps, parts-1, parts),
|
||||
|
@ -199,8 +199,8 @@ module trapezoidal_threaded_rod(
|
|||
// top and bottom thread endcap
|
||||
[
|
||||
for (
|
||||
start = [0 : starts-1],
|
||||
part = [1 : parts-2],
|
||||
start = [0:1:starts-1],
|
||||
part = [1:1:parts-2],
|
||||
is_top = [0, 1]
|
||||
) let (
|
||||
astep = is_top? asteps-1 : 0,
|
||||
|
@ -215,7 +215,7 @@ module trapezoidal_threaded_rod(
|
|||
// body side triangles
|
||||
[
|
||||
for (
|
||||
start = [0 : starts-1],
|
||||
start = [0:1:starts-1],
|
||||
is_top = [false, true],
|
||||
trinum = [0, 1]
|
||||
) let (
|
||||
|
@ -237,8 +237,8 @@ module trapezoidal_threaded_rod(
|
|||
// Caps
|
||||
[
|
||||
for (
|
||||
start = [0 : starts-1],
|
||||
astep = [0 : asteps/starts-1],
|
||||
start = [0:1:starts-1],
|
||||
astep = [0:1:asteps/starts-1],
|
||||
is_top = [0, 1]
|
||||
) let (
|
||||
thread = is_top? threads-1 : 0,
|
||||
|
|
|
@ -675,7 +675,7 @@ module spread(p1=undef, p2=undef, spacing=undef, l=undef, n=undef)
|
|||
);
|
||||
assert(!is_undef(cnt), "Need two of `spacing`, 'l', 'n', or `p1`/`p2` arguments in `spread()`.");
|
||||
spos = !is_undef(p1)? point3d(p1) : -(cnt-1)/2 * spc;
|
||||
for (i=[0 : cnt-1]) {
|
||||
for (i=[0:1:cnt-1]) {
|
||||
pos = i * spc + spos;
|
||||
$pos = pos;
|
||||
$idx = i;
|
||||
|
@ -821,12 +821,12 @@ module zspread(spacing=undef, n=undef, l=undef, sp=undef)
|
|||
module distribute(spacing=undef, sizes=undef, dir=RIGHT, l=undef)
|
||||
{
|
||||
gaps = ($children < 2)? [0] :
|
||||
!is_undef(sizes)? [for (i=[0:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||
[for (i=[0:$children-2]) 0];
|
||||
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||
[for (i=[0:1:$children-2]) 0];
|
||||
spc = !is_undef(l)? ((l - sum(gaps)) / ($children-1)) : default(spacing, 10);
|
||||
gaps2 = [for (gap = gaps) gap+spc];
|
||||
spos = dir * -sum(gaps2)/2;
|
||||
for (i=[0:$children-1]) {
|
||||
for (i=[0:1:$children-1]) {
|
||||
totspc = sum(concat([0], slice(gaps2, 0, i)));
|
||||
$pos = spos + totspc * dir;
|
||||
$idx = i;
|
||||
|
@ -866,12 +866,12 @@ module xdistribute(spacing=10, sizes=undef, l=undef)
|
|||
{
|
||||
dir = RIGHT;
|
||||
gaps = ($children < 2)? [0] :
|
||||
!is_undef(sizes)? [for (i=[0:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||
[for (i=[0:$children-2]) 0];
|
||||
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||
[for (i=[0:1:$children-2]) 0];
|
||||
spc = !is_undef(l)? ((l - sum(gaps)) / ($children-1)) : default(spacing, 10);
|
||||
gaps2 = [for (gap = gaps) gap+spc];
|
||||
spos = dir * -sum(gaps2)/2;
|
||||
for (i=[0:$children-1]) {
|
||||
for (i=[0:1:$children-1]) {
|
||||
totspc = sum(concat([0], slice(gaps2, 0, i)));
|
||||
$pos = spos + totspc * dir;
|
||||
$idx = i;
|
||||
|
@ -911,12 +911,12 @@ module ydistribute(spacing=10, sizes=undef, l=undef)
|
|||
{
|
||||
dir = BACK;
|
||||
gaps = ($children < 2)? [0] :
|
||||
!is_undef(sizes)? [for (i=[0:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||
[for (i=[0:$children-2]) 0];
|
||||
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||
[for (i=[0:1:$children-2]) 0];
|
||||
spc = !is_undef(l)? ((l - sum(gaps)) / ($children-1)) : default(spacing, 10);
|
||||
gaps2 = [for (gap = gaps) gap+spc];
|
||||
spos = dir * -sum(gaps2)/2;
|
||||
for (i=[0:$children-1]) {
|
||||
for (i=[0:1:$children-1]) {
|
||||
totspc = sum(concat([0], slice(gaps2, 0, i)));
|
||||
$pos = spos + totspc * dir;
|
||||
$idx = i;
|
||||
|
@ -956,12 +956,12 @@ module zdistribute(spacing=10, sizes=undef, l=undef)
|
|||
{
|
||||
dir = UP;
|
||||
gaps = ($children < 2)? [0] :
|
||||
!is_undef(sizes)? [for (i=[0:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||
[for (i=[0:$children-2]) 0];
|
||||
!is_undef(sizes)? [for (i=[0:1:$children-2]) sizes[i]/2 + sizes[i+1]/2] :
|
||||
[for (i=[0:1:$children-2]) 0];
|
||||
spc = !is_undef(l)? ((l - sum(gaps)) / ($children-1)) : default(spacing, 10);
|
||||
gaps2 = [for (gap = gaps) gap+spc];
|
||||
spos = dir * -sum(gaps2)/2;
|
||||
for (i=[0:$children-1]) {
|
||||
for (i=[0:1:$children-1]) {
|
||||
totspc = sum(concat([0], slice(gaps2, 0, i)));
|
||||
$pos = spos + totspc * dir;
|
||||
$idx = i;
|
||||
|
@ -1042,15 +1042,15 @@ module grid2d(size=undef, spacing=undef, cols=undef, rows=undef, stagger=false,
|
|||
} else {
|
||||
spc = is_list(spacing)? spacing : vmul(scalar_vec3(spacing), scl);
|
||||
bounds = !is_undef(in_poly)? pointlist_bounds(in_poly) : undef;
|
||||
bnds = !is_undef(bounds)? [for (a=[0:1]) 2*max(vabs([ for (i=[0,1]) bounds[i][a] ]))+1 ] : undef;
|
||||
bnds = !is_undef(bounds)? [for (a=[0,1]) 2*max(vabs([ for (i=[0,1]) bounds[i][a] ]))+1 ] : undef;
|
||||
mcols = !is_undef(cols)? cols : (!is_undef(spc) && !is_undef(bnds))? quantup(ceil(bnds[0]/spc[0])-1, 4)+1 : undef;
|
||||
mrows = !is_undef(rows)? rows : (!is_undef(spc) && !is_undef(bnds))? quantup(ceil(bnds[1]/spc[1])-1, 4)+1 : undef;
|
||||
siz = vmul(spc, [mcols-1, mrows-1, 0]);
|
||||
staggermod = (stagger == "alt")? 1 : 0;
|
||||
if (stagger == false) {
|
||||
orient_and_anchor(siz, orient, anchor, spin=spin) {
|
||||
for (row = [0:mrows-1]) {
|
||||
for (col = [0:mcols-1]) {
|
||||
for (row = [0:1:mrows-1]) {
|
||||
for (col = [0:1:mcols-1]) {
|
||||
pos = [col*spc[0], row*spc[1]] - point2d(siz/2);
|
||||
if (is_undef(in_poly) || point_in_polygon(pos, in_poly)>=0) {
|
||||
$col = col;
|
||||
|
@ -1066,10 +1066,10 @@ module grid2d(size=undef, spacing=undef, cols=undef, rows=undef, stagger=false,
|
|||
orient_and_anchor(siz, orient, anchor, spin=spin) {
|
||||
cols1 = ceil(mcols/2);
|
||||
cols2 = mcols - cols1;
|
||||
for (row = [0:mrows-1]) {
|
||||
for (row = [0:1:mrows-1]) {
|
||||
rowcols = ((row%2) == staggermod)? cols1 : cols2;
|
||||
if (rowcols > 0) {
|
||||
for (col = [0:rowcols-1]) {
|
||||
for (col = [0:1:rowcols-1]) {
|
||||
rowdx = (row%2 != staggermod)? spc[0] : 0;
|
||||
pos = [2*col*spc[0]+rowdx, row*spc[1]] - point2d(siz/2);
|
||||
if (is_undef(in_poly) || point_in_polygon(pos, in_poly)>=0) {
|
||||
|
@ -1124,9 +1124,9 @@ module grid3d(xa=[0], ya=[0], za=[0], n=undef, spacing=undef)
|
|||
n = scalar_vec3(n, 1);
|
||||
spacing = scalar_vec3(spacing, undef);
|
||||
if (!is_undef(n) && !is_undef(spacing)) {
|
||||
for (xi = [0:n.x-1]) {
|
||||
for (yi = [0:n.y-1]) {
|
||||
for (zi = [0:n.z-1]) {
|
||||
for (xi = [0:1:n.x-1]) {
|
||||
for (yi = [0:1:n.y-1]) {
|
||||
for (zi = [0:1:n.z-1]) {
|
||||
$idx = [xi,yi,zi];
|
||||
$pos = vmul(spacing, $idx - (n-[1,1,1])/2);
|
||||
translate($pos) children();
|
||||
|
@ -1204,16 +1204,16 @@ module rot_copies(rots=[], v=undef, cp=[0,0,0], count=undef, n=undef, sa=0, offs
|
|||
{
|
||||
cnt = first_defined([count, n]);
|
||||
sang = sa + offset;
|
||||
angs = !is_undef(cnt)? (cnt<=0? [] : [for (i=[0:cnt-1]) i/cnt*360+sang]) : rots;
|
||||
angs = !is_undef(cnt)? (cnt<=0? [] : [for (i=[0:1:cnt-1]) i/cnt*360+sang]) : rots;
|
||||
if (cp != [0,0,0]) {
|
||||
translate(cp) rot_copies(rots=rots, v=v, n=cnt, sa=sang, delta=delta, subrot=subrot) children();
|
||||
} else if (subrot) {
|
||||
for ($idx = [0:len(angs)-1]) {
|
||||
for ($idx = [0:1:len(angs)-1]) {
|
||||
$ang = angs[$idx];
|
||||
rotate(a=$ang,v=v) translate(delta) rot(a=sang,v=v,reverse=true) children();
|
||||
}
|
||||
} else {
|
||||
for ($idx = [0:len(angs)-1]) {
|
||||
for ($idx = [0:1:len(angs)-1]) {
|
||||
$ang = angs[$idx];
|
||||
rotate(a=$ang,v=v) translate(delta) rot(a=$ang,v=v,reverse=true) children();
|
||||
}
|
||||
|
@ -1525,7 +1525,7 @@ module arc_of(
|
|||
ea = posmod(ea, 360);
|
||||
n = (abs(ea-sa)<0.01)?(n+1):n;
|
||||
delt = (((ea<=sa)?360.0:0)+ea-sa)/(n-1);
|
||||
for ($idx = [0:n-1]) {
|
||||
for ($idx = [0:1:n-1]) {
|
||||
$ang = sa + ($idx * delt);
|
||||
$pos =[rx*cos($ang), ry*sin($ang), 0];
|
||||
translate($pos) {
|
||||
|
@ -1577,9 +1577,9 @@ module ovoid_spread(r=undef, d=undef, n=100, cone_ang=90, scale=[1,1,1], perp=tr
|
|||
// Calculate an array of [theta,phi] angles for `n` number of
|
||||
// points, almost evenly spaced across the surface of a sphere.
|
||||
// This approximation is based on the golden spiral method.
|
||||
theta_phis = [for (x=[0:n-1]) [180*(1+sqrt(5))*(x+0.5)%360, acos(1-2*(x+0.5)/cnt)]];
|
||||
theta_phis = [for (x=[0:1:n-1]) [180*(1+sqrt(5))*(x+0.5)%360, acos(1-2*(x+0.5)/cnt)]];
|
||||
|
||||
for ($idx = [0:len(theta_phis)-1]) {
|
||||
for ($idx = [0:1:len(theta_phis)-1]) {
|
||||
tp = theta_phis[$idx];
|
||||
xyz = spherical_to_xyz(r, tp[0], tp[1]);
|
||||
$pos = vmul(xyz,scale);
|
||||
|
@ -2025,7 +2025,7 @@ module chain_hull()
|
|||
if ($children == 1) {
|
||||
children();
|
||||
} else if ($children > 1) {
|
||||
for (i =[1:$children-1]) {
|
||||
for (i =[1:1:$children-1]) {
|
||||
hull() {
|
||||
children(i-1);
|
||||
children(i);
|
||||
|
|
|
@ -24,7 +24,7 @@ function face_normal(points, face) =
|
|||
normalize(
|
||||
sum(
|
||||
[
|
||||
for(i=[0:count-1]) cross(
|
||||
for(i=[0:1:count-1]) cross(
|
||||
points[face[(i+1)%count]]-points[face[0]],
|
||||
points[face[(i+2)%count]]-points[face[(i+1)%count]]
|
||||
)
|
||||
|
@ -91,7 +91,7 @@ function _check_point_in_ear(point, tests) =
|
|||
function normalize_vertex_perimeter(v) =
|
||||
(len(v) < 2)? v :
|
||||
(v[len(v)-1] != v[0])? v :
|
||||
[for (i=[0:len(v)-2]) v[i]]
|
||||
[for (i=[0:1:len(v)-2]) v[i]]
|
||||
;
|
||||
|
||||
|
||||
|
@ -110,7 +110,7 @@ function is_only_noncolinear_vertex(points, facelist, vertex) =
|
|||
)
|
||||
0==sum(
|
||||
[
|
||||
for(i=[0:count-1]) norm(
|
||||
for(i=[0:1:count-1]) norm(
|
||||
cross(
|
||||
points[face[(i+1)%count]]-points[face[0]],
|
||||
points[face[(i+2)%count]]-points[face[(i+1)%count]]
|
||||
|
@ -180,7 +180,7 @@ function triangulate_face(points, face) =
|
|||
// faces = Array of faces for the polyhedron. Each face is a list of 3 or more indices into the `points` array.
|
||||
function triangulate_faces(points, faces) =
|
||||
[
|
||||
for (i=[0 : len(faces)-1])
|
||||
for (i=[0:1:len(faces)-1])
|
||||
let(facet = normalize_vertex_perimeter(faces[i]))
|
||||
for (face = triangulate_face(points, facet))
|
||||
if (face[0]!=face[1] && face[1]!=face[2] && face[2]!=face[0]) face
|
||||
|
|
|
@ -28,7 +28,7 @@ function is_vector(v) = is_list(v) && is_num(v[0]);
|
|||
// v2 = The second vector.
|
||||
// Example:
|
||||
// vmul([3,4,5], [8,7,6]); // Returns [24, 28, 30]
|
||||
function vmul(v1, v2) = [for (i = [0:len(v1)-1]) v1[i]*v2[i]];
|
||||
function vmul(v1, v2) = [for (i = [0:1:len(v1)-1]) v1[i]*v2[i]];
|
||||
|
||||
|
||||
// Function: vdiv()
|
||||
|
@ -40,7 +40,7 @@ function vmul(v1, v2) = [for (i = [0:len(v1)-1]) v1[i]*v2[i]];
|
|||
// v2 = The second vector.
|
||||
// Example:
|
||||
// vdiv([24,28,30], [8,7,6]); // Returns [3, 4, 5]
|
||||
function vdiv(v1, v2) = [for (i = [0:len(v1)-1]) v1[i]/v2[i]];
|
||||
function vdiv(v1, v2) = [for (i = [0:1:len(v1)-1]) v1[i]/v2[i]];
|
||||
|
||||
|
||||
// Function: vabs()
|
||||
|
|
|
@ -442,9 +442,9 @@ module sparse_strut3d(h=50, l=100, w=50, thick=3, maxang=40, strut=3, max_bridge
|
|||
ybridge = (l - (yreps+1) * strut) / yreps;
|
||||
xspread(xoff) sparse_strut(h=h, l=l, thick=thick, maxang=maxang, strut=strut, max_bridge=ybridge/ceil(ybridge/max_bridge));
|
||||
yspread(yoff) zrot(90) sparse_strut(h=h, l=w, thick=thick, maxang=maxang, strut=strut, max_bridge=max_bridge);
|
||||
for(zs = [0:zreps-1]) {
|
||||
for(xs = [0:xreps-1]) {
|
||||
for(ys = [0:yreps-1]) {
|
||||
for(zs = [0:1:zreps-1]) {
|
||||
for(xs = [0:1:xreps-1]) {
|
||||
for(ys = [0:1:yreps-1]) {
|
||||
translate([(xs+0.5)*xstep-xoff/2, (ys+0.5)*ystep-yoff/2, (zs+0.5)*zstep-zoff/2]) {
|
||||
zflip_copy(offset=-(zstep-strut)/2) {
|
||||
xflip_copy() {
|
||||
|
@ -459,7 +459,7 @@ module sparse_strut3d(h=50, l=100, w=50, thick=3, maxang=40, strut=3, max_bridge
|
|||
}
|
||||
}
|
||||
}
|
||||
for (soff = [0 : supp_reps-1] ) {
|
||||
for (soff = [0:1:supp_reps-1] ) {
|
||||
yflip_copy() {
|
||||
back(soff*supp_step) {
|
||||
skew_xy(ya=supp_ang) {
|
||||
|
|
|
@ -31,7 +31,7 @@ function hex_offset_ring(d, lev=0) =
|
|||
(lev == 0)? [[0,0]] : [
|
||||
for (
|
||||
sideang = [0:60:359.999],
|
||||
sidenum = [1:lev]
|
||||
sidenum = [1:1:lev]
|
||||
) [
|
||||
lev*d*cos(sideang)+sidenum*d*cos(sideang+120),
|
||||
lev*d*sin(sideang)+sidenum*d*sin(sideang+120)
|
||||
|
@ -93,8 +93,8 @@ module wiring(path, wires, wirediam=2, rounding=10, wirenum=0, bezsteps=12) {
|
|||
poly = simplify3d_path(path3d(bezier_polyline(bezpath, bezsteps)));
|
||||
n = max(segs(wirediam), 8);
|
||||
r = wirediam/2;
|
||||
for (i = [0:wires-1]) {
|
||||
extpath = [for (j = [0:n-1]) let(a=j*360/n) [r*cos(a)+offsets[i][0], r*sin(a)+offsets[i][1]]];
|
||||
for (i = [0:1:wires-1]) {
|
||||
extpath = [for (j = [0:1:n-1]) let(a=j*360/n) [r*cos(a)+offsets[i][0], r*sin(a)+offsets[i][1]]];
|
||||
color(colors[(i+wirenum)%len(colors)]) {
|
||||
extrude_2dpath_along_3dpath(extpath, poly);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue