mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-04 03:09:45 +00:00
Merge pull request #747 from revarbat/revarbat_dev
Added [xyz]move(). Removed affine2d planar returns from transform fu…
This commit is contained in:
commit
1d5c34eeb6
4 changed files with 121 additions and 136 deletions
22
gears.scad
22
gears.scad
|
@ -476,20 +476,18 @@ function spur_gear2d(
|
|||
) = let(
|
||||
pitch = is_undef(mod) ? pitch : pitch_value(mod),
|
||||
pr = pitch_radius(pitch=pitch, teeth=teeth),
|
||||
tooth_profile = gear_tooth_profile(
|
||||
pitch = pitch,
|
||||
teeth = teeth,
|
||||
pressure_angle = pressure_angle,
|
||||
clearance = clearance,
|
||||
backlash = backlash,
|
||||
interior = interior,
|
||||
valleys = false
|
||||
),
|
||||
pts = concat(
|
||||
[for (tooth = [0:1:teeth-hide-1])
|
||||
each rot(tooth*360/teeth,
|
||||
planar=true,
|
||||
p=gear_tooth_profile(
|
||||
pitch = pitch,
|
||||
teeth = teeth,
|
||||
pressure_angle = pressure_angle,
|
||||
clearance = clearance,
|
||||
backlash = backlash,
|
||||
interior = interior,
|
||||
valleys = false
|
||||
)
|
||||
)
|
||||
each rot(tooth*360/teeth, p=tooth_profile)
|
||||
],
|
||||
hide>0? [[0,0]] : []
|
||||
)
|
||||
|
|
|
@ -250,8 +250,8 @@ test_q_slerp();
|
|||
|
||||
|
||||
module test_q_matrix3() {
|
||||
assert_approx(q_matrix3(quat_z(37)),rot(37,planar=true));
|
||||
assert_approx(q_matrix3(quat_z(-49)),rot(-49,planar=true));
|
||||
assert_approx(q_matrix3(quat_z(37)),affine2d_zrot(37));
|
||||
assert_approx(q_matrix3(quat_z(-49)),affine2d_zrot(-49));
|
||||
}
|
||||
test_q_matrix3();
|
||||
|
||||
|
|
|
@ -289,12 +289,11 @@ module test_rot() {
|
|||
for (vec1 = vecs2d) {
|
||||
for (vec2 = vecs2d) {
|
||||
assert_approx(
|
||||
rot(from=vec1, to=vec2, p=pts2d, planar=true),
|
||||
rot(from=vec1, to=vec2, p=pts2d),
|
||||
apply(affine2d_zrot(v_theta(vec2)-v_theta(vec1)), pts2d),
|
||||
info=str(
|
||||
"from = ", vec1, ", ",
|
||||
"to = ", vec2, ", ",
|
||||
"planar = ", true, ", ",
|
||||
"p=..., 2D"
|
||||
)
|
||||
);
|
||||
|
|
194
transforms.scad
194
transforms.scad
|
@ -190,11 +190,13 @@ module left(x=0, p) {
|
|||
translate([-x,0,0]) children();
|
||||
}
|
||||
|
||||
function left(x=0, p=_NO_ARG) = assert(is_finite(x), "Invalid number")
|
||||
move([-x,0,0],p=p);
|
||||
function left(x=0, p=_NO_ARG) =
|
||||
assert(is_finite(x), "Invalid number")
|
||||
move([-x,0,0],p=p);
|
||||
|
||||
|
||||
// Function&Module: right()
|
||||
// Aliases: xmove()
|
||||
//
|
||||
// Usage: As Module
|
||||
// right(x) ...
|
||||
|
@ -230,8 +232,19 @@ module right(x=0, p) {
|
|||
translate([x,0,0]) children();
|
||||
}
|
||||
|
||||
function right(x=0, p=_NO_ARG) = assert(is_finite(x), "Invalid number")
|
||||
move([x,0,0],p=p);
|
||||
function right(x=0, p=_NO_ARG) =
|
||||
assert(is_finite(x), "Invalid number")
|
||||
move([x,0,0],p=p);
|
||||
|
||||
module xmove(x=0, p) {
|
||||
assert(is_undef(p), "Module form `xmove()` does not accept p= argument.");
|
||||
assert(is_finite(x), "Invalid number")
|
||||
translate([x,0,0]) children();
|
||||
}
|
||||
|
||||
function xmove(x=0, p=_NO_ARG) =
|
||||
assert(is_finite(x), "Invalid number")
|
||||
move([x,0,0],p=p);
|
||||
|
||||
|
||||
// Function&Module: fwd()
|
||||
|
@ -270,11 +283,13 @@ module fwd(y=0, p) {
|
|||
translate([0,-y,0]) children();
|
||||
}
|
||||
|
||||
function fwd(y=0, p=_NO_ARG) = assert(is_finite(y), "Invalid number")
|
||||
move([0,-y,0],p=p);
|
||||
function fwd(y=0, p=_NO_ARG) =
|
||||
assert(is_finite(y), "Invalid number")
|
||||
move([0,-y,0],p=p);
|
||||
|
||||
|
||||
// Function&Module: back()
|
||||
// Aliases: ymove()
|
||||
//
|
||||
// Usage: As Module
|
||||
// back(y) ...
|
||||
|
@ -310,8 +325,19 @@ module back(y=0, p) {
|
|||
translate([0,y,0]) children();
|
||||
}
|
||||
|
||||
function back(y=0,p=_NO_ARG) = assert(is_finite(y), "Invalid number")
|
||||
move([0,y,0],p=p);
|
||||
function back(y=0,p=_NO_ARG) =
|
||||
assert(is_finite(y), "Invalid number")
|
||||
move([0,y,0],p=p);
|
||||
|
||||
module ymove(y=0, p) {
|
||||
assert(is_undef(p), "Module form `ymove()` does not accept p= argument.");
|
||||
assert(is_finite(y), "Invalid number")
|
||||
translate([0,y,0]) children();
|
||||
}
|
||||
|
||||
function ymove(y=0,p=_NO_ARG) =
|
||||
assert(is_finite(y), "Invalid number")
|
||||
move([0,y,0],p=p);
|
||||
|
||||
|
||||
// Function&Module: down()
|
||||
|
@ -348,10 +374,13 @@ module down(z=0, p) {
|
|||
translate([0,0,-z]) children();
|
||||
}
|
||||
|
||||
function down(z=0, p=_NO_ARG) = move([0,0,-z],p=p);
|
||||
function down(z=0, p=_NO_ARG) =
|
||||
assert(is_finite(z), "Invalid number")
|
||||
move([0,0,-z],p=p);
|
||||
|
||||
|
||||
// Function&Module: up()
|
||||
// Aliases: zmove()
|
||||
//
|
||||
// Usage: As Module
|
||||
// up(z) ...
|
||||
|
@ -386,8 +415,19 @@ module up(z=0, p) {
|
|||
translate([0,0,z]) children();
|
||||
}
|
||||
|
||||
function up(z=0, p=_NO_ARG) = assert(is_finite(z), "Invalid number")
|
||||
move([0,0,z],p=p);
|
||||
function up(z=0, p=_NO_ARG) =
|
||||
assert(is_finite(z), "Invalid number")
|
||||
move([0,0,z],p=p);
|
||||
|
||||
module zmove(z=0, p) {
|
||||
assert(is_undef(p), "Module form `zmove()` does not accept p= argument.");
|
||||
assert(is_finite(z), "Invalid number");
|
||||
translate([0,0,z]) children();
|
||||
}
|
||||
|
||||
function zmove(z=0, p=_NO_ARG) =
|
||||
assert(is_finite(z), "Invalid number")
|
||||
move([0,0,z],p=p);
|
||||
|
||||
|
||||
|
||||
|
@ -409,10 +449,10 @@ function up(z=0, p=_NO_ARG) = assert(is_finite(z), "Invalid number")
|
|||
// pts = rot(a, v, p=, [cp=], [reverse=]);
|
||||
// pts = rot([a], from=, to=, p=, [reverse=]);
|
||||
// Usage: As a Function to return a transform matrix
|
||||
// M = rot(a, [cp=], [reverse=], [planar=]);
|
||||
// M = rot([X,Y,Z], [cp=], [reverse=], [planar=]);
|
||||
// M = rot(a, v, [cp=], [reverse=], [planar=]);
|
||||
// M = rot(from=, to=, [a=], [reverse=], [planar=]);
|
||||
// M = rot(a, [cp=], [reverse=]);
|
||||
// M = rot([X,Y,Z], [cp=], [reverse=]);
|
||||
// M = rot(a, v, [cp=], [reverse=]);
|
||||
// M = rot(from=, to=, [a=], [reverse=]);
|
||||
//
|
||||
// Topics: Affine, Matrices, Transforms, Rotation
|
||||
// See Also: xrot(), yrot(), zrot()
|
||||
|
@ -434,19 +474,17 @@ function up(z=0, p=_NO_ARG) = assert(is_finite(z), "Invalid number")
|
|||
// * Called as a function with a `p` argument containing a list of points, returns the list of rotated points.
|
||||
// * Called as a function with a [bezier patch](beziers.scad) in the `p` argument, returns the rotated patch.
|
||||
// * Called as a function with a [VNF structure](vnf.scad) in the `p` argument, returns the rotated VNF.
|
||||
// * Called as a function without a `p` argument, and `planar` is true, returns the affine2d rotational matrix. The angle `a` must be a scalar.
|
||||
// * Called as a function without a `p` argument, and `planar` is false, returns the affine3d rotational matrix.
|
||||
// * Called as a function without a `p` argument, returns the affine3d rotational matrix.
|
||||
// Note that unlike almost all the other transformations, the `p` argument must be given as a named argument.
|
||||
//
|
||||
// Arguments:
|
||||
// a = Scalar angle or vector of XYZ rotation angles to rotate by, in degrees. If `planar` is true or if `p` holds 2d data, or if you use the `from` and `to` arguments then `a` must be a scalar. Default: `0`
|
||||
// a = Scalar angle or vector of XYZ rotation angles to rotate by, in degrees. If you use the `from` and `to` arguments then `a` must be a scalar. Default: `0`
|
||||
// v = vector for the axis of rotation. Default: [0,0,1] or UP
|
||||
// ---
|
||||
// cp = centerpoint to rotate around. Default: [0,0,0]
|
||||
// from = Starting vector for vector-based rotations.
|
||||
// to = Target vector for vector-based rotations.
|
||||
// reverse = If true, exactly reverses the rotation, including axis rotation ordering. Default: false
|
||||
// planar = If called as a function, this specifies if you want to work with 2D points.
|
||||
// p = If called as a function, this contains data to rotate: a point, list of points, bezier patch or VNF.
|
||||
//
|
||||
// Example:
|
||||
|
@ -467,11 +505,11 @@ function up(z=0, p=_NO_ARG) = assert(is_finite(z), "Invalid number")
|
|||
// stroke(rot(30,p=path), closed=true);
|
||||
module rot(a=0, v, cp, from, to, reverse=false)
|
||||
{
|
||||
m = rot(a=a, v=v, cp=cp, from=from, to=to, reverse=reverse, planar=false);
|
||||
m = rot(a=a, v=v, cp=cp, from=from, to=to, reverse=reverse);
|
||||
multmatrix(m) children();
|
||||
}
|
||||
|
||||
function rot(a=0, v, cp, from, to, reverse=false, planar=false, p=_NO_ARG, _m) =
|
||||
function rot(a=0, v, cp, from, to, reverse=false, p=_NO_ARG, _m) =
|
||||
assert(is_undef(from)==is_undef(to), "from and to must be specified together.")
|
||||
assert(is_undef(from) || is_vector(from, zero=false), "'from' must be a non-zero vector.")
|
||||
assert(is_undef(to) || is_vector(to, zero=false), "'to' must be a non-zero vector.")
|
||||
|
@ -479,22 +517,8 @@ function rot(a=0, v, cp, from, to, reverse=false, planar=false, p=_NO_ARG, _m) =
|
|||
assert(is_undef(cp) || is_vector(cp), "'cp' must be a vector.")
|
||||
assert(is_finite(a) || is_vector(a), "'a' must be a finite scalar or a vector.")
|
||||
assert(is_bool(reverse))
|
||||
assert(is_bool(planar))
|
||||
let(
|
||||
m = planar? let(
|
||||
check = assert(is_num(a)),
|
||||
cp = is_undef(cp)? cp : point2d(cp),
|
||||
m1 = is_undef(from)? affine2d_zrot(a) :
|
||||
assert(a==0, "'from' and 'to' cannot be used with 'a' when 'planar' is true.")
|
||||
assert(approx(point3d(from).z, 0), "'from' must be a 2D vector when 'planar' is true.")
|
||||
assert(approx(point3d(to).z, 0), "'to' must be a 2D vector when 'planar' is true.")
|
||||
affine2d_zrot(
|
||||
v_theta(to) -
|
||||
v_theta(from)
|
||||
),
|
||||
m2 = is_undef(cp)? m1 : (move(cp) * m1 * move(-cp)),
|
||||
m3 = reverse? rot_inverse(m2) : m2
|
||||
) m3 : let(
|
||||
m = let(
|
||||
from = is_undef(from)? undef : point3d(from),
|
||||
to = is_undef(to)? undef : point3d(to),
|
||||
cp = is_undef(cp)? undef : point3d(cp),
|
||||
|
@ -534,8 +558,7 @@ function rot(a=0, v, cp, from, to, reverse=false, planar=false, p=_NO_ARG, _m) =
|
|||
// * Called as a function with a `p` argument containing a list of points, returns the list of rotated points.
|
||||
// * Called as a function with a [bezier patch](beziers.scad) in the `p` argument, returns the rotated patch.
|
||||
// * Called as a function with a [VNF structure](vnf.scad) in the `p` argument, returns the rotated VNF.
|
||||
// * Called as a function without a `p` argument, and `planar` is true, returns the affine2d rotational matrix.
|
||||
// * Called as a function without a `p` argument, and `planar` is false, returns the affine3d rotational matrix.
|
||||
// * Called as a function without a `p` argument, returns the affine3d rotational matrix.
|
||||
//
|
||||
// Arguments:
|
||||
// a = angle to rotate by in degrees.
|
||||
|
@ -580,8 +603,7 @@ function xrot(a=0, p=_NO_ARG, cp) = rot([a,0,0], cp=cp, p=p);
|
|||
// * Called as a function with a `p` argument containing a list of points, returns the list of rotated points.
|
||||
// * Called as a function with a [bezier patch](beziers.scad) in the `p` argument, returns the rotated patch.
|
||||
// * Called as a function with a [VNF structure](vnf.scad) in the `p` argument, returns the rotated VNF.
|
||||
// * Called as a function without a `p` argument, and `planar` is true, returns the affine2d rotational matrix.
|
||||
// * Called as a function without a `p` argument, and `planar` is false, returns the affine3d rotational matrix.
|
||||
// * Called as a function without a `p` argument, returns the affine3d rotational matrix.
|
||||
//
|
||||
// Arguments:
|
||||
// a = angle to rotate by in degrees.
|
||||
|
@ -626,8 +648,7 @@ function yrot(a=0, p=_NO_ARG, cp) = rot([0,a,0], cp=cp, p=p);
|
|||
// * Called as a function with a `p` argument containing a list of points, returns the list of rotated points.
|
||||
// * Called as a function with a [bezier patch](beziers.scad) in the `p` argument, returns the rotated patch.
|
||||
// * Called as a function with a [VNF structure](vnf.scad) in the `p` argument, returns the rotated VNF.
|
||||
// * Called as a function without a `p` argument, and `planar` is true, returns the affine2d rotational matrix.
|
||||
// * Called as a function without a `p` argument, and `planar` is false, returns the affine3d rotational matrix.
|
||||
// * Called as a function without a `p` argument, returns the affine3d rotational matrix.
|
||||
//
|
||||
// Arguments:
|
||||
// a = angle to rotate by in degrees.
|
||||
|
@ -716,7 +737,7 @@ function scale(v=1, p=_NO_ARG, cp=[0,0,0]) =
|
|||
// Usage: Scale Points
|
||||
// scaled = xscale(x, p, [cp=]);
|
||||
// Usage: Get Affine Matrix
|
||||
// mat = xscale(x, [cp=], [planar=]);
|
||||
// mat = xscale(x, [cp=]);
|
||||
//
|
||||
// Topics: Affine, Matrices, Transforms, Scaling
|
||||
// See Also: scale(), yscale(), zscale()
|
||||
|
@ -736,7 +757,6 @@ function scale(v=1, p=_NO_ARG, cp=[0,0,0]) =
|
|||
// p = A point, path, bezier patch, or VNF 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]`
|
||||
// planar = If true, and `p` is not given, then the matrix returned is an affine2d matrix instead of an affine3d matrix.
|
||||
//
|
||||
// Example: As Module
|
||||
// xscale(3) sphere(r=10);
|
||||
|
@ -745,9 +765,8 @@ function scale(v=1, p=_NO_ARG, cp=[0,0,0]) =
|
|||
// path = circle(d=50,$fn=12);
|
||||
// #stroke(path,closed=true);
|
||||
// stroke(xscale(2,p=path),closed=true);
|
||||
module xscale(x=1, p, cp=0, planar) {
|
||||
module xscale(x=1, p, cp=0) {
|
||||
assert(is_undef(p), "Module form `xscale()` does not accept p= argument.");
|
||||
assert(is_undef(planar), "Module form `xscale()` does not accept planar= argument.");
|
||||
cp = is_num(cp)? [cp,0,0] : cp;
|
||||
if (cp == [0,0,0]) {
|
||||
scale([x,1,1]) children();
|
||||
|
@ -756,15 +775,12 @@ module xscale(x=1, p, cp=0, planar) {
|
|||
}
|
||||
}
|
||||
|
||||
function xscale(x=1, p=_NO_ARG, cp=0, planar=false) =
|
||||
function xscale(x=1, p=_NO_ARG, cp=0) =
|
||||
assert(is_finite(x))
|
||||
assert(p==_NO_ARG || is_list(p))
|
||||
assert(is_finite(cp) || is_vector(cp))
|
||||
assert(is_bool(planar))
|
||||
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);
|
||||
scale([x,1,1], cp=cp, p=p);
|
||||
|
||||
|
||||
// Function&Module: yscale()
|
||||
|
@ -774,7 +790,7 @@ function xscale(x=1, p=_NO_ARG, cp=0, planar=false) =
|
|||
// Usage: Scale Points
|
||||
// scaled = yscale(y, p, [cp=]);
|
||||
// Usage: Get Affine Matrix
|
||||
// mat = yscale(y, [cp=], [planar=]);
|
||||
// mat = yscale(y, [cp=]);
|
||||
//
|
||||
// Topics: Affine, Matrices, Transforms, Scaling
|
||||
// See Also: scale(), xscale(), zscale()
|
||||
|
@ -794,7 +810,6 @@ function xscale(x=1, p=_NO_ARG, cp=0, planar=false) =
|
|||
// p = A point, path, bezier patch, or VNF 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]`
|
||||
// planar = If true, and `p` is not given, then the matrix returned is an affine2d matrix instead of an affine3d matrix.
|
||||
//
|
||||
// Example: As Module
|
||||
// yscale(3) sphere(r=10);
|
||||
|
@ -803,9 +818,8 @@ function xscale(x=1, p=_NO_ARG, cp=0, planar=false) =
|
|||
// path = circle(d=50,$fn=12);
|
||||
// #stroke(path,closed=true);
|
||||
// stroke(yscale(2,p=path),closed=true);
|
||||
module yscale(y=1, p, cp=0, planar) {
|
||||
module yscale(y=1, p, cp=0) {
|
||||
assert(is_undef(p), "Module form `yscale()` does not accept p= argument.");
|
||||
assert(is_undef(planar), "Module form `yscale()` does not accept planar= argument.");
|
||||
cp = is_num(cp)? [0,cp,0] : cp;
|
||||
if (cp == [0,0,0]) {
|
||||
scale([1,y,1]) children();
|
||||
|
@ -814,15 +828,12 @@ module yscale(y=1, p, cp=0, planar) {
|
|||
}
|
||||
}
|
||||
|
||||
function yscale(y=1, p=_NO_ARG, cp=0, planar=false) =
|
||||
function yscale(y=1, p=_NO_ARG, cp=0) =
|
||||
assert(is_finite(y))
|
||||
assert(p==_NO_ARG || is_list(p))
|
||||
assert(is_finite(cp) || is_vector(cp))
|
||||
assert(is_bool(planar))
|
||||
let( cp = is_num(cp)? [0,cp,0] : cp )
|
||||
(planar || (!is_undef(p) && len(p)==2))
|
||||
? scale([1,y], cp=cp, p=p)
|
||||
: scale([1,y,1], cp=cp, p=p);
|
||||
scale([1,y,1], cp=cp, p=p);
|
||||
|
||||
|
||||
// Function&Module: zscale()
|
||||
|
@ -958,7 +969,7 @@ function mirror(v, p=_NO_ARG) =
|
|||
// Usage: As Function
|
||||
// pt = xflip(p, [x]);
|
||||
// Usage: Get Affine Matrix
|
||||
// pt = xflip([x], [planar=]);
|
||||
// pt = xflip([x]);
|
||||
//
|
||||
// Topics: Affine, Matrices, Transforms, Reflection, Mirroring
|
||||
// See Also: mirror(), yflip(), zflip()
|
||||
|
@ -970,14 +981,11 @@ function mirror(v, p=_NO_ARG) =
|
|||
// * Called as a function with a list of points in the `p` argument, returns the list of points, with each one mirrored across the line/plane.
|
||||
// * Called as a function with a [bezier patch](beziers.scad) in the `p` argument, returns the mirrored patch.
|
||||
// * Called as a function with a [VNF structure](vnf.scad) in the `p` argument, returns the mirrored VNF.
|
||||
// * Called as a function without a `p` argument, and `planar=true`, returns the affine2d 3x3 mirror matrix.
|
||||
// * Called as a function without a `p` argument, and `planar=false`, returns the affine3d 4x4 mirror matrix.
|
||||
// * Called as a function without a `p` argument, returns the affine3d 4x4 mirror matrix.
|
||||
//
|
||||
// Arguments:
|
||||
// x = The X coordinate of the plane of reflection. Default: 0
|
||||
// p = If given, the point, path, patch, or VNF to mirror. Function use only.
|
||||
// ---
|
||||
// planar = If true, and p is not given, returns a 2D affine transformation matrix. Function use only. Default: False
|
||||
//
|
||||
// Example:
|
||||
// xflip() yrot(90) cylinder(d1=10, d2=0, h=20);
|
||||
|
@ -988,26 +996,21 @@ function mirror(v, p=_NO_ARG) =
|
|||
// xflip(x=-5) yrot(90) cylinder(d1=10, d2=0, h=20);
|
||||
// color("blue", 0.25) left(5) cube([0.01,15,15], center=true);
|
||||
// color("red", 0.333) yrot(90) cylinder(d1=10, d2=0, h=20);
|
||||
module xflip(p, x=0, planar) {
|
||||
module xflip(p, x=0) {
|
||||
assert(is_undef(p), "Module form `zflip()` does not accept p= argument.");
|
||||
assert(is_undef(planar), "Module form `zflip()` does not accept planar= argument.");
|
||||
translate([x,0,0])
|
||||
mirror([1,0,0])
|
||||
translate([-x,0,0]) children();
|
||||
}
|
||||
|
||||
function xflip(p=_NO_ARG, x=0, planar=false) =
|
||||
function xflip(p=_NO_ARG, x=0) =
|
||||
assert(is_finite(x))
|
||||
assert(is_bool(planar))
|
||||
assert(p==_NO_ARG || is_list(p),"Invalid point list")
|
||||
let( v = RIGHT )
|
||||
x == 0 ? mirror(v,p=p) :
|
||||
let(
|
||||
v = RIGHT,
|
||||
n = planar? point2d(v) : v
|
||||
)
|
||||
x == 0 ? mirror(n,p=p) :
|
||||
let(
|
||||
cp = x * n,
|
||||
m = move(cp) * mirror(n) * move(-cp)
|
||||
cp = x * v,
|
||||
m = move(cp) * mirror(v) * move(-cp)
|
||||
)
|
||||
p==_NO_ARG? m : apply(m, p);
|
||||
|
||||
|
@ -1019,7 +1022,7 @@ function xflip(p=_NO_ARG, x=0, planar=false) =
|
|||
// Usage: As Function
|
||||
// pt = yflip(p, [y]);
|
||||
// Usage: Get Affine Matrix
|
||||
// pt = yflip([y], [planar=]);
|
||||
// pt = yflip([y]);
|
||||
//
|
||||
// Topics: Affine, Matrices, Transforms, Reflection, Mirroring
|
||||
// See Also: mirror(), xflip(), zflip()
|
||||
|
@ -1031,14 +1034,11 @@ function xflip(p=_NO_ARG, x=0, planar=false) =
|
|||
// * Called as a function with a list of points in the `p` argument, returns the list of points, with each one mirrored across the line/plane.
|
||||
// * Called as a function with a [bezier patch](beziers.scad) in the `p` argument, returns the mirrored patch.
|
||||
// * Called as a function with a [VNF structure](vnf.scad) in the `p` argument, returns the mirrored VNF.
|
||||
// * Called as a function without a `p` argument, and `planar=true`, returns the affine2d 3x3 mirror matrix.
|
||||
// * Called as a function without a `p` argument, and `planar=false`, returns the affine3d 4x4 mirror matrix.
|
||||
// * Called as a function without a `p` argument, returns the affine3d 4x4 mirror matrix.
|
||||
//
|
||||
// Arguments:
|
||||
// p = If given, the point, path, patch, or VNF to mirror. Function use only.
|
||||
// y = The Y coordinate of the plane of reflection. Default: 0
|
||||
// ---
|
||||
// planar = If true, and p is not given, returns a 2D affine transformation matrix. Function use only. Default: False
|
||||
//
|
||||
// Example:
|
||||
// yflip() xrot(90) cylinder(d1=10, d2=0, h=20);
|
||||
|
@ -1049,26 +1049,21 @@ function xflip(p=_NO_ARG, x=0, planar=false) =
|
|||
// yflip(y=5) xrot(90) cylinder(d1=10, d2=0, h=20);
|
||||
// color("blue", 0.25) back(5) cube([15,0.01,15], center=true);
|
||||
// color("red", 0.333) xrot(90) cylinder(d1=10, d2=0, h=20);
|
||||
module yflip(p, y=0, planar) {
|
||||
module yflip(p, y=0) {
|
||||
assert(is_undef(p), "Module form `yflip()` does not accept p= argument.");
|
||||
assert(is_undef(planar), "Module form `yflip()` does not accept planar= argument.");
|
||||
translate([0,y,0])
|
||||
mirror([0,1,0])
|
||||
translate([0,-y,0]) children();
|
||||
}
|
||||
|
||||
function yflip(p=_NO_ARG, y=0, planar=false) =
|
||||
function yflip(p=_NO_ARG, y=0) =
|
||||
assert(is_finite(y))
|
||||
assert(is_bool(planar))
|
||||
assert(p==_NO_ARG || is_list(p),"Invalid point list")
|
||||
let( v = BACK )
|
||||
y == 0 ? mirror(v,p=p) :
|
||||
let(
|
||||
v = BACK,
|
||||
n = planar? point2d(v) : v
|
||||
)
|
||||
y == 0 ? mirror(n,p=p) :
|
||||
let(
|
||||
cp = y * n,
|
||||
m = move(cp) * mirror(n) * move(-cp)
|
||||
cp = y * v,
|
||||
m = move(cp) * mirror(v) * move(-cp)
|
||||
)
|
||||
p==_NO_ARG? m : apply(m, p);
|
||||
|
||||
|
@ -1219,7 +1214,7 @@ module frame_map(x,y,z,p,reverse=false)
|
|||
// Usage: As Function
|
||||
// pts = skew(p, [sxy=], [sxz=], [syx=], [syz=], [szx=], [szy=]);
|
||||
// Usage: Get Affine Matrix
|
||||
// mat = skew([sxy=], [sxz=], [syx=], [syz=], [szx=], [szy=], [planar=]);
|
||||
// mat = skew([sxy=], [sxz=], [syx=], [syz=], [szx=], [szy=]);
|
||||
// Topics: Affine, Matrices, Transforms, Skewing
|
||||
//
|
||||
// Description:
|
||||
|
@ -1229,8 +1224,7 @@ module frame_map(x,y,z,p,reverse=false)
|
|||
// * Called as a function with a list of points in the `p` argument, returns the list of skewed points.
|
||||
// * Called as a function with a [bezier patch](beziers.scad) in the `p` argument, returns the skewed patch.
|
||||
// * Called as a function with a [VNF structure](vnf.scad) in the `p` argument, returns the skewed VNF.
|
||||
// * Called as a function without a `p` argument, and with `planar` true, returns the affine2d 3x3 skew matrix.
|
||||
// * Called as a function without a `p` argument, and with `planar` false, returns the affine3d 4x4 skew matrix.
|
||||
// * Called as a function without a `p` argument, returns the affine3d 4x4 skew matrix.
|
||||
// Each skew factor is a multiplier. For example, if `sxy=2`, then it will skew along the X axis by 2x the value of the Y axis.
|
||||
// Arguments:
|
||||
// p = If given, the point, path, patch, or VNF to skew. Function use only.
|
||||
|
@ -1274,21 +1268,15 @@ module skew(p, sxy=0, sxz=0, syx=0, syz=0, szx=0, szy=0)
|
|||
) children();
|
||||
}
|
||||
|
||||
function skew(p=_NO_ARG, sxy=0, sxz=0, syx=0, syz=0, szx=0, szy=0, planar=false) =
|
||||
function skew(p=_NO_ARG, sxy=0, sxz=0, syx=0, syz=0, szx=0, szy=0) =
|
||||
assert(is_finite(sxy))
|
||||
assert(is_finite(sxz))
|
||||
assert(is_finite(syx))
|
||||
assert(is_finite(syz))
|
||||
assert(is_finite(szx))
|
||||
assert(is_finite(szy))
|
||||
assert(is_bool(planar))
|
||||
let(
|
||||
planar = planar || (is_list(p) && is_num(p.x) && len(p)==2),
|
||||
m = planar? [
|
||||
[ 1, sxy, 0],
|
||||
[syx, 1, 0],
|
||||
[ 0, 0, 1]
|
||||
] : affine3d_skew(sxy=sxy, sxz=sxz, syx=syx, syz=syz, szx=szx, szy=szy)
|
||||
m = affine3d_skew(sxy=sxy, sxz=sxz, syx=syx, syz=syz, szx=szx, szy=szy)
|
||||
)
|
||||
p==_NO_ARG? m : apply(m, p);
|
||||
|
||||
|
|
Loading…
Reference in a new issue