From b82f1b8e5de68fdd7c16266544fe36994948ee69 Mon Sep 17 00:00:00 2001 From: Adrian Mariano Date: Sat, 12 Dec 2020 21:15:33 -0500 Subject: [PATCH] tweaked vac example in turtle3d added delete_last() to arrays.scad added endpoint= option to arc added tests for last two things --- arrays.scad | 11 ++++++++++- shapes2d.scad | 10 +++++++--- tests/test_arrays.scad | 15 +++++++++++++++ tests/test_shapes2d.scad | 1 + turtle3d.scad | 2 +- 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/arrays.scad b/arrays.scad index 967109b..db9a4c6 100644 --- a/arrays.scad +++ b/arrays.scad @@ -101,6 +101,15 @@ function select(list, start, end=undef) = // last(l); // Returns 9. function last(list) = list[len(list)-1]; +// Function: delete_last() +// Description: +// Returns a list of all but the last entry. If input is empty, returns empty list. +// Usage: +// delete_last(list) +function delete_last(list) = + assert(is_list(list)) + list==[] ? [] : slice(list,0,-2); + // Function: slice() // Description: // Returns a slice of a list. The first item is index 0. @@ -281,7 +290,7 @@ function list_range(n=undef, s=0, e=undef, step=undef) = // Example: // reverse([3,4,5,6]); // Returns [6,5,4,3] function reverse(x) = - assert(is_list(x)||is_string(x)) + assert(is_list(x)||is_string(x), "Input to reverse must be a list or string") let (elems = [ for (i = [len(x)-1 : -1 : 0]) x[i] ]) is_string(x)? str_join(elems) : elems; diff --git a/shapes2d.scad b/shapes2d.scad index 3401250..b9750da 100644 --- a/shapes2d.scad +++ b/shapes2d.scad @@ -350,7 +350,7 @@ module stroke( // N = Number of vertices to form the arc curve from. // r = Radius of the arc. // d = Diameter of the arc. -// angle = If a scalar, specifies the end angle in degrees. If a vector of two scalars, specifies start and end angles. +// angle = If a scalar, specifies the end angle in degrees (relative to start parameter). If a vector of two scalars, specifies start and end angles. // cp = Centerpoint of arc. // points = Points on the arc. // long = if given with cp and points takes the long arc instead of the default short arc. Default: false @@ -360,6 +360,7 @@ module stroke( // thickness = If given with `width`, arc starts and ends on X axis, to make a circle segment. // start = Start angle of arc. // wedge = If true, include centerpoint `cp` in output to form pie slice shape. +// endpoint = If false exclude the last point (function only). Default: true // Examples(2D): // arc(N=4, r=30, angle=30, wedge=true); // arc(r=30, angle=30, wedge=true); @@ -378,7 +379,10 @@ module stroke( // Example(FlatSpin): // path = arc(points=[[0,30,0],[0,0,30],[30,0,0]]); // trace_path(path, showpts=true, color="cyan"); -function arc(N, r, angle, d, cp, points, width, thickness, start, wedge=false, long=false, cw=false, ccw=false) = +function arc(N, r, angle, d, cp, points, width, thickness, start, wedge=false, long=false, cw=false, ccw=false, endpoint=true) = + assert(is_bool(endpoint)) + !endpoint ? assert(!wedge, "endpoint cannot be false if wedge is true") + slice(arc(N,r,angle,d,cp,points,width,thickness,start,wedge,long,cw,ccw,true),0,-2) : // First try for 2D arc specified by width and thickness is_def(width) && is_def(thickness)? ( assert(!any_defined([r,cp,points]) && !any([cw,ccw,long]),"Conflicting or invalid parameters to arc") @@ -472,7 +476,7 @@ function _normal_segment(p1,p2) = // Function: turtle() // Usage: -// turtle(commands, [state], [full_state], [repeat]) +// turtle(commands, [state], [full_state], [repeat], [endpoint]) // Description: // Use a sequence of turtle graphics commands to generate a path. The parameter `commands` is a list of // turtle commands and optional parameters for each command. The turtle state has a position, movement direction, diff --git a/tests/test_arrays.scad b/tests/test_arrays.scad index f40b72a..521e6e9 100644 --- a/tests/test_arrays.scad +++ b/tests/test_arrays.scad @@ -27,6 +27,21 @@ module test_select() { } test_select(); +module test_last() { + list = [1,2,3,4]; + assert(last(list)==4); + assert(last([])==undef); +} +test_last(); + +module test_delete_last() { + list = [1,2,3,4]; + assert(delete_last(list) == [1,2,3]); + assert(delete_last([1]) == []); + assert(delete_last([]) == []); +} +test_delete_last(); + module test_slice() { assert(slice([3,4,5,6,7,8,9], 3, 5) == [6,7]); diff --git a/tests/test_shapes2d.scad b/tests/test_shapes2d.scad index 1ee5ffa..ce63261 100644 --- a/tests/test_shapes2d.scad +++ b/tests/test_shapes2d.scad @@ -40,6 +40,7 @@ test_turtle(); module test_arc() { assert_approx(arc(N=8, d=100, angle=135, cp=[10,10]), [[60,10],[57.1941665154,26.5139530978],[49.0915741234,41.1744900929],[36.6016038258,52.3362099614],[21.1260466978,58.7463956091],[4.40177619483,59.6856104947],[-11.6941869559,55.0484433951],[-25.3553390593,45.3553390593]]); + assert_approx(arc(N=8, d=100, angle=135, cp=[10,10],endpoint=false), [[60,10],[57.1941665154,26.5139530978],[49.0915741234,41.1744900929],[36.6016038258,52.3362099614],[21.1260466978,58.7463956091],[4.40177619483,59.6856104947],[-11.6941869559,55.0484433951],[-25.3553390593]]); assert_approx(arc(N=8, d=100, angle=[45,225], cp=[10,10]), [[45.3553390593,45.3553390593],[26.5139530978,57.1941665154],[4.40177619483,59.6856104947],[-16.6016038258,52.3362099614],[-32.3362099614,36.6016038258],[-39.6856104947,15.5982238052],[-37.1941665154,-6.51395309776],[-25.3553390593,-25.3553390593]]); assert_approx(arc(N=8, d=100, start=45, angle=135, cp=[10,10]), [[45.3553390593,45.3553390593],[31.6941869559,55.0484433951],[15.5982238052,59.6856104947],[-1.12604669782,58.7463956091],[-16.6016038258,52.3362099614],[-29.0915741234,41.1744900929],[-37.1941665154,26.5139530978],[-40,10]]); assert_approx(arc(N=8, d=100, start=45, angle=-90, cp=[10,10]), [[45.3553390593,45.3553390593],[52.3362099614,36.6016038258],[57.1941665154,26.5139530978],[59.6856104947,15.5982238052],[59.6856104947,4.40177619483],[57.1941665154,-6.51395309776],[52.3362099614,-16.6016038258],[45.3553390593,-25.3553390593]]); diff --git a/turtle3d.scad b/turtle3d.scad index 1e959d8..e7bbac3 100644 --- a/turtle3d.scad +++ b/turtle3d.scad @@ -360,7 +360,7 @@ function _rotpart(T) = [for(i=[0:3]) [for(j=[0:3]) j<3 || i==3 ? T[i][j] : 0]]; // ["move", seg1_len, "grow", seg1_bot_ID/seg2_bot_ID] // ], // state=UP, transforms=true); -// zrot(90)back_half() // Remove this to get a usable part +// back_half() // Remove this to get a usable part // sweep(circle(d=seg1_bot_OD, $fn=128), trans, closed=true); // Example: Closed spiral // include