mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-01 09:49:45 +00:00
Fix for #166: tweaks for xcopies, etc.
This commit is contained in:
parent
021073863a
commit
f36fbb60db
4 changed files with 83 additions and 23 deletions
|
@ -152,7 +152,7 @@ module line_of(spacing, n, l, p1, p2)
|
||||||
// spacing = spacing between copies. (Default: 1.0)
|
// spacing = spacing between copies. (Default: 1.0)
|
||||||
// n = Number of copies to spread out. (Default: 2)
|
// n = Number of copies to spread out. (Default: 2)
|
||||||
// l = Length to spread copies over.
|
// l = Length to spread copies over.
|
||||||
// sp = If given, copies will be spread on a line to the right of starting position `sp`. If not given, copies will be spread along a line that is centered at [0,0,0].
|
// sp = If given as a point, copies will be spread on a line to the right of starting position `sp`. If given as a scalar, copies will be spread on a line to the right of starting position `[sp,0,0]`. If not given, copies will be spread along a line that is centered at [0,0,0].
|
||||||
//
|
//
|
||||||
// Side Effects:
|
// Side Effects:
|
||||||
// `$pos` is set to the relative centerpoint of each child copy, and can be used to modify each child individually.
|
// `$pos` is set to the relative centerpoint of each child copy, and can be used to modify each child individually.
|
||||||
|
@ -170,6 +170,7 @@ module line_of(spacing, n, l, p1, p2)
|
||||||
// }
|
// }
|
||||||
module xcopies(spacing, n, l, sp)
|
module xcopies(spacing, n, l, sp)
|
||||||
{
|
{
|
||||||
|
sp = is_finite(sp)? [sp,0,0] : sp;
|
||||||
line_of(l=l*RIGHT, spacing=spacing*RIGHT, n=n, p1=sp) children();
|
line_of(l=l*RIGHT, spacing=spacing*RIGHT, n=n, p1=sp) children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,7 +188,7 @@ module xcopies(spacing, n, l, sp)
|
||||||
// spacing = spacing between copies. (Default: 1.0)
|
// spacing = spacing between copies. (Default: 1.0)
|
||||||
// n = Number of copies to spread out. (Default: 2)
|
// n = Number of copies to spread out. (Default: 2)
|
||||||
// l = Length to spread copies over.
|
// l = Length to spread copies over.
|
||||||
// sp = If given, copies will be spread on a line back from starting position `sp`. If not given, copies will be spread along a line that is centered at [0,0,0].
|
// sp = If given as a point, copies will be spread on a line back from starting position `sp`. If given as a scalar, copies will be spread on a line back from starting position `[0,sp,0]`. If not given, copies will be spread along a line that is centered at [0,0,0].
|
||||||
//
|
//
|
||||||
// Side Effects:
|
// Side Effects:
|
||||||
// `$pos` is set to the relative centerpoint of each child copy, and can be used to modify each child individually.
|
// `$pos` is set to the relative centerpoint of each child copy, and can be used to modify each child individually.
|
||||||
|
@ -205,6 +206,7 @@ module xcopies(spacing, n, l, sp)
|
||||||
// }
|
// }
|
||||||
module ycopies(spacing, n, l, sp)
|
module ycopies(spacing, n, l, sp)
|
||||||
{
|
{
|
||||||
|
sp = is_finite(sp)? [0,sp,0] : sp;
|
||||||
line_of(l=l*BACK, spacing=spacing*BACK, n=n, p1=sp) children();
|
line_of(l=l*BACK, spacing=spacing*BACK, n=n, p1=sp) children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +224,7 @@ module ycopies(spacing, n, l, sp)
|
||||||
// spacing = spacing between copies. (Default: 1.0)
|
// spacing = spacing between copies. (Default: 1.0)
|
||||||
// n = Number of copies to spread out. (Default: 2)
|
// n = Number of copies to spread out. (Default: 2)
|
||||||
// l = Length to spread copies over.
|
// l = Length to spread copies over.
|
||||||
// sp = If given, copies will be spread on a line up from starting position `sp`. If not given, copies will be spread along a line that is centered at [0,0,0].
|
// sp = If given as a point, copies will be spread on a line up from starting position `sp`. If given as a scalar, copies will be spread on a line up from starting position `[0,0,sp]`. If not given, copies will be spread along a line that is centered at [0,0,0].
|
||||||
//
|
//
|
||||||
// Side Effects:
|
// Side Effects:
|
||||||
// `$pos` is set to the relative centerpoint of each child copy, and can be used to modify each child individually.
|
// `$pos` is set to the relative centerpoint of each child copy, and can be used to modify each child individually.
|
||||||
|
@ -240,6 +242,7 @@ module ycopies(spacing, n, l, sp)
|
||||||
// }
|
// }
|
||||||
module zcopies(spacing, n, l, sp)
|
module zcopies(spacing, n, l, sp)
|
||||||
{
|
{
|
||||||
|
sp = is_finite(sp)? [0,0,sp] : sp;
|
||||||
line_of(l=l*UP, spacing=spacing*UP, n=n, p1=sp) children();
|
line_of(l=l*UP, spacing=spacing*UP, n=n, p1=sp) children();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,14 +106,23 @@ test_up();
|
||||||
|
|
||||||
|
|
||||||
module test_scale() {
|
module test_scale() {
|
||||||
|
cb = cube(1);
|
||||||
vals = [[-1,-2,-3],[1,1,1],[3,6,2],[1,2,3],[243,75,147]];
|
vals = [[-1,-2,-3],[1,1,1],[3,6,2],[1,2,3],[243,75,147]];
|
||||||
for (val=vals) {
|
for (val=vals) {
|
||||||
|
assert_equal(scale(point2d(val)), [[val.x,0,0],[0,val.y,0],[0,0,1]]);
|
||||||
assert_equal(scale(val), [[val.x,0,0,0],[0,val.y,0,0],[0,0,val.z,0],[0,0,0,1]]);
|
assert_equal(scale(val), [[val.x,0,0,0],[0,val.y,0,0],[0,0,val.z,0],[0,0,0,1]]);
|
||||||
assert_equal(scale(val, p=[1,2,3]), vmul([1,2,3], val));
|
assert_equal(scale(val, p=[1,2,3]), vmul([1,2,3], val));
|
||||||
scale(val) nil();
|
scale(val) nil();
|
||||||
}
|
}
|
||||||
assert_equal(scale(3), [[3,0,0,0],[0,3,0,0],[0,0,3,0],[0,0,0,1]]);
|
assert_equal(scale(3), [[3,0,0,0],[0,3,0,0],[0,0,3,0],[0,0,0,1]]);
|
||||||
assert_equal(scale(3, p=[1,2,3]), 3*[1,2,3]);
|
assert_equal(scale(3, p=[1,2,3]), 3*[1,2,3]);
|
||||||
|
assert_equal(scale(3, p=cb), cube(3));
|
||||||
|
assert_equal(scale(2, p=square(1)), square(2));
|
||||||
|
assert_equal(scale(2, cp=[1,1], p=square(1)), square(2, center=true));
|
||||||
|
assert_equal(scale([2,3], p=square(1)), square([2,3]));
|
||||||
|
assert_equal(scale([2,2], cp=[0.5,0.5], p=square(1)), move([-0.5,-0.5], p=square([2,2])));
|
||||||
|
assert_equal(scale([2,3,4], p=cb), cube([2,3,4]));
|
||||||
|
assert_equal(scale([-2,-3,-4], p=cb), [[for (p=cb[0]) vmul(p,[-2,-3,-4])], [for (f=cb[1]) reverse(f)]]);
|
||||||
// Verify that module at least doesn't crash.
|
// Verify that module at least doesn't crash.
|
||||||
scale(-5) scale(5) nil();
|
scale(-5) scale(5) nil();
|
||||||
}
|
}
|
||||||
|
|
|
@ -524,12 +524,12 @@ function zrot(a=0, cp=undef, p=undef) = rot(a, cp=cp, p=p);
|
||||||
|
|
||||||
// Function&Module: scale()
|
// Function&Module: scale()
|
||||||
// Usage: As Module
|
// Usage: As Module
|
||||||
// scale(SCALAR) ...
|
// scale(SCALAR, <cp>) ...
|
||||||
// scale([X,Y,Z]) ...
|
// scale([X,Y,Z], <cp>) ...
|
||||||
// Usage: Scale Points
|
// Usage: Scale Points
|
||||||
// pts = scale(v, p);
|
// pts = scale(v, p, <cp>);
|
||||||
// Usage: Get Scaling Matrix
|
// Usage: Get Scaling Matrix
|
||||||
// mat = scale(v);
|
// mat = scale(v, <cp>);
|
||||||
// Description:
|
// Description:
|
||||||
// Scales by the [X,Y,Z] scaling factors given in `v`. If `v` is given as a scalar number, all axes are scaled uniformly by that amount.
|
// Scales by the [X,Y,Z] scaling factors given in `v`. If `v` is given as a scalar number, all axes are scaled uniformly by that amount.
|
||||||
// * Called as the built-in module, scales all children.
|
// * Called as the built-in module, scales all children.
|
||||||
|
@ -541,6 +541,7 @@ function zrot(a=0, cp=undef, p=undef) = rot(a, cp=cp, p=p);
|
||||||
// * Called as a function without a `p` argument, and a 3D list of scaling factors in `v`, returns an affine3d scaling matrix.
|
// * Called as a function without a `p` argument, and a 3D list of scaling factors in `v`, returns an affine3d scaling matrix.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// v = Either a numeric uniform scaling factor, or a list of [X,Y,Z] scaling factors. Default: 1
|
// v = Either a numeric uniform scaling factor, or a list of [X,Y,Z] scaling factors. Default: 1
|
||||||
|
// cp = If given, centers the scaling on the point `cp`.
|
||||||
// p = If called as a function, the point or list of points to scale.
|
// p = If called as a function, the point or list of points to scale.
|
||||||
// Example(NORENDER):
|
// Example(NORENDER):
|
||||||
// pt1 = scale(3, p=[3,1,4]); // Returns: [9,3,12]
|
// pt1 = scale(3, p=[3,1,4]); // Returns: [9,3,12]
|
||||||
|
@ -552,20 +553,33 @@ function zrot(a=0, cp=undef, p=undef) = rot(a, cp=cp, p=p);
|
||||||
// path = circle(d=50,$fn=12);
|
// path = circle(d=50,$fn=12);
|
||||||
// #stroke(path,closed=true);
|
// #stroke(path,closed=true);
|
||||||
// stroke(scale([1.5,3],p=path),closed=true);
|
// stroke(scale([1.5,3],p=path),closed=true);
|
||||||
function scale(v=1, p=undef) =
|
function scale(v=1, cp=[0,0,0], p=undef) =
|
||||||
assert(is_num(v) || is_vector(v))
|
assert(is_num(v) || is_vector(v))
|
||||||
assert(is_undef(p) || is_list(p))
|
assert(is_undef(p) || is_list(p))
|
||||||
let(v = is_num(v)? [v,v,v] : v)
|
let( v = is_num(v)? [v,v,v] : v )
|
||||||
is_undef(p)? (
|
is_undef(p)? (
|
||||||
len(v)==2? affine2d_scale(v) : affine3d_scale(point3d(v))
|
len(v)==2? (
|
||||||
|
cp==[0,0,0] || cp == [0,0] ? affine2d_scale(v) : (
|
||||||
|
affine2d_translate(point2d(cp)) *
|
||||||
|
affine2d_scale(v) *
|
||||||
|
affine2d_translate(point2d(-cp))
|
||||||
|
)
|
||||||
|
) : (
|
||||||
|
cp==[0,0,0] ? affine3d_scale(v) : (
|
||||||
|
affine3d_translate(point3d(cp)) *
|
||||||
|
affine3d_scale(v) *
|
||||||
|
affine3d_translate(point3d(-cp))
|
||||||
|
)
|
||||||
|
)
|
||||||
) : (
|
) : (
|
||||||
assert(is_list(p))
|
assert(is_list(p))
|
||||||
is_vector(p)? ( len(p)==2? vmul(p,point2d(v)) : vmul(p,point3d(v,1)) ) :
|
let( mat = scale(v=v, cp=cp) )
|
||||||
|
is_vector(p)? apply(mat, p) :
|
||||||
is_vnf(p)? let(inv=product([for (x=v) x<0? -1 : 1])) [
|
is_vnf(p)? let(inv=product([for (x=v) x<0? -1 : 1])) [
|
||||||
scale(v=v, p=p[0]),
|
apply(mat, p[0]),
|
||||||
inv>=0? p[1] : [for (l=p[1]) reverse(l)]
|
inv>=0? p[1] : [for (l=p[1]) reverse(l)]
|
||||||
] :
|
] :
|
||||||
[ for (pp=p) scale(v=v, p=pp) ]
|
apply(mat, p)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -591,7 +605,8 @@ function scale(v=1, p=undef) =
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// x = Factor to scale by, along the X axis.
|
// x = Factor to scale by, along the X axis.
|
||||||
// p = A point or path to scale, when called as a function.
|
// cp = If given as a point, centers the scaling on the point `cp`. If given as a scalar, centers scaling on the point `[cp,0,0]`
|
||||||
|
// p = A point, path, bezier patch, or VNF to scale, when called as a function.
|
||||||
// planar = If true, and `p` is not given, then the matrix returned is an affine2d matrix instead of an affine3d matrix.
|
// planar = If true, and `p` is not given, then the matrix returned is an affine2d matrix instead of an affine3d matrix.
|
||||||
//
|
//
|
||||||
// Example: As Module
|
// Example: As Module
|
||||||
|
@ -601,9 +616,20 @@ function scale(v=1, p=undef) =
|
||||||
// path = circle(d=50,$fn=12);
|
// path = circle(d=50,$fn=12);
|
||||||
// #stroke(path,closed=true);
|
// #stroke(path,closed=true);
|
||||||
// stroke(xscale(2,p=path),closed=true);
|
// stroke(xscale(2,p=path),closed=true);
|
||||||
module xscale(x=1) scale([x,1,1]) children();
|
module xscale(x=1, cp=0) {
|
||||||
|
cp = is_num(cp)? [cp,0,0] : cp;
|
||||||
|
if (cp == [0,0,0]) {
|
||||||
|
scale([x,1,1]) children();
|
||||||
|
} else {
|
||||||
|
translate(cp) scale([x,1,1]) translate(-cp) children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function xscale(x=1, p=undef, planar=false) = (planar || (!is_undef(p) && len(p)==2))? scale([x,1],p=p) : scale([x,1,1],p=p);
|
function xscale(x=1, cp=0, p, planar=false) =
|
||||||
|
let( cp = is_num(cp)? [cp,0,0] : cp )
|
||||||
|
(planar || (!is_undef(p) && len(p)==2))
|
||||||
|
? scale([x,1], cp=cp, p=p)
|
||||||
|
: scale([x,1,1], cp=cp, p=p);
|
||||||
|
|
||||||
|
|
||||||
// Function&Module: yscale()
|
// Function&Module: yscale()
|
||||||
|
@ -627,7 +653,8 @@ function xscale(x=1, p=undef, planar=false) = (planar || (!is_undef(p) && len(p)
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// y = Factor to scale by, along the Y axis.
|
// y = Factor to scale by, along the Y axis.
|
||||||
// p = A point or path to scale, when called as a function.
|
// cp = If given as a point, centers the scaling on the point `cp`. If given as a scalar, centers scaling on the point `[0,cp,0]`
|
||||||
|
// p = A point, path, bezier patch, or VNF to scale, when called as a function.
|
||||||
// planar = If true, and `p` is not given, then the matrix returned is an affine2d matrix instead of an affine3d matrix.
|
// planar = If true, and `p` is not given, then the matrix returned is an affine2d matrix instead of an affine3d matrix.
|
||||||
//
|
//
|
||||||
// Example: As Module
|
// Example: As Module
|
||||||
|
@ -637,9 +664,20 @@ function xscale(x=1, p=undef, planar=false) = (planar || (!is_undef(p) && len(p)
|
||||||
// path = circle(d=50,$fn=12);
|
// path = circle(d=50,$fn=12);
|
||||||
// #stroke(path,closed=true);
|
// #stroke(path,closed=true);
|
||||||
// stroke(yscale(2,p=path),closed=true);
|
// stroke(yscale(2,p=path),closed=true);
|
||||||
module yscale(y=1) scale([1,y,1]) children();
|
module yscale(y=1, cp=0) {
|
||||||
|
cp = is_num(cp)? [0,cp,0] : cp;
|
||||||
|
if (cp == [0,0,0]) {
|
||||||
|
scale([1,y,1]) children();
|
||||||
|
} else {
|
||||||
|
translate(cp) scale([1,y,1]) translate(-cp) children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function yscale(y=1, p=undef, planar=false) = (planar || (!is_undef(p) && len(p)==2))? scale([1,y],p=p) : scale([1,y,1],p=p);
|
function yscale(y=1, cp=0, p, planar=false) =
|
||||||
|
let( cp = is_num(cp)? [0,cp,0] : cp )
|
||||||
|
(planar || (!is_undef(p) && len(p)==2))
|
||||||
|
? scale([1,y],p=p)
|
||||||
|
: scale([1,y,1],p=p);
|
||||||
|
|
||||||
|
|
||||||
// Function&Module: zscale()
|
// Function&Module: zscale()
|
||||||
|
@ -663,7 +701,8 @@ function yscale(y=1, p=undef, planar=false) = (planar || (!is_undef(p) && len(p)
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// z = Factor to scale by, along the Z axis.
|
// z = Factor to scale by, along the Z axis.
|
||||||
// p = A point or path to scale, when called as a function.
|
// cp = If given as a point, centers the scaling on the point `cp`. If given as a scalar, centers scaling on the point `[0,0,cp]`
|
||||||
|
// p = A point, path, bezier patch, or VNF to scale, when called as a function.
|
||||||
// planar = If true, and `p` is not given, then the matrix returned is an affine2d matrix instead of an affine3d matrix.
|
// planar = If true, and `p` is not given, then the matrix returned is an affine2d matrix instead of an affine3d matrix.
|
||||||
//
|
//
|
||||||
// Example: As Module
|
// Example: As Module
|
||||||
|
@ -673,9 +712,18 @@ function yscale(y=1, p=undef, planar=false) = (planar || (!is_undef(p) && len(p)
|
||||||
// path = xrot(90,p=path3d(circle(d=50,$fn=12)));
|
// path = xrot(90,p=path3d(circle(d=50,$fn=12)));
|
||||||
// #trace_path(path);
|
// #trace_path(path);
|
||||||
// trace_path(zscale(2,p=path));
|
// trace_path(zscale(2,p=path));
|
||||||
module zscale(z=1) scale([1,1,z]) children();
|
module zscale(z=1, cp=0) {
|
||||||
|
cp = is_num(cp)? [0,0,cp] : cp;
|
||||||
|
if (cp == [0,0,0]) {
|
||||||
|
scale([1,1,z]) children();
|
||||||
|
} else {
|
||||||
|
translate(cp) scale([1,1,z]) translate(-cp) children();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function zscale(z=1, p=undef) = scale([1,1,z],p=p);
|
function zscale(z=1, cp=0, p) =
|
||||||
|
let( cp = is_num(cp)? [0,0,cp] : cp )
|
||||||
|
scale([1,1,z], cp=cp, p=p);
|
||||||
|
|
||||||
|
|
||||||
// Function&Module: mirror()
|
// Function&Module: mirror()
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
BOSL_VERSION = [2,0,472];
|
BOSL_VERSION = [2,0,473];
|
||||||
|
|
||||||
|
|
||||||
// Section: BOSL Library Version Functions
|
// Section: BOSL Library Version Functions
|
||||||
|
|
Loading…
Reference in a new issue