From 598ae04ba54c786c91e9c1ea641c11268b08187c Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Sun, 19 Jul 2020 05:39:49 -0700 Subject: [PATCH 1/9] Tighten image comparison requirements. --- scripts/docs_gen.py | 2 +- version.scad | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/docs_gen.py b/scripts/docs_gen.py index d2f819c..b1131d3 100755 --- a/scripts/docs_gen.py +++ b/scripts/docs_gen.py @@ -97,7 +97,7 @@ def image_compare(file1, file2): sq = (value * (i % 256) ** 2 for i, value in enumerate(diff)) sum_squares = sum(sq) rms = math.sqrt(sum_squares / float(img1.size[0] * img1.size[1])) - return rms<10 + return rms<2 def image_resize(infile, outfile, newsize=(320,240)): diff --git a/version.scad b/version.scad index eda7210..b15931a 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,391]; +BOSL_VERSION = [2,0,392]; // Section: BOSL Library Version Functions From 14e013cd13529bfcffec47a7354acdaae4bcc6f0 Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Sun, 19 Jul 2020 05:49:05 -0700 Subject: [PATCH 2/9] Bugfix for unit() changes in attachment --- attachments.scad | 2 +- version.scad | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/attachments.scad b/attachments.scad index 1c4b19a..1e7a9fb 100644 --- a/attachments.scad +++ b/attachments.scad @@ -421,7 +421,7 @@ function find_anchor(anchor, geom) = top = point3d(vmul(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 = anchor==CENTER? UP : unit([0,0,anchor.z]), + vvec = anchor==CENTER? UP : unit([0,0,anchor.z],UP), vec = anchor==CENTER? UP : approx(axy,[0,0])? unit(anchor,UP) : approx(anchor.z,0)? sidevec : diff --git a/version.scad b/version.scad index b15931a..073f188 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,392]; +BOSL_VERSION = [2,0,393]; // Section: BOSL Library Version Functions From 87c8adef659be38ec93fc835d2d319806433ecec Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Sun, 19 Jul 2020 06:24:16 -0700 Subject: [PATCH 3/9] Bad use of unit() in debug_polyhedron() --- debug.scad | 17 +++++++++-------- version.scad | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/debug.scad b/debug.scad index 3ff5704..ada55e8 100644 --- a/debug.scad +++ b/debug.scad @@ -191,16 +191,17 @@ module debug_faces(vertices, faces, size=1, disabled=false) { 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); } else { - v0 = vertices[face[0]]; - v1 = vertices[face[1]]; - v2 = vertices[face[2]]; - c = mean(select(vertices,face)); + verts = select(vertices,face); + c = mean(verts); + v0 = verts[0]; + v1 = verts[1]; + v2 = verts[2]; dv0 = unit(v1 - v0); dv1 = unit(v2 - v0); - nrm0 = unit(cross(dv0, dv1)); - nrm1 = [0, 0, 1]; - axis = unit(cross(nrm0, nrm1)); - ang = vector_angle(nrm0, nrm1); + nrm0 = cross(dv0, dv1); + nrm1 = UP; + axis = vector_axis(nrm0, nrm1); + ang = vector_angle(nrm0, nrm1); theta = atan2(nrm0[1], nrm0[0]); translate(c) { rotate(a=180-ang, v=axis) { diff --git a/version.scad b/version.scad index 073f188..b26cd44 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,393]; +BOSL_VERSION = [2,0,394]; // Section: BOSL Library Version Functions From 806a0cf2b5bd2f0201afcf12114a6e4333a3e5e9 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sun, 19 Jul 2020 11:48:31 -0400 Subject: [PATCH 4/9] Various doc fixes --- rounding.scad | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/rounding.scad b/rounding.scad index 6f2a065..8d6e2c6 100644 --- a/rounding.scad +++ b/rounding.scad @@ -159,6 +159,7 @@ include // fwd(60) // Note how the different points are cut back by different amounts // stroke(round_corners(zig,radius=1.5,closed=false),width=1); // Example(FlatSpin): Rounding some random 3D paths +// $fn=36; // list1= [ // [2.887360, 4.03497, 6.372090], // [5.682210, 9.37103, 0.783548], @@ -926,10 +927,10 @@ function os_profile(points, extra,check_valid, quality, offset_maxstep, offset) // // Example: Chamfered elliptical prism. If you stretch a chamfered cylinder the chamfer will be uneven. // convex_offset_extrude(bottom = os_chamfer(height=-2), top=os_chamfer(height=1), height=7) -// xscale(4)circle(r=6); +// xscale(4)circle(r=6,$fn=64); // Example: Elliptical prism with circular roundovers. // convex_offset_extrude(bottom=os_circle(r=-2), top=os_circle(r=1), height=7,steps=10) -// xscale(4)circle(r=6); +// xscale(4)circle(r=6,$fn=64); // Example: If you give a non-convex input you get a convex hull output // right(50) linear_extrude(height=7) star(5,r=22,ir=13); // convex_offset_extrude(bottom = os_chamfer(height=-2), top=os_chamfer(height=1), height=7) @@ -1122,6 +1123,7 @@ function _remove_undefined_vals(list) = // fwd(7) // offset_stroke(arc, width=2, start=os_pointed(loc=2,dist=2),end=os_pointed(loc=.5,dist=-1)); // Example(2D): The os_round() end treatment adds roundovers to the end corners by specifying the `cut` parameter. In the first example, the cut parameter is the same at each corner. The bezier smoothness parameter `k` is given to allow a larger cut. In the second example, each corner is given a different roundover, including zero for no rounding at all. The red shows the same strokes without the roundover. +// $fn=36; // arc = arc(points=[[1,1],[3,4],[6,3]],N=50); // path = [[0,0],[6,2],[9,7],[8,10]]; // offset_stroke(path, width=2, rounded=false,start=os_round(angle=-20, cut=0.4,k=.9), end=os_round(angle=-35, cut=0.4,k=.9)); @@ -1133,9 +1135,9 @@ function _remove_undefined_vals(list) = // Example(2D): Negative cut values produce a flaring end. Note how the absolute angle aligns the ends of the first example withi the axes. In the second example positive and negative cut values are combined. Note also that very different cuts are needed at the start end to produce a similar looking flare. // arc = arc(points=[[1,1],[3,4],[6,3]],N=50); // path = [[0,0],[6,2],[9,7],[8,10]]; -// offset_stroke(path, width=2, rounded=false,start=os_round(cut=-1, abs_angle=90), end=os_round(cut=-0.5, abs_angle=0)); +// offset_stroke(path, width=2, rounded=false,start=os_round(cut=-1, abs_angle=90), end=os_round(cut=-0.5, abs_angle=0),$fn=36); // right(10) -// offset_stroke(arc, width=2, rounded=false, start=os_round(cut=[-.75,-.2], angle=-45), end=os_round(cut=[-.2,.2], angle=20)); +// offset_stroke(arc, width=2, rounded=false, start=os_round(cut=[-.75,-.2], angle=-45), end=os_round(cut=[-.2,.2], angle=20),$fn=36); // Example(2D): Setting the width to a vector allows generation of a set of parallel strokes // path = [[0,0],[4,4],[8,4],[2,9],[10,10]]; // for(i=[0:.25:2]) @@ -1146,9 +1148,9 @@ function _remove_undefined_vals(list) = // offset_stroke(path, rounded=true,width = [i,i+.08]); // Example(2D): In this example a spurious triangle appears. This results from overly enthusiastic validity checking. Turning validity checking off fixes it in this case. // path = [[0,0],[4,4],[8,4],[2,9],[10,10]]; -// offset_stroke(path, check_valid=true,rounded=false,width = [1.4, 1.45]); +// offset_stroke(path, check_valid=true,rounded=false,width = [1.4, 1.5]); // right(2) -// offset_stroke(path, check_valid=false,rounded=false,width = [1.4, 1.45]); +// offset_stroke(path, check_valid=false,rounded=false,width = [1.4, 1.5]); // Example(2D): But in this case, disabling the validity check produces an invalid result. // path = [[0,0],[4,4],[8,4],[2,9],[10,10]]; // offset_stroke(path, check_valid=true,rounded=false,width = [1.9, 2]); @@ -1786,7 +1788,7 @@ function _circle_mask(r) = // less than 180 degrees, and the path shouldn't have closely spaced points at concave points of high curvature because // this will cause self-intersection in the mask polyhedron, resulting in CGAL failures. // Arguments: -// r|radius = center radius of the cylindrical shell to cut a hole in +// r / radius = center radius of the cylindrical shell to cut a hole in // thickness = thickness of cylindrical shell (may need to be slighly oversized) // path = 2d path that defines the hole to cut // Example: The mask as long pointed ends because this was the most efficient way to close off those ends. From 375f1f2e3bf30ae0f68c011217ec42a33979afed Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Sun, 19 Jul 2020 23:05:54 -0700 Subject: [PATCH 5/9] Bugfix for new unit() in affine_frame_map() --- affine.scad | 6 +++--- version.scad | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/affine.scad b/affine.scad index 4a1a7ff..b39529f 100644 --- a/affine.scad +++ b/affine.scad @@ -277,9 +277,9 @@ function affine_frame_map(x,y,z, reverse=false) = assert(yvalid,"Input y must be a length 3 vector") assert(zvalid,"Input z must be a length 3 vector") let( - x = is_undef(x)? undef : unit(x), - y = is_undef(y)? undef : unit(y), - z = is_undef(z)? undef : unit(z), + x = is_undef(x)? undef : unit(x,RIGHT), + y = is_undef(y)? undef : unit(y,BACK), + z = is_undef(z)? undef : unit(z,UP), map = is_undef(x)? [cross(y,z), y, z] : is_undef(y)? [x, cross(z,x), z] : is_undef(z)? [x, y, cross(x,y)] : diff --git a/version.scad b/version.scad index b26cd44..5ce4534 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,394]; +BOSL_VERSION = [2,0,395]; // Section: BOSL Library Version Functions From ae1a6d8d6137d2143b1dbc7f2eca7da6f4adbbbe Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Sun, 19 Jul 2020 23:07:49 -0700 Subject: [PATCH 6/9] Rewrote line_closest_point() and segment_closest_point() to support 3D. Added ray_closest_point(). --- geometry.scad | 185 ++++++++++++++++++++++++++++++++++++++++++++++---- version.scad | 2 +- 2 files changed, 173 insertions(+), 14 deletions(-) diff --git a/geometry.scad b/geometry.scad index b5f4c29..62dd436 100644 --- a/geometry.scad +++ b/geometry.scad @@ -133,8 +133,9 @@ function distance_from_line(line, pt) = // color("green") stroke([p1,p1+10*n], endcap2="arrow2"); // color("blue") move_copies([p1,p2]) circle(d=2, $fn=12); function line_normal(p1,p2) = - is_undef(p2)? line_normal(p1[0],p1[1]) : - unit([p1.y-p2.y,p2.x-p1.x]); + is_undef(p2)? + assert(is_path(p1,2)) line_normal(p1[0],p1[1]) : + assert(is_vector(p1,2)&&is_vector(p2,2)) unit([p1.y-p2.y,p2.x-p1.x]); // 2D Line intersection from two segments. @@ -252,34 +253,192 @@ function segment_intersection(s1,s2,eps=EPSILON) = // Usage: // line_closest_point(line,pt); // Description: -// Returns the point on the given `line` that is closest to the given point `pt`. +// Returns the point on the given 2D or 3D `line` that is closest to the given point `pt`. +// The `line` and `pt` args should either both be 2D or both 3D. // Arguments: // line = A list of two points that are on the unbounded line. // pt = The point to find the closest point on the line to. +// Example(2D): +// line = [[-30,0],[30,30]]; +// pt = [-32,-10]; +// p2 = line_closest_point(line,pt); +// stroke(line, endcaps="arrow2"); +// color("blue") translate(pt) circle(r=1,$fn=12); +// color("red") translate(p2) circle(r=1,$fn=12); +// Example(2D): +// line = [[-30,0],[30,30]]; +// pt = [-5,0]; +// p2 = line_closest_point(line,pt); +// stroke(line, endcaps="arrow2"); +// color("blue") translate(pt) circle(r=1,$fn=12); +// color("red") translate(p2) circle(r=1,$fn=12); +// Example(2D): +// line = [[-30,0],[30,30]]; +// pt = [40,25]; +// p2 = line_closest_point(line,pt); +// stroke(line, endcaps="arrow2"); +// color("blue") translate(pt) circle(r=1,$fn=12); +// color("red") translate(p2) circle(r=1,$fn=12); +// Example(FlatSpin): +// line = [[-30,-15,0],[30,15,30]]; +// pt = [5,5,5]; +// p2 = line_closest_point(line,pt); +// stroke(line, endcaps="arrow2"); +// color("blue") translate(pt) sphere(r=1,$fn=12); +// color("red") translate(p2) sphere(r=1,$fn=12); +// Example(FlatSpin): +// line = [[-30,-15,0],[30,15,30]]; +// pt = [-35,-15,0]; +// p2 = line_closest_point(line,pt); +// stroke(line, endcaps="arrow2"); +// color("blue") translate(pt) sphere(r=1,$fn=12); +// color("red") translate(p2) sphere(r=1,$fn=12); +// Example(FlatSpin): +// line = [[-30,-15,0],[30,15,30]]; +// pt = [40,15,25]; +// p2 = line_closest_point(line,pt); +// stroke(line, endcaps="arrow2"); +// color("blue") translate(pt) sphere(r=1,$fn=12); +// color("red") translate(p2) sphere(r=1,$fn=12); function line_closest_point(line,pt) = + assert(is_path(line)&&len(line)==2) + assert(same_shape(pt,line[0])) + assert(!approx(line[0],line[1])) let( - n = line_normal(line), - isect = _general_line_intersection(line,[pt,pt+n]) - ) isect[0]; + seglen = norm(line[1]-line[0]), + segvec = (line[1]-line[0])/seglen, + projection = (pt-line[0]) * segvec + ) + line[0] + projection*segvec; + + +// Function: ray_closest_point() +// Usage: +// ray_closest_point(seg,pt); +// Description: +// Returns the point on the given 2D or 3D ray `ray` that is closest to the given point `pt`. +// The `ray` and `pt` args should either both be 2D or both 3D. +// Arguments: +// ray = The ray, given as a list `[START,POINT]` of the start-point START, and a point POINT on the ray. +// pt = The point to find the closest point on the ray to. +// Example(2D): +// ray = [[-30,0],[30,30]]; +// pt = [-32,-10]; +// p2 = ray_closest_point(ray,pt); +// stroke(ray, endcap2="arrow2"); +// color("blue") translate(pt) circle(r=1,$fn=12); +// color("red") translate(p2) circle(r=1,$fn=12); +// Example(2D): +// ray = [[-30,0],[30,30]]; +// pt = [-5,0]; +// p2 = ray_closest_point(ray,pt); +// stroke(ray, endcap2="arrow2"); +// color("blue") translate(pt) circle(r=1,$fn=12); +// color("red") translate(p2) circle(r=1,$fn=12); +// Example(2D): +// ray = [[-30,0],[30,30]]; +// pt = [40,25]; +// p2 = ray_closest_point(ray,pt); +// stroke(ray, endcap2="arrow2"); +// color("blue") translate(pt) circle(r=1,$fn=12); +// color("red") translate(p2) circle(r=1,$fn=12); +// Example(FlatSpin): +// ray = [[-30,-15,0],[30,15,30]]; +// pt = [5,5,5]; +// p2 = ray_closest_point(ray,pt); +// stroke(ray, endcap2="arrow2"); +// color("blue") translate(pt) sphere(r=1,$fn=12); +// color("red") translate(p2) sphere(r=1,$fn=12); +// Example(FlatSpin): +// ray = [[-30,-15,0],[30,15,30]]; +// pt = [-35,-15,0]; +// p2 = ray_closest_point(ray,pt); +// stroke(ray, endcap2="arrow2"); +// color("blue") translate(pt) sphere(r=1,$fn=12); +// color("red") translate(p2) sphere(r=1,$fn=12); +// Example(FlatSpin): +// ray = [[-30,-15,0],[30,15,30]]; +// pt = [40,15,25]; +// p2 = ray_closest_point(ray,pt); +// stroke(ray, endcap2="arrow2"); +// color("blue") translate(pt) sphere(r=1,$fn=12); +// color("red") translate(p2) sphere(r=1,$fn=12); +function ray_closest_point(ray,pt) = + assert(is_path(ray)&&len(ray)==2) + assert(same_shape(pt,ray[0])) + assert(!approx(ray[0],ray[1])) + let( + seglen = norm(ray[1]-ray[0]), + segvec = (ray[1]-ray[0])/seglen, + projection = (pt-ray[0]) * segvec + ) + projection<=0 ? ray[0] : + ray[0] + projection*segvec; // Function: segment_closest_point() // Usage: // segment_closest_point(seg,pt); // Description: -// Returns the point on the given line segment `seg` that is closest to the given point `pt`. +// Returns the point on the given 2D or 3D line segment `seg` that is closest to the given point `pt`. +// The `seg` and `pt` args should either both be 2D or both 3D. // Arguments: // seg = A list of two points that are the endpoints of the bounded line segment. // pt = The point to find the closest point on the segment to. +// Example(2D): +// seg = [[-30,0],[30,30]]; +// pt = [-32,-10]; +// p2 = segment_closest_point(seg,pt); +// stroke(seg); +// color("blue") translate(pt) circle(r=1,$fn=12); +// color("red") translate(p2) circle(r=1,$fn=12); +// Example(2D): +// seg = [[-30,0],[30,30]]; +// pt = [-5,0]; +// p2 = segment_closest_point(seg,pt); +// stroke(seg); +// color("blue") translate(pt) circle(r=1,$fn=12); +// color("red") translate(p2) circle(r=1,$fn=12); +// Example(2D): +// seg = [[-30,0],[30,30]]; +// pt = [40,25]; +// p2 = segment_closest_point(seg,pt); +// stroke(seg); +// color("blue") translate(pt) circle(r=1,$fn=12); +// color("red") translate(p2) circle(r=1,$fn=12); +// Example(FlatSpin): +// seg = [[-30,-15,0],[30,15,30]]; +// pt = [5,5,5]; +// p2 = segment_closest_point(seg,pt); +// stroke(seg); +// color("blue") translate(pt) sphere(r=1,$fn=12); +// color("red") translate(p2) sphere(r=1,$fn=12); +// Example(FlatSpin): +// seg = [[-30,-15,0],[30,15,30]]; +// pt = [-35,-15,0]; +// p2 = segment_closest_point(seg,pt); +// stroke(seg); +// color("blue") translate(pt) sphere(r=1,$fn=12); +// color("red") translate(p2) sphere(r=1,$fn=12); +// Example(FlatSpin): +// seg = [[-30,-15,0],[30,15,30]]; +// pt = [40,15,25]; +// p2 = segment_closest_point(seg,pt); +// stroke(seg); +// color("blue") translate(pt) sphere(r=1,$fn=12); +// color("red") translate(p2) sphere(r=1,$fn=12); function segment_closest_point(seg,pt) = + assert(is_path(seg)&&len(seg)==2) + assert(same_shape(pt,seg[0])) + approx(seg[0],seg[1])? seg[0] : let( - n = line_normal(seg), - isect = _general_line_intersection(seg,[pt,pt+n]) + seglen = norm(seg[1]-seg[0]), + segvec = (seg[1]-seg[0])/seglen, + projection = (pt-seg[0]) * segvec ) - norm(n)==0? seg[0] : - isect[1]<=0? seg[0] : - isect[1]>=1? seg[1] : - isect[0]; + projection<=0 ? seg[0] : + projection>=seglen ? seg[1] : + seg[0] + projection*segvec; // Section: 2D Triangles diff --git a/version.scad b/version.scad index 5ce4534..4ba73cf 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,395]; +BOSL_VERSION = [2,0,396]; // Section: BOSL Library Version Functions From 4a37a5dc8ef661ef6334999937a0f67686b0d9ed Mon Sep 17 00:00:00 2001 From: Garth Minette Date: Tue, 21 Jul 2020 16:15:02 -0700 Subject: [PATCH 7/9] Added zero=undef/true/false arg to is_vector. Bugfix for vector_axis() --- tests/test_vectors.scad | 4 ++++ vectors.scad | 51 +++++++++++++++++++++++++++-------------- version.scad | 2 +- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/tests/test_vectors.scad b/tests/test_vectors.scad index 399be01..6651c46 100644 --- a/tests/test_vectors.scad +++ b/tests/test_vectors.scad @@ -9,6 +9,10 @@ module test_is_vector() { assert(is_vector(1) == false); assert(is_vector("foo") == false); assert(is_vector(true) == false); + assert(is_vector([0,0,0],zero=true) == true); + assert(is_vector([0,0,0],zero=false) == false); + assert(is_vector([0,1,0],zero=true) == false); + assert(is_vector([0,0,1],zero=false) == true); } test_is_vector(); diff --git a/vectors.scad b/vectors.scad index 0030160..bb28ead 100644 --- a/vectors.scad +++ b/vectors.scad @@ -19,6 +19,8 @@ // Arguments: // v = The value to test to see if it is a vector. // length = If given, make sure the vector is `length` items long. +// zero = If false, require that the length of the vector is not approximately zero. If true, require the length of the vector to be approx zero-length. Default: `undef` (don't check vector length.) +// eps = The minimum vector length that is considered non-zero. Default: `EPSILON` (`1e-9`) // Example: // is_vector(4); // Returns false // is_vector([4,true,false]); // Returns false @@ -28,8 +30,14 @@ // is_vector([3,4,5],3); // Returns true // is_vector([3,4,5],4); // Returns true // is_vector([]); // Returns false -function is_vector(v,length) = - is_list(v) && is_num(0*(v*v)) && (is_undef(length)||len(v)==length); +// is_vector([0,0,0],zero=true); // Returns true +// is_vector([0,0,0],zero=false); // Returns false +// is_vector([0,1,0],zero=true); // Returns false +// is_vector([0,0,1],zero=false); // Returns true +function is_vector(v,length,zero,eps=EPSILON) = + is_list(v) && is_num(0*(v*v)) + && (is_undef(length) || len(v)==length) + && (is_undef(zero) || ((norm(v) >= eps) == !zero)); // Function: add_scalar() @@ -188,22 +196,31 @@ function vector_angle(v1,v2,v3) = // vector_axis([10,0,10], [0,0,0], [-10,10,0]); // Returns: [-0.57735, -0.57735, 0.57735] // vector_axis([[10,0,10], [0,0,0], [-10,10,0]]); // Returns: [-0.57735, -0.57735, 0.57735] function vector_axis(v1,v2=undef,v3=undef) = - (is_list(v1) && is_list(v1[0]) && is_undef(v2) && is_undef(v3))? ( - assert(is_vector(v1.x)) - assert(is_vector(v1.y)) - len(v1)==3? assert(is_vector(v1.z)) vector_axis(v1.x, v1.y, v1.z) : - len(v1)==2? vector_axis(v1.x, v1.y) : - assert(false, "Bad arguments.") - ) : - (is_vector(v1) && is_vector(v2) && is_vector(v3))? vector_axis(v1-v2, v3-v2) : - (is_vector(v1) && is_vector(v2) && is_undef(v3))? let( + is_vector(v3) + ? assert(is_consistent([v3,v2,v1]), "Bad arguments.") + vector_axis(v1-v2, v3-v2) + : + assert( is_undef(v3), "Bad arguments.") + is_undef(v2) + ? assert( is_list(v1), "Bad arguments.") + len(v1) == 2 + ? vector_axis(v1[0],v1[1]) + : vector_axis(v1[0],v1[1],v1[2]) + : + assert( + is_vector(v1,zero=false) && + is_vector(v2,zero=false) && + is_consistent([v1,v2]), + "Bad arguments." + ) + let( eps = 1e-6, - v1 = point3d(v1/norm(v1)), - v2 = point3d(v2/norm(v2)), - v3 = (norm(v1-v2) > eps && norm(v1+v2) > eps)? v2 : - (norm(vabs(v2)-UP) > eps)? UP : - RIGHT - ) unit(cross(v1,v3)) : assert(false, "Bad arguments."); + 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 + : RIGHT + ) unit(cross(w1,w3)); // vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap diff --git a/version.scad b/version.scad index 4ba73cf..406f9e4 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,396]; +BOSL_VERSION = [2,0,397]; // Section: BOSL Library Version Functions From a73ca6368c36c5556a9d5bc9601572c25a94877d Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Tue, 21 Jul 2020 19:55:05 -0400 Subject: [PATCH 8/9] fixed in_list bug --- arrays.scad | 6 +++++- tests/test_arrays.scad | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/arrays.scad b/arrays.scad index 9d9463a..ea47d48 100644 --- a/arrays.scad +++ b/arrays.scad @@ -91,7 +91,11 @@ function slice(arr,st,end) = let( // in_list("bar", ["foo", "bar", "baz"]); // Returns true. // in_list("bee", ["foo", "bar", "baz"]); // Returns false. // in_list("bar", [[2,"foo"], [4,"bar"], [3,"baz"]], idx=1); // Returns true. -function in_list(x,l,idx=undef) = search([x], l, num_returns_per_match=1, index_col_num=idx) != [[]]; +function in_list(val,list,idx=undef) = + let( s = search([val], list, num_returns_per_match=1, index_col_num=idx)[0] ) + s==[] ? false + : is_undef(idx) ? val==list[s] + : val==list[s][idx]; // Function: min_index() diff --git a/tests/test_arrays.scad b/tests/test_arrays.scad index 0ed2bd6..a9e2b38 100644 --- a/tests/test_arrays.scad +++ b/tests/test_arrays.scad @@ -1,6 +1,5 @@ include - // List/Array Ops module test_repeat() { @@ -16,6 +15,11 @@ module test_in_list() { assert(in_list("bar", ["foo", "bar", "baz"])); assert(!in_list("bee", ["foo", "bar", "baz"])); assert(in_list("bar", [[2,"foo"], [4,"bar"], [3,"baz"]], idx=1)); + assert(!in_list(undef, [3,4,5])); + assert(in_list(undef,[3,4,undef,5])); + assert(!in_list(3,[])); + assert(!in_list(3,[4,5,[3]])); + } test_in_list(); From 7eafa691b4c88b0b37dfadcc52640e2210d9aa6d Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Tue, 21 Jul 2020 20:05:21 -0400 Subject: [PATCH 9/9] Changed to relative include names --- tests/hull.scad | 4 ++-- tests/polyhedra.scad | 4 ++-- tests/test_affine.scad | 2 +- tests/test_arrays.scad | 2 +- tests/test_common.scad | 2 +- tests/test_coords.scad | 2 +- tests/test_cubetruss.scad | 4 ++-- tests/test_debug.scad | 2 +- tests/test_edges.scad | 2 +- tests/test_errors.scad | 2 +- tests/test_geometry.scad | 2 +- tests/test_linear_bearings.scad | 4 ++-- tests/test_math.scad | 2 +- tests/test_mutators.scad | 2 +- tests/test_primitives.scad | 2 +- tests/test_quaternions.scad | 4 ++-- tests/test_queues.scad | 4 ++-- tests/test_shapes.scad | 4 ++-- tests/test_shapes2d.scad | 2 +- tests/test_skin.scad | 4 ++-- tests/test_stacks.scad | 4 ++-- tests/test_strings.scad | 4 ++-- tests/test_structs.scad | 4 ++-- tests/test_transforms.scad | 2 +- tests/test_vectors.scad | 4 ++-- tests/test_version.scad | 2 +- tests/test_vnf.scad | 4 ++-- 27 files changed, 40 insertions(+), 40 deletions(-) diff --git a/tests/hull.scad b/tests/hull.scad index 98bdb3f..50366d2 100644 --- a/tests/hull.scad +++ b/tests/hull.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../hull.scad> testpoints_on_sphere = [ for(p = diff --git a/tests/polyhedra.scad b/tests/polyhedra.scad index 5f2bedb..3a77fbc 100644 --- a/tests/polyhedra.scad +++ b/tests/polyhedra.scad @@ -1,5 +1,5 @@ -include -include +include<../std.scad> +include<../polyhedra.scad> $fn=96; diff --git a/tests/test_affine.scad b/tests/test_affine.scad index a37153c..a759b56 100644 --- a/tests/test_affine.scad +++ b/tests/test_affine.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_ident() { diff --git a/tests/test_arrays.scad b/tests/test_arrays.scad index a9e2b38..756e433 100644 --- a/tests/test_arrays.scad +++ b/tests/test_arrays.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> // List/Array Ops diff --git a/tests/test_common.scad b/tests/test_common.scad index ed97cae..fa6bdbd 100644 --- a/tests/test_common.scad +++ b/tests/test_common.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_typeof() { diff --git a/tests/test_coords.scad b/tests/test_coords.scad index 702a351..4b89c12 100644 --- a/tests/test_coords.scad +++ b/tests/test_coords.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_point2d() { diff --git a/tests/test_cubetruss.scad b/tests/test_cubetruss.scad index 9b71f0e..3c6965d 100644 --- a/tests/test_cubetruss.scad +++ b/tests/test_cubetruss.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../cubetruss.scad> module test_cubetruss_dist() { diff --git a/tests/test_debug.scad b/tests/test_debug.scad index 8c30564..b6351c5 100644 --- a/tests/test_debug.scad +++ b/tests/test_debug.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_standard_anchors() { diff --git a/tests/test_edges.scad b/tests/test_edges.scad index 047c1f9..0b755d6 100644 --- a/tests/test_edges.scad +++ b/tests/test_edges.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_is_edge_array() { diff --git a/tests/test_errors.scad b/tests/test_errors.scad index ba82755..fffe9eb 100644 --- a/tests/test_errors.scad +++ b/tests/test_errors.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> // Can't test echo output as yet. Include these for coverage calculations. diff --git a/tests/test_geometry.scad b/tests/test_geometry.scad index dca4069..92b9f16 100644 --- a/tests/test_geometry.scad +++ b/tests/test_geometry.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_point_on_segment2d() { diff --git a/tests/test_linear_bearings.scad b/tests/test_linear_bearings.scad index 19bc2f5..fb57ba5 100644 --- a/tests/test_linear_bearings.scad +++ b/tests/test_linear_bearings.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../linear_bearings.scad> module test_get_lmXuu_bearing_diam() { diff --git a/tests/test_math.scad b/tests/test_math.scad index 8b34da7..3233e6f 100644 --- a/tests/test_math.scad +++ b/tests/test_math.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> // Simple Calculations diff --git a/tests/test_mutators.scad b/tests/test_mutators.scad index 5854b52..7361434 100644 --- a/tests/test_mutators.scad +++ b/tests/test_mutators.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_HSL() { diff --git a/tests/test_primitives.scad b/tests/test_primitives.scad index 8780b5b..e903617 100644 --- a/tests/test_primitives.scad +++ b/tests/test_primitives.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_square() { diff --git a/tests/test_quaternions.scad b/tests/test_quaternions.scad index 7a66d25..b1e5130 100644 --- a/tests/test_quaternions.scad +++ b/tests/test_quaternions.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../strings.scad> function rec_cmp(a,b,eps=1e-9) = diff --git a/tests/test_queues.scad b/tests/test_queues.scad index cf45eef..4ce3c8c 100644 --- a/tests/test_queues.scad +++ b/tests/test_queues.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../queues.scad> module test_queue_init() { diff --git a/tests/test_shapes.scad b/tests/test_shapes.scad index 0b66d60..ec1d58b 100644 --- a/tests/test_shapes.scad +++ b/tests/test_shapes.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../hull.scad> module test_prismoid() { diff --git a/tests/test_shapes2d.scad b/tests/test_shapes2d.scad index dc8e874..1ee5ffa 100644 --- a/tests/test_shapes2d.scad +++ b/tests/test_shapes2d.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_turtle() { diff --git a/tests/test_skin.scad b/tests/test_skin.scad index 347ccd2..c4a231d 100644 --- a/tests/test_skin.scad +++ b/tests/test_skin.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../skin.scad> module test_skin() { diff --git a/tests/test_stacks.scad b/tests/test_stacks.scad index 3f3f0d2..7241203 100644 --- a/tests/test_stacks.scad +++ b/tests/test_stacks.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../stacks.scad> module test_stack_init() { diff --git a/tests/test_strings.scad b/tests/test_strings.scad index 673e8f0..a1d05d6 100644 --- a/tests/test_strings.scad +++ b/tests/test_strings.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../strings.scad> module test_upcase() { diff --git a/tests/test_structs.scad b/tests/test_structs.scad index 55db3b4..a4a4d92 100644 --- a/tests/test_structs.scad +++ b/tests/test_structs.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../structs.scad> module test_struct_set() { diff --git a/tests/test_transforms.scad b/tests/test_transforms.scad index 722b65e..a44e47c 100644 --- a/tests/test_transforms.scad +++ b/tests/test_transforms.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_translate() { diff --git a/tests/test_vectors.scad b/tests/test_vectors.scad index 6651c46..42f0a04 100644 --- a/tests/test_vectors.scad +++ b/tests/test_vectors.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_is_vector() { @@ -60,7 +60,7 @@ module test_vabs() { } test_vabs(); -include +include <../strings.scad> module test_vang() { assert(vang([1,0])==0); assert(vang([0,1])==90); diff --git a/tests/test_version.scad b/tests/test_version.scad index f877b5c..e82f13f 100644 --- a/tests/test_version.scad +++ b/tests/test_version.scad @@ -1,4 +1,4 @@ -include +include <../std.scad> module test_bosl_version() { diff --git a/tests/test_vnf.scad b/tests/test_vnf.scad index 65d5350..753803c 100644 --- a/tests/test_vnf.scad +++ b/tests/test_vnf.scad @@ -1,5 +1,5 @@ -include -include +include <../std.scad> +include <../vnf.scad> module test_is_vnf() {