mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +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)
|
||||
// n = Number of copies to spread out. (Default: 2)
|
||||
// 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:
|
||||
// `$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)
|
||||
{
|
||||
sp = is_finite(sp)? [sp,0,0] : sp;
|
||||
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)
|
||||
// n = Number of copies to spread out. (Default: 2)
|
||||
// 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:
|
||||
// `$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)
|
||||
{
|
||||
sp = is_finite(sp)? [0,sp,0] : sp;
|
||||
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)
|
||||
// n = Number of copies to spread out. (Default: 2)
|
||||
// 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:
|
||||
// `$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)
|
||||
{
|
||||
sp = is_finite(sp)? [0,0,sp] : sp;
|
||||
line_of(l=l*UP, spacing=spacing*UP, n=n, p1=sp) children();
|
||||
}
|
||||
|
||||
|
|
|
@ -106,14 +106,23 @@ test_up();
|
|||
|
||||
|
||||
module test_scale() {
|
||||
cb = cube(1);
|
||||
vals = [[-1,-2,-3],[1,1,1],[3,6,2],[1,2,3],[243,75,147]];
|
||||
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, p=[1,2,3]), vmul([1,2,3], val));
|
||||
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, 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.
|
||||
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()
|
||||
// Usage: As Module
|
||||
// scale(SCALAR) ...
|
||||
// scale([X,Y,Z]) ...
|
||||
// scale(SCALAR, <cp>) ...
|
||||
// scale([X,Y,Z], <cp>) ...
|
||||
// Usage: Scale Points
|
||||
// pts = scale(v, p);
|
||||
// pts = scale(v, p, <cp>);
|
||||
// Usage: Get Scaling Matrix
|
||||
// mat = scale(v);
|
||||
// mat = scale(v, <cp>);
|
||||
// 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.
|
||||
// * 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.
|
||||
// Arguments:
|
||||
// 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.
|
||||
// Example(NORENDER):
|
||||
// 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);
|
||||
// #stroke(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_undef(p) || is_list(p))
|
||||
let( v = is_num(v)? [v,v,v] : v )
|
||||
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))
|
||||
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])) [
|
||||
scale(v=v, p=p[0]),
|
||||
apply(mat, p[0]),
|
||||
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:
|
||||
// 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.
|
||||
//
|
||||
// Example: As Module
|
||||
|
@ -601,9 +616,20 @@ function scale(v=1, p=undef) =
|
|||
// path = circle(d=50,$fn=12);
|
||||
// #stroke(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()
|
||||
|
@ -627,7 +653,8 @@ function xscale(x=1, p=undef, planar=false) = (planar || (!is_undef(p) && len(p)
|
|||
//
|
||||
// Arguments:
|
||||
// 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.
|
||||
//
|
||||
// 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);
|
||||
// #stroke(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()
|
||||
|
@ -663,7 +701,8 @@ function yscale(y=1, p=undef, planar=false) = (planar || (!is_undef(p) && len(p)
|
|||
//
|
||||
// Arguments:
|
||||
// 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.
|
||||
//
|
||||
// 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)));
|
||||
// #trace_path(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()
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
BOSL_VERSION = [2,0,472];
|
||||
BOSL_VERSION = [2,0,473];
|
||||
|
||||
|
||||
// Section: BOSL Library Version Functions
|
||||
|
|
Loading…
Reference in a new issue