mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-29 16:29:40 +00:00
helix rewrite
make skin() take regions
This commit is contained in:
parent
df5971ba0f
commit
71b22e5850
2 changed files with 42 additions and 22 deletions
61
drawing.scad
61
drawing.scad
|
@ -688,32 +688,49 @@ module arc(N, r, angle, d, cp, points, width, thickness, start, wedge=false)
|
||||||
|
|
||||||
|
|
||||||
// Function: helix()
|
// Function: helix()
|
||||||
// Description:
|
|
||||||
// Returns a 3D helical path.
|
|
||||||
// Usage:
|
// Usage:
|
||||||
// helix(turns, h, n, r|d, [cp], [scale]);
|
// helix([l|h], [turns], [angle], r|r1|r2, d|d1|d2)
|
||||||
|
// Description:
|
||||||
|
// Returns a 3D helical path on a cone, including the degerate case of flat spirals.
|
||||||
|
// You can specify start and end radii. You can give the length, the helix angle, or the number of turns: two
|
||||||
|
// of these three parameters define the helix. For a flat helix you must give length 0 and a turn count.
|
||||||
|
// Helix will be right handed if turns is positive and left handed if it is negative.
|
||||||
|
// The angle is calculateld based on the radius at the base of the helix.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// h = Height of spiral.
|
// h|l = Height/length of helix, zero for a flat spiral
|
||||||
// turns = Number of turns in spiral.
|
// ---
|
||||||
// n = Number of spiral sides.
|
// turns = Number of turns in helix, positive for right handed
|
||||||
// r = Radius of spiral.
|
// angle = helix angle
|
||||||
// d = Radius of spiral.
|
// r = Radius of helix
|
||||||
// cp = Centerpoint of spiral. Default: `[0,0]`
|
// r1 = Radius of bottom of helix
|
||||||
// scale = [X,Y] scaling factors for each axis. Default: `[1,1]`
|
// r2 = Radius of top of helix
|
||||||
|
// d = Diameter of helix
|
||||||
|
// d1 = Diameter of bottom of helix
|
||||||
|
// d2 = Diameter of top of helix
|
||||||
// Example(3D):
|
// Example(3D):
|
||||||
// trace_path(helix(turns=2.5, h=100, n=24, r=50), N=1, showpts=true);
|
// trace_path(helix(turns=2.5, h=100, r=50), N=1, showpts=true);
|
||||||
function helix(turns=3, h=100, n=12, r, d, cp=[0,0], scale=[1,1]) = let(
|
// Example(3D): Helix that turns the other way
|
||||||
rr=get_radius(r=r, d=d, dflt=100),
|
// trace_path(helix(turns=-2.5, h=100, r=50), N=1, showpts=true);
|
||||||
cnt=floor(turns*n),
|
// Example(3D): Flat helix (note points are still 3d)
|
||||||
dz=h/cnt
|
// stroke(helix(h=0,r1=50,r2=25,l=0, turns=4));
|
||||||
) [
|
function helix(l,h,turns,angle, r, r1, r2, d, d1, d2)=
|
||||||
for (i=[0:1:cnt]) [
|
let(
|
||||||
rr * cos(i*360/n) * scale.x + cp.x,
|
r1=get_radius(r=r,r1=r1,d=d,d1=d1,dflt=1),
|
||||||
rr * sin(i*360/n) * scale.y + cp.y,
|
r2=get_radius(r=r,r1=r2,d=d,d1=d2,dflt=1),
|
||||||
i*dz
|
length = first_defined([l,h])
|
||||||
]
|
)
|
||||||
];
|
assert(num_defined([length,turns,angle])==2,"Must define exactly two of l/h, turns, and angle")
|
||||||
|
assert(is_undef(angle) || length!=0, "Cannot give length 0 with an angle")
|
||||||
|
let(
|
||||||
|
// length advances dz for each turn
|
||||||
|
dz = is_def(angle) && length!=0 ? 2*PI*r1*tan(angle) : length/abs(turns),
|
||||||
|
|
||||||
|
maxtheta = is_def(turns) ? 360*turns : 360*length/dz,
|
||||||
|
N = segs(max(r1,r2))
|
||||||
|
)
|
||||||
|
[for(theta=lerpn(0,maxtheta, max(3,ceil(abs(maxtheta)*N/360))))
|
||||||
|
let(R=lerp(r1,r2,theta/maxtheta))
|
||||||
|
[R*cos(theta), R*sin(theta), abs(theta)/360 * dz]];
|
||||||
|
|
||||||
|
|
||||||
function _normal_segment(p1,p2) =
|
function _normal_segment(p1,p2) =
|
||||||
|
|
|
@ -395,6 +395,9 @@ module skin(profiles, slices, refine=1, method="direct", sampling, caps, closed=
|
||||||
function skin(profiles, slices, refine=1, method="direct", sampling, caps, closed=false, z, style="min_edge") =
|
function skin(profiles, slices, refine=1, method="direct", sampling, caps, closed=false, z, style="min_edge") =
|
||||||
assert(is_def(slices),"The slices argument must be specified.")
|
assert(is_def(slices),"The slices argument must be specified.")
|
||||||
assert(is_list(profiles) && len(profiles)>1, "Must provide at least two profiles")
|
assert(is_list(profiles) && len(profiles)>1, "Must provide at least two profiles")
|
||||||
|
let(
|
||||||
|
profiles = [for(p=profiles) if (is_region(p) && len(p)==1) p[0] else p]
|
||||||
|
)
|
||||||
let( bad = [for(i=idx(profiles)) if (!(is_path(profiles[i]) && len(profiles[i])>2)) i])
|
let( bad = [for(i=idx(profiles)) if (!(is_path(profiles[i]) && len(profiles[i])>2)) i])
|
||||||
assert(len(bad)==0, str("Profiles ",bad," are not a paths or have length less than 3"))
|
assert(len(bad)==0, str("Profiles ",bad," are not a paths or have length less than 3"))
|
||||||
let(
|
let(
|
||||||
|
|
Loading…
Reference in a new issue