vmul() to v_mul(), etc.

This commit is contained in:
Garth Minette 2021-06-14 20:28:49 -07:00
parent e0625491ee
commit a748c77077
18 changed files with 130 additions and 132 deletions

View file

@ -328,7 +328,7 @@ function attach_geom_size(geom) =
[2*maxxr, 2*maxyr,l]
) : type == "spheroid"? ( //r
let( r=geom[1] )
is_num(r)? [2,2,2]*r : vmul([2,2,2],point3d(r))
is_num(r)? [2,2,2]*r : v_mul([2,2,2],point3d(r))
) : type == "vnf_extent" || type=="vnf_isect"? ( //vnf
let(
vnf = geom[1]
@ -344,7 +344,7 @@ function attach_geom_size(geom) =
) [maxx, size.y]
) : type == "circle"? ( //r
let( r=geom[1] )
is_num(r)? [2,2]*r : vmul([2,2],point2d(r))
is_num(r)? [2,2]*r : v_mul([2,2],point2d(r))
) : type == "path_isect" || type == "path_extent"? ( //path
let(
mm = pointlist_bounds(geom[1]),
@ -476,8 +476,8 @@ function find_anchor(anchor, geom) =
h = size.z,
u = (anch.z+1)/2,
axy = point2d(anch),
bot = point3d(vmul(point2d(size)/2,axy),-h/2),
top = point3d(vmul(point2d(size2)/2,axy)+shift,h/2),
bot = point3d(v_mul(point2d(size)/2,axy),-h/2),
top = point3d(v_mul(point2d(size2)/2,axy)+shift,h/2),
pos = point3d(cp) + lerp(bot,top,u) + offset,
sidevec = unit(rot(from=UP, to=top-bot, p=point3d(axy)),UP),
vvec = anch==CENTER? UP : unit([0,0,anch.z],UP),
@ -497,8 +497,8 @@ function find_anchor(anchor, geom) =
anch = rot(from=axis, to=UP, p=anchor),
u = (anch.z+1)/2,
axy = unit(point2d(anch),[0,0]),
bot = point3d(vmul(r1,axy), -l/2),
top = point3d(vmul(r2,axy)+shift, l/2),
bot = point3d(v_mul(r1,axy), -l/2),
top = point3d(v_mul(r2,axy)+shift, l/2),
pos = point3d(cp) + lerp(bot,top,u) + offset,
sidevec = rot(from=UP, to=top-bot, p=point3d(axy)),
vvec = anch==CENTER? UP : unit([0,0,anch.z],UP),
@ -514,8 +514,8 @@ function find_anchor(anchor, geom) =
rr = geom[1],
r = is_num(rr)? [rr,rr,rr] : point3d(rr),
anchor = unit(point3d(anchor),CENTER),
pos = point3d(cp) + vmul(r,anchor) + point3d(offset),
vec = unit(vmul(r,anchor),UP)
pos = point3d(cp) + v_mul(r,anchor) + point3d(offset),
vec = unit(v_mul(r,anchor),UP)
) [anchor, pos, vec, oang]
) : type == "vnf_isect"? ( //vnf
let(
@ -597,8 +597,8 @@ function find_anchor(anchor, geom) =
rr = geom[1],
r = is_num(rr)? [rr,rr] : point2d(rr),
anchor = unit(point2d(anchor),[0,0]),
pos = point2d(cp) + vmul(r,anchor) + point2d(offset),
vec = unit(vmul(r,anchor),[0,1])
pos = point2d(cp) + v_mul(r,anchor) + point2d(offset),
vec = unit(v_mul(r,anchor),[0,1])
) [anchor, pos, vec, 0]
) : type == "path_isect"? ( //path
let(
@ -1232,10 +1232,10 @@ module edge_profile(edges=EDGES_ALL, except=[], convexity=10) {
psize = point3d($parent_size);
length = [for (i=[0:2]) if(!vec[i]) psize[i]][0]+0.1;
rotang =
vec.z<0? [90,0,180+vang(point2d(vec))] :
vec.z==0 && sign(vec.x)==sign(vec.y)? 135+vang(point2d(vec)) :
vec.z==0 && sign(vec.x)!=sign(vec.y)? [0,180,45+vang(point2d(vec))] :
[-90,0,180+vang(point2d(vec))];
vec.z<0? [90,0,180+v_theta(vec)] :
vec.z==0 && sign(vec.x)==sign(vec.y)? 135+v_theta(vec) :
vec.z==0 && sign(vec.x)!=sign(vec.y)? [0,180,45+v_theta(vec)] :
[-90,0,180+v_theta(vec)];
translate(anch[1]) {
rot(rotang) {
linear_extrude(height=length, center=true, convexity=convexity) {
@ -1286,8 +1286,8 @@ module corner_profile(corners=CORNERS_ALL, except=[], r, d, convexity=10) {
$attach_norot = true;
$tags = "mask";
rotang = vec.z<0?
[ 0,0,180+vang(point2d(vec))-45] :
[180,0,-90+vang(point2d(vec))-45];
[ 0,0,180+v_theta(vec)-45] :
[180,0,-90+v_theta(vec)-45];
translate(anch[1]) {
rot(rotang) {
render(convexity=convexity)
@ -1357,10 +1357,10 @@ module edge_mask(edges=EDGES_ALL, except=[]) {
$attach_norot = true;
$tags = "mask";
rotang =
vec.z<0? [90,0,180+vang(point2d(vec))] :
vec.z==0 && sign(vec.x)==sign(vec.y)? 135+vang(point2d(vec)) :
vec.z==0 && sign(vec.x)!=sign(vec.y)? [0,180,45+vang(point2d(vec))] :
[-90,0,180+vang(point2d(vec))];
vec.z<0? [90,0,180+v_theta(vec)] :
vec.z==0 && sign(vec.x)==sign(vec.y)? 135+v_theta(vec) :
vec.z==0 && sign(vec.x)!=sign(vec.y)? [0,180,45+v_theta(vec)] :
[-90,0,180+v_theta(vec)];
translate(anch[1]) rot(rotang) children();
}
}
@ -1401,8 +1401,8 @@ module corner_mask(corners=CORNERS_ALL, except=[]) {
$attach_norot = true;
$tags = "mask";
rotang = vec.z<0?
[ 0,0,180+vang(point2d(vec))-45] :
[180,0,-90+vang(point2d(vec))-45];
[ 0,0,180+v_theta(vec)-45] :
[180,0,-90+v_theta(vec)-45];
translate(anch[1]) rot(rotang) children();
}
}

View file

@ -1461,7 +1461,7 @@ function bezier_patch_flat(size=[100,100], N=4, spin=0, orient=UP, trans=[0,0,0]
patch = [
for (x=[0:1:N]) [
for (y=[0:1:N])
vmul(point3d(size), [x/N-0.5, 0.5-y/N, 0])
v_mul(point3d(size), [x/N-0.5, 0.5-y/N, 0])
]
],
m = move(trans) * rot(a=spin, from=UP, to=orient)

View file

@ -465,7 +465,7 @@ module cubetruss(extents=6, clips=[], bracing, size, strut, clipthick, anchor=CE
}
if (clipthick > 0) {
for (vec = clips) {
exts = vabs(rot(from=FWD, to=vec, p=extents));
exts = v_abs(rot(from=FWD, to=vec, p=extents));
rot(from=FWD,to=vec) {
for (zrow = [0:1:exts.z-1]) {
up((zrow-(exts.z-1)/2)*(size-strut)) {

View file

@ -520,20 +520,20 @@ module grid2d(spacing, n, size, stagger=false, inside=undef)
) :
is_vector(spacing)? assert(len(spacing)==2) spacing :
size!=undef? (
is_num(n)? vdiv(size,(n-1)*[1,1]) :
is_vector(n)? assert(len(n)==2) vdiv(size,n-[1,1]) :
vdiv(size,(stagger==false? [1,1] : [2,2]))
is_num(n)? v_div(size,(n-1)*[1,1]) :
is_vector(n)? assert(len(n)==2) v_div(size,n-[1,1]) :
v_div(size,(stagger==false? [1,1] : [2,2]))
) :
undef;
n = is_num(n)? [n,n] :
is_vector(n)? assert(len(n)==2) n :
size!=undef && spacing!=undef? vfloor(vdiv(size,spacing))+[1,1] :
size!=undef && spacing!=undef? v_floor(v_div(size,spacing))+[1,1] :
[2,2];
offset = vmul(spacing, n-[1,1])/2;
offset = v_mul(spacing, n-[1,1])/2;
if (stagger == false) {
for (row = [0:1:n.y-1]) {
for (col = [0:1:n.x-1]) {
pos = vmul([col,row],spacing) - offset;
pos = v_mul([col,row],spacing) - offset;
if (
is_undef(inside) ||
(is_path(inside) && point_in_polygon(pos, inside)>=0) ||
@ -556,7 +556,7 @@ module grid2d(spacing, n, size, stagger=false, inside=undef)
if (rowcols > 0) {
for (col = [0:1:rowcols-1]) {
rowdx = (row%2 != staggermod)? spacing.x : 0;
pos = vmul([2*col,row],spacing) + [rowdx,0] - offset;
pos = v_mul([2*col,row],spacing) + [rowdx,0] - offset;
if (
is_undef(inside) ||
(is_path(inside) && point_in_polygon(pos, inside)>=0) ||
@ -616,7 +616,7 @@ module grid3d(xa=[0], ya=[0], za=[0], n=undef, spacing=undef)
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);
$pos = v_mul(spacing, $idx - (n-[1,1,1])/2);
translate($pos) children();
}
}
@ -989,7 +989,7 @@ module arc_of(
//
// Example:
// ovoid_spread(n=500, d=100, cone_ang=180)
// color(unit(point3d(vabs($pos))))
// color(unit(point3d(v_abs($pos))))
// cylinder(d=8, h=10, center=false);
module ovoid_spread(r=undef, d=undef, n=100, cone_ang=90, scale=[1,1,1], perp=true)
{
@ -1004,7 +1004,7 @@ module ovoid_spread(r=undef, d=undef, n=100, cone_ang=90, scale=[1,1,1], perp=tr
for ($idx = idx(theta_phis)) {
tp = theta_phis[$idx];
xyz = spherical_to_xyz(r, tp[0], tp[1]);
$pos = vmul(xyz,point3d(scale,1));
$pos = v_mul(xyz,point3d(scale,1));
$theta = tp[0];
$phi = tp[1];
$rad = r;

View file

@ -139,7 +139,7 @@ function _edge_set(v) =
str(v, " must be a vector, edge array, or one of ", valid_values)
) v
) :
let(nonz = sum(vabs(v)))
let(nonz = sum(v_abs(v)))
nonz==2? (v==v2) : // Edge: return matching edge.
let(
matches = count_true([

View file

@ -928,7 +928,7 @@ function bevel_gear(
radcp = [0, midpr] + polar_to_xy(cutter_radius, 180+spiral_angle),
angC1 = law_of_cosines(a=cutter_radius, b=norm(radcp), c=ocone_rad),
angC2 = law_of_cosines(a=cutter_radius, b=norm(radcp), c=icone_rad),
radcpang = vang(radcp),
radcpang = v_theta(radcp),
sang = radcpang - (180-angC1),
eang = radcpang - (180-angC2),
profile = gear_tooth_profile(
@ -944,7 +944,7 @@ function bevel_gear(
verts1 = [
for (v = lerpn(0,1,slices+1)) let(
p = radcp + polar_to_xy(cutter_radius, lerp(sang,eang,v)),
ang = vang(p)-90,
ang = v_theta(p)-90,
dist = norm(p)
) [
let(

View file

@ -237,7 +237,7 @@ function u_sub(a,b) = is_undef(a) || is_undef(b)? undef : a - b;
// b = Second value.
function u_mul(a,b) =
is_undef(a) || is_undef(b)? undef :
is_vector(a) && is_vector(b)? vmul(a,b) :
is_vector(a) && is_vector(b)? v_mul(a,b) :
a * b;
@ -252,7 +252,7 @@ function u_mul(a,b) =
// b = Second value.
function u_div(a,b) =
is_undef(a) || is_undef(b)? undef :
is_vector(a) && is_vector(b)? vdiv(a,b) :
is_vector(a) && is_vector(b)? v_div(a,b) :
a / b;
@ -674,7 +674,7 @@ function _product(v, i=0, _tot) =
i>=len(v) ? _tot :
_product( v,
i+1,
( is_vector(v[i])? vmul(_tot,v[i]) : _tot*v[i] ) );
( is_vector(v[i])? v_mul(_tot,v[i]) : _tot*v[i] ) );
@ -711,7 +711,7 @@ function _cumprod_vec(v,_i=0,_acc=[]) =
v, _i+1,
concat(
_acc,
[_i==0 ? v[_i] : vmul(_acc[len(_acc)-1],v[_i])]
[_i==0 ? v[_i] : v_mul(_acc[len(_acc)-1],v[_i])]
)
);

View file

@ -515,7 +515,7 @@ module path_extrude2d(path, caps=true) {
}
}
for (t=triplet(path)) {
ang = vang(t[2]-t[1]) - vang(t[1]-t[0]);
ang = v_theta(t[2]-t[1]) - v_theta(t[1]-t[0]);
delt = t[2] - t[1];
translate(t[1]) {
minkowski() {

View file

@ -44,7 +44,7 @@ function _partition_cutpath(l, h, cutsize, cutpath, gap) =
cplen = (cutsize.x+gap) * reps,
path = deduplicate(concat(
[[-l/2, cutpath[0].y*cutsize.y]],
[for (i=[0:1:reps-1], pt=cutpath) vmul(pt,cutsize)+[i*(cutsize.x+gap)+gap/2-cplen/2,0]],
[for (i=[0:1:reps-1], pt=cutpath) v_mul(pt,cutsize)+[i*(cutsize.x+gap)+gap/2-cplen/2,0]],
[[ l/2, cutpath[len(cutpath)-1].y*cutsize.y]]
))
) path;
@ -164,7 +164,7 @@ module partition(size=100, spread=10, cutsize=10, cutpath=undef, gap=0, spin=0)
{
size = is_vector(size)? size : [size,size,size];
cutsize = is_vector(cutsize)? cutsize : [cutsize*2, cutsize];
rsize = vabs(rot(spin,p=size));
rsize = v_abs(rot(spin,p=size));
vec = rot(spin,p=BACK)*spread/2;
move(vec) {
intersection() {

View file

@ -377,7 +377,7 @@ function _point_ref(points, sign="both") =
unique([
for(i=[-1,1],j=[-1,1],k=[-1,1])
if (sign=="both" || sign=="even" && i*j*k>0 || sign=="odd" && i*j*k<0)
each [for(point=points) vmul(point,[i,j,k])]
each [for(point=points) v_mul(point,[i,j,k])]
]);
//
_tribonacci=(1+4*cosh(acosh(2+3/8)/3))/3;

View file

@ -139,7 +139,7 @@ function cube(size=1, center, anchor, spin=0, orient=UP) =
[-1,-1, 1],[1,-1, 1],[1,1, 1],[-1,1, 1],
]/2,
verts = is_num(size)? unscaled * size :
is_vector(size,3)? [for (p=unscaled) vmul(p,size)] :
is_vector(size,3)? [for (p=unscaled) v_mul(p,size)] :
assert(is_num(size) || is_vector(size,3)),
faces = [
[0,1,2], [0,2,3], //BOTTOM

View file

@ -111,9 +111,9 @@ module cuboid(
cnt = sum(e);
r = first_defined([chamfer, rounding, 0]);
c = [min(r,size.x/2), min(r,size.y/2), min(r,size.z/2)];
c2 = vmul(corner,c/2);
c2 = v_mul(corner,c/2);
$fn = is_finite(chamfer)? 4 : segs(r);
translate(vmul(corner, size/2-c)) {
translate(v_mul(corner, size/2-c)) {
if (cnt == 0 || approx(r,0)) {
translate(c2) cube(c, center=true);
} else if (cnt == 1) {
@ -163,7 +163,7 @@ module cuboid(
if (!is_undef(p1)) {
if (!is_undef(p2)) {
translate(pointlist_bounds([p1,p2])[0]) {
cuboid(size=vabs(p2-p1), chamfer=chamfer, rounding=rounding, edges=edges, trimcorners=trimcorners, anchor=ALLNEG) children();
cuboid(size=v_abs(p2-p1), chamfer=chamfer, rounding=rounding, edges=edges, trimcorners=trimcorners, anchor=ALLNEG) children();
}
} else {
translate(p1) {
@ -209,7 +209,7 @@ module cuboid(
for (i = [0:3], axis=[0:1]) {
if (edges[axis][i]>0) {
vec = EDGE_OFFSETS[axis][i];
translate(vmul(vec/2, size+[ach,ach,-ach])) {
translate(v_mul(vec/2, size+[ach,ach,-ach])) {
rotate(majrots[axis]) {
cube([ach, ach, size[axis]], center=true);
}
@ -222,7 +222,7 @@ module cuboid(
for (za=[-1,1], ya=[-1,1], xa=[-1,1]) {
ce = corner_edges(edges, [xa,ya,za]);
if (ce.x + ce.y > 1) {
translate(vmul([xa,ya,za]/2, size+[ach-0.01,ach-0.01,-ach])) {
translate(v_mul([xa,ya,za]/2, size+[ach-0.01,ach-0.01,-ach])) {
cube([ach+0.01,ach+0.01,ach], center=true);
}
}
@ -234,7 +234,7 @@ module cuboid(
for (i = [0:3], axis=[0:1]) {
if (edges[axis][i]>0) {
vec = EDGE_OFFSETS[axis][i];
translate(vmul(vec/2, size+[2*ach,2*ach,-2*ach])) {
translate(v_mul(vec/2, size+[2*ach,2*ach,-2*ach])) {
rotate(majrots[axis]) {
zrot(45) cube([ach*sqrt(2), ach*sqrt(2), size[axis]+2.1*ach], center=true);
}
@ -296,7 +296,7 @@ module cuboid(
for (i = [0:3], axis=[0:1]) {
if (edges[axis][i]>0) {
vec = EDGE_OFFSETS[axis][i];
translate(vmul(vec/2, size+[ard,ard,-ard])) {
translate(v_mul(vec/2, size+[ard,ard,-ard])) {
rotate(majrots[axis]) {
cube([ard, ard, size[axis]], center=true);
}
@ -309,7 +309,7 @@ module cuboid(
for (za=[-1,1], ya=[-1,1], xa=[-1,1]) {
ce = corner_edges(edges, [xa,ya,za]);
if (ce.x + ce.y > 1) {
translate(vmul([xa,ya,za]/2, size+[ard-0.01,ard-0.01,-ard])) {
translate(v_mul([xa,ya,za]/2, size+[ard-0.01,ard-0.01,-ard])) {
cube([ard+0.01,ard+0.01,ard], center=true);
}
}
@ -321,7 +321,7 @@ module cuboid(
for (i = [0:3], axis=[0:1]) {
if (edges[axis][i]>0) {
vec = EDGE_OFFSETS[axis][i];
translate(vmul(vec/2, size+[2*ard,2*ard,-2*ard])) {
translate(v_mul(vec/2, size+[2*ard,2*ard,-2*ard])) {
rotate(majrots[axis]) {
cyl(l=size[axis]+2.1*ard, r=ard);
}
@ -521,8 +521,8 @@ function prismoid(
let(
corners = [[1,1],[1,-1],[-1,-1],[-1,1]] * 0.5,
points = [
for (p=corners) point3d(vmul(s2,p), +h/2) + shiftby,
for (p=corners) point3d(vmul(s1,p), -h/2)
for (p=corners) point3d(v_mul(s2,p), +h/2) + shiftby,
for (p=corners) point3d(v_mul(s1,p), -h/2)
],
faces=[
[0,1,2], [0,2,3], [0,4,5], [0,5,1],

View file

@ -959,7 +959,7 @@ function rect(size=1, center, rounding=0, chamfer=0, anchor, spin=0) =
[-size.x/2, size.y/2],
[ size.x/2, size.y/2]
]
) rot(spin, p=move(-vmul(anchor,size/2), p=path)) :
) rot(spin, p=move(-v_mul(anchor,size/2), p=path)) :
let(
chamfer = is_list(chamfer)? chamfer : [for (i=[0:3]) chamfer],
rounding = is_list(rounding)? rounding : [for (i=[0:3]) rounding],
@ -978,7 +978,7 @@ function rect(size=1, center, rounding=0, chamfer=0, anchor, spin=0) =
quad = quadorder[i],
inset = insets[quad],
cverts = quant(segs(inset),4)/4,
cp = vmul(size/2-[inset,inset], quadpos[quad]),
cp = v_mul(size/2-[inset,inset], quadpos[quad]),
step = 90/cverts,
angs =
chamfer[quad] > 0? [0,-90]-90*[i,i] :

View file

@ -111,7 +111,7 @@ module test_scale() {
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));
assert_equal(scale(val, p=[1,2,3]), v_mul([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]]);
@ -122,7 +122,7 @@ module test_scale() {
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)]]);
assert_equal(scale([-2,-3,-4], p=cb), [[for (p=cb[0]) v_mul(p,[-2,-3,-4])], [for (f=cb[1]) reverse(f)]]);
// Verify that module at least doesn't crash.
scale(-5) scale(5) nil();
}
@ -289,7 +289,7 @@ module test_rot() {
for (vec2 = vecs2d) {
assert_equal(
rot(from=vec1, to=vec2, p=pts2d, planar=true),
apply(affine2d_zrot(vang(vec2)-vang(vec1)), pts2d),
apply(affine2d_zrot(v_theta(vec2)-v_theta(vec1)), pts2d),
info=str(
"from = ", vec1, ", ",
"to = ", vec2, ", ",

View file

@ -32,66 +32,67 @@ module test_is_vector() {
test_is_vector();
module test_vfloor() {
assert_equal(vfloor([2.0, 3.14, 18.9, 7]), [2,3,18,7]);
assert_equal(vfloor([-2.0, -3.14, -18.9, -7]), [-2,-4,-19,-7]);
module test_v_floor() {
assert_equal(v_floor([2.0, 3.14, 18.9, 7]), [2,3,18,7]);
assert_equal(v_floor([-2.0, -3.14, -18.9, -7]), [-2,-4,-19,-7]);
}
test_vfloor();
test_v_floor();
module test_vceil() {
assert_equal(vceil([2.0, 3.14, 18.9, 7]), [2,4,19,7]);
assert_equal(vceil([-2.0, -3.14, -18.9, -7]), [-2,-3,-18,-7]);
module test_v_ceil() {
assert_equal(v_ceil([2.0, 3.14, 18.9, 7]), [2,4,19,7]);
assert_equal(v_ceil([-2.0, -3.14, -18.9, -7]), [-2,-3,-18,-7]);
}
test_vceil();
test_v_ceil();
module test_vmul() {
assert_equal(vmul([3,4,5], [8,7,6]), [24,28,30]);
assert_equal(vmul([1,2,3], [4,5,6]), [4,10,18]);
assert_equal(vmul([[1,2,3],[4,5,6],[7,8,9]], [[4,5,6],[3,2,1],[5,9,3]]), [32,28,134]);
module test_v_mul() {
assert_equal(v_mul([3,4,5], [8,7,6]), [24,28,30]);
assert_equal(v_mul([1,2,3], [4,5,6]), [4,10,18]);
assert_equal(v_mul([[1,2,3],[4,5,6],[7,8,9]], [[4,5,6],[3,2,1],[5,9,3]]), [32,28,134]);
}
test_vmul();
test_v_mul();
module test_vdiv() {
assert(vdiv([24,28,30], [8,7,6]) == [3, 4, 5]);
module test_v_div() {
assert(v_div([24,28,30], [8,7,6]) == [3, 4, 5]);
}
test_vdiv();
test_v_div();
module test_vabs() {
assert(vabs([2,4,8]) == [2,4,8]);
assert(vabs([-2,-4,-8]) == [2,4,8]);
assert(vabs([-2,4,8]) == [2,4,8]);
assert(vabs([2,-4,8]) == [2,4,8]);
assert(vabs([2,4,-8]) == [2,4,8]);
module test_v_abs() {
assert(v_abs([2,4,8]) == [2,4,8]);
assert(v_abs([-2,-4,-8]) == [2,4,8]);
assert(v_abs([-2,4,8]) == [2,4,8]);
assert(v_abs([2,-4,8]) == [2,4,8]);
assert(v_abs([2,4,-8]) == [2,4,8]);
}
test_vabs();
test_v_abs();
include <../strings.scad>
module test_vang() {
assert(vang([1,0])==0);
assert(vang([0,1])==90);
assert(vang([-1,0])==180);
assert(vang([0,-1])==-90);
assert(vang([1,1])==45);
assert(vang([-1,1])==135);
assert(vang([1,-1])==-45);
assert(vang([-1,-1])==-135);
assert(vang([0,0,1])==[0,90]);
assert(vang([0,1,1])==[90,45]);
assert(vang([0,1,-1])==[90,-45]);
assert(vang([1,0,0])==[0,0]);
assert(vang([0,1,0])==[90,0]);
assert(vang([0,-1,0])==[-90,0]);
assert(vang([-1,0,0])==[180,0]);
assert(vang([1,0,1])==[0,45]);
assert(vang([0,1,1])==[90,45]);
assert(vang([0,-1,1])==[-90,45]);
assert(approx(vang([1,1,1]),[45, 35.2643896828]));
module test_v_theta() {
assert_approx(v_theta([0,0]), 0);
assert_approx(v_theta([1,0]), 0);
assert_approx(v_theta([0,1]), 90);
assert_approx(v_theta([-1,0]), 180);
assert_approx(v_theta([0,-1]), -90);
assert_approx(v_theta([1,1]), 45);
assert_approx(v_theta([-1,1]), 135);
assert_approx(v_theta([1,-1]), -45);
assert_approx(v_theta([-1,-1]), -135);
assert_approx(v_theta([0,0,1]), 0);
assert_approx(v_theta([0,1,1]), 90);
assert_approx(v_theta([0,1,-1]), 90);
assert_approx(v_theta([1,0,0]), 0);
assert_approx(v_theta([0,1,0]), 90);
assert_approx(v_theta([0,-1,0]), -90);
assert_approx(v_theta([-1,0,0]), 180);
assert_approx(v_theta([1,0,1]), 0);
assert_approx(v_theta([0,1,1]), 90);
assert_approx(v_theta([0,-1,1]), -90);
assert_approx(v_theta([1,1,1]), 45);
}
test_vang();
test_v_theta();
module test_unit() {

View file

@ -414,8 +414,8 @@ function rot(a=0, v, cp, from, to, reverse=false, planar=false, p, _m) =
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(
vang(point2d(to)) -
vang(point2d(from))
v_theta(to) -
v_theta(from)
),
m2 = is_undef(cp)? m1 : (move(cp) * m1 * move(-cp)),
m3 = reverse? matrix_inverse(m2) : m2

View file

@ -693,7 +693,7 @@ function _turtle3d_list_command(command,arcsteps,movescale, lastT,lastPre,index)
assert(is_vector(grow,2), str("Parameter to \"grow\" must be a scalar or 2d vector at index ",index))
assert(is_vector(shrink,2), str("Parameter to \"shrink\" must be a scalar or 2d vector at index ",index))
let(
scaling = point3d(vdiv(grow,shrink),1),
scaling = point3d(v_div(grow,shrink),1),
usersteps = struct_val(keys,"steps"),
roll = struct_val(keys,"roll"),
////////////////////////////////////////////////////////////////////////////////////////

View file

@ -11,7 +11,7 @@
// Function: is_vector()
// Usage:
// is_vector(v, [length]);
// is_vector(v, <length>, ...);
// Description:
// Returns true if v is a list of finite numbers.
// Arguments:
@ -42,20 +42,17 @@ function is_vector(v, length, zero, all_nonzero=false, eps=EPSILON) =
&& (!all_nonzero || all_nonzero(v)) ;
// Function: vang()
// Function: v_theta()
// Usage:
// theta = vang([X,Y]);
// theta_phi = vang([X,Y,Z]);
// theta = v_theta([X,Y]);
// Description:
// Given a 2D vector, returns the angle in degrees counter-clockwise from X+ on the XY plane.
// Given a 3D vector, returns [THETA,PHI] where THETA is the number of degrees counter-clockwise from X+ on the XY plane, and PHI is the number of degrees up from the X+ axis along the XZ plane.
function vang(v) =
// Given a vector, returns the angle in degrees counter-clockwise from X+ on the XY plane.
function v_theta(v) =
assert( is_vector(v,2) || is_vector(v,3) , "Invalid vector")
len(v)==2? atan2(v.y,v.x) :
let(res=xyz_to_spherical(v)) [res[1], 90-res[2]];
atan2(v.y,v.x);
// Function: vmul()
// Function: v_mul()
// Description:
// Element-wise multiplication. Multiplies each element of `v1` by the corresponding element of `v2`.
// Both `v1` and `v2` must be the same length. Returns a vector of the products.
@ -63,13 +60,13 @@ function vang(v) =
// v1 = The first vector.
// v2 = The second vector.
// Example:
// vmul([3,4,5], [8,7,6]); // Returns [24, 28, 30]
function vmul(v1, v2) =
// v_mul([3,4,5], [8,7,6]); // Returns [24, 28, 30]
function v_mul(v1, v2) =
assert( is_list(v1) && is_list(v2) && len(v1)==len(v2), "Incompatible input")
[for (i = [0:1:len(v1)-1]) v1[i]*v2[i]];
// Function: vdiv()
// Function: v_div()
// Description:
// Element-wise vector division. Divides each element of vector `v1` by
// the corresponding element of vector `v2`. Returns a vector of the quotients.
@ -77,35 +74,35 @@ function vmul(v1, v2) =
// v1 = The first vector.
// v2 = The second vector.
// Example:
// vdiv([24,28,30], [8,7,6]); // Returns [3, 4, 5]
function vdiv(v1, v2) =
// v_div([24,28,30], [8,7,6]); // Returns [3, 4, 5]
function v_div(v1, v2) =
assert( is_vector(v1) && is_vector(v2,len(v1)), "Incompatible vectors")
[for (i = [0:1:len(v1)-1]) v1[i]/v2[i]];
// Function: vabs()
// Function: v_abs()
// Description: Returns a vector of the absolute value of each element of vector `v`.
// Arguments:
// v = The vector to get the absolute values of.
// Example:
// vabs([-1,3,-9]); // Returns: [1,3,9]
function vabs(v) =
// v_abs([-1,3,-9]); // Returns: [1,3,9]
function v_abs(v) =
assert( is_vector(v), "Invalid vector" )
[for (x=v) abs(x)];
// Function: vfloor()
// Function: v_floor()
// Description:
// Returns the given vector after performing a `floor()` on all items.
function vfloor(v) =
function v_floor(v) =
assert( is_vector(v), "Invalid vector" )
[for (x=v) floor(x)];
// Function: vceil()
// Function: v_ceil()
// Description:
// Returns the given vector after performing a `ceil()` on all items.
function vceil(v) =
function v_ceil(v) =
assert( is_vector(v), "Invalid vector" )
[for (x=v) ceil(x)];
@ -213,7 +210,7 @@ function vector_axis(v1,v2=undef,v3=undef) =
w1 = point3d(v1/norm(v1)),
w2 = point3d(v2/norm(v2)),
w3 = (norm(w1-w2) > eps && norm(w1+w2) > eps) ? w2
: (norm(vabs(w2)-UP) > eps)? UP
: (norm(v_abs(w2)-UP) > eps)? UP
: RIGHT
) unit(cross(w1,w3));