From b9713845f79cc078f7fd92b23bb48a84364ffa8e Mon Sep 17 00:00:00 2001 From: Adrian Mariano <avm4@cornell.edu> Date: Sat, 6 Aug 2022 10:28:36 -0400 Subject: [PATCH] added n= option to supershape to give number of points --- shapes2d.scad | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/shapes2d.scad b/shapes2d.scad index 9767581..52d5efa 100644 --- a/shapes2d.scad +++ b/shapes2d.scad @@ -1399,18 +1399,22 @@ function _superformula(theta,m1,m2,n1,n2=1,n3=1,a=1,b=1) = // Function&Module: supershape() // Usage: As Module -// supershape(step, [m1=], [m2=], [n1=], [n2=], [n3=], [a=], [b=], [r=/d=]) [ATTACHMENTS]; +// supershape([step],[n=], [m1=], [m2=], [n1=], [n2=], [n3=], [a=], [b=], [r=/d=]) [ATTACHMENTS]; // Usage: As Function -// path = supershape(step, [m1=], [m2=], [n1=], [n2=], [n3=], [a=], [b=], [r=/d=]); +// path = supershape([step], [n=], [m1=], [m2=], [n1=], [n2=], [n3=], [a=], [b=], [r=/d=]); // Topics: Shapes (2D), Paths (2D), Path Generators, Attachable // See Also: circle(), ellipse() // Description: // When called as a function, returns a 2D path for the outline of the [Superformula](https://en.wikipedia.org/wiki/Superformula) shape. // When called as a module, creates a 2D [Superformula](https://en.wikipedia.org/wiki/Superformula) shape. // Note that the "hull" type anchoring (the default) is more intuitive for concave star-like shapes, but the anchor points do not -// necesarily lie on the line of the anchor vector, which can be confusing, especially for simpler, ellipse-like shapes. +// necesarily lie on the line of the anchor vector, which can be confusing, especially for simpler, ellipse-like shapes. +// Note that the default step angle of 0.5 is very fine and can be slow, but due to the complex curves of the supershape, +// many points are often required to give a good result. // Arguments: -// step = The angle step size for sampling the superformula shape. Smaller steps are slower but more accurate. +// step = The angle step size for sampling the superformula shape. Smaller steps are slower but more accurate. Default: 0.5 +// --- +// n = Produce n points as output. Alternative to step. Not to be confused with shape parameters n1 and n2. // m1 = The m1 argument for the superformula. Default: 4. // m2 = The m2 argument for the superformula. Default: m1. // n1 = The n1 argument for the superformula. Default: 1. @@ -1419,7 +1423,6 @@ function _superformula(theta,m1,m2,n1,n2=1,n3=1,a=1,b=1) = // a = The a argument for the superformula. Default: 1. // b = The b argument for the superformula. Default: a. // r = Radius of the shape. Scale shape to fit in a circle of radius r. -// --- // d = Diameter of the shape. Scale shape to fit in a circle of diameter d. // anchor = Translate so anchor point is at origin (0,0,0). See [anchor](attachments.scad#subsection-anchor). Default: `CENTER` // spin = Rotate this many degrees around the Z axis after anchor. See [spin](attachments.scad#subsection-spin). Default: `0` @@ -1449,26 +1452,25 @@ function _superformula(theta,m1,m2,n1,n2=1,n3=1,a=1,b=1) = // Examples: // linear_extrude(height=0.3, scale=0) supershape(step=1, m1=6, n1=0.4, n2=0, n3=6); // linear_extrude(height=5, scale=0) supershape(step=1, b=3, m1=6, n1=3.8, n2=16, n3=10); -function supershape(step=0.5, m1=4, m2, n1=1, n2, n3, a=1, b, r, d,anchor=CENTER, spin=0, atype="hull") = +function supershape(step=0.5, n, m1=4, m2, n1=1, n2, n3, a=1, b, r, d,anchor=CENTER, spin=0, atype="hull") = assert(in_list(atype, _ANCHOR_TYPES), "Anchor type must be \"hull\" or \"intersect\"") let( - + n = first_defined([n, ceil(360/step)]), + angs = lerpn(360,0,n,endpoint=false), r = get_radius(r=r, d=d, dflt=undef), m2 = is_def(m2) ? m2 : m1, n2 = is_def(n2) ? n2 : n1, n3 = is_def(n3) ? n3 : n2, b = is_def(b) ? b : a, - steps = ceil(360/step), - step = 360/steps, - angs = [for (i = [0:steps]) step*i], - rads = [for (theta = angs) _superformula(theta=theta,m1=m1,m2=m2,n1=n1,n2=n2,n3=n3,a=a,b=b)], - scale = is_def(r) ? r/max(rads) : 1, - path = [for (i = [steps:-1:1]) let(a=angs[i]) scale*rads[i]*[cos(a), sin(a)]] + // superformula returns r(theta), the point in polar coordinates + rvals = [for (theta = angs) _superformula(theta=theta,m1=m1,m2=m2,n1=n1,n2=n2,n3=n3,a=a,b=b)], + scale = is_def(r) ? r/max(rvals) : 1, + path = [for (i=idx(angs)) scale*rvals[i]*[cos(angs[i]), sin(angs[i])]] ) reorient(anchor,spin, two_d=true, path=path, p=path, extent=atype=="hull"); -module supershape(step=0.5,m1=4,m2=undef,n1,n2=undef,n3=undef,a=1,b=undef, r=undef, d=undef, anchor=CENTER, spin=0, atype="hull") { +module supershape(step=0.5,n,m1=4,m2=undef,n1,n2=undef,n3=undef,a=1,b=undef, r=undef, d=undef, anchor=CENTER, spin=0, atype="hull") { check = assert(in_list(atype, _ANCHOR_TYPES), "Anchor type must be \"hull\" or \"intersect\""); - path = supershape(step=step,m1=m1,m2=m2,n1=n1,n2=n2,n3=n3,a=a,b=b,r=r,d=d); + path = supershape(step=step,n=n,m1=m1,m2=m2,n1=n1,n2=n2,n3=n3,a=a,b=b,r=r,d=d); attachable(anchor,spin,extent=atype=="hull", two_d=true, path=path) { polygon(path); children();