fix bug in left hand spirals in spiral_sweep

add multi-facet higbee to threaded_rod
This commit is contained in:
Adrian Mariano 2023-01-31 22:49:23 -05:00
parent 9d4430387f
commit b47fcbf595
2 changed files with 21 additions and 15 deletions

View File

@ -1079,6 +1079,7 @@ module rotate_sweep(
// poly = [[-10,0], [-3,-5], [3,-5], [10,0], [0,-30]];
// spiral_sweep(poly, h=200, r=50, turns=3, $fn=36);
function _taperfunc(x) =
x>1 ? 1 : x<0 ? 0:
let(higofs = pow(0.05,2)) // Smallest hig scale is the square root of this value
sqrt((1-higofs)*x+higofs);
function _taperfunc_ellipse(x) =
@ -1087,7 +1088,8 @@ function _ss_polygon_r(N,theta) =
let( alpha = 360/N )
cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2));
function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, taper1, taper2, internal=false, anchor=CENTER, spin=0, orient=UP) =
assert(is_num(turns) && turns != 0)
assert(is_num(turns) && turns != 0, "turns must be a nonzero number")
assert(all_positive([h]), "Spiral height must be a positive number")
let(
tapersample = 10, // Oversample factor for higbee tapering
dir = sign(turns),
@ -1148,7 +1150,7 @@ function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, tap
u = a/(360*turns),
r = lerp(r1,r2,u),
mat = affine3d_zrot(dir*a)
* affine3d_translate([_ss_polygon_r(sides,dir*a)*r, 0, dir*h * (u-0.5)])
* affine3d_translate([_ss_polygon_r(sides,dir*a)*r, 0, h * (u-0.5)])
* affine3d_xrot(90)
* skewmat
* scale([hsc,lerp(hsc,1,0.25),1], cp=[internal ? xmax : xmin, yctr, 0]),
@ -2637,7 +2639,7 @@ function associate_vertices(polygons, split, curpoly=0) =
// Figure(3D): This is the "hexgrid" VNF tile, which creates a hexagonal grid texture, something which doesn't work well with a height field because the edges of the hexagon don't align with the grid. Note how the tile ranges between 0 and 1 in both X, Y and Z.
// tex = texture("hex_grid");
// vnf_polyhedron(tex);
// Figure(3D): This is an example of a tile that has no edges at the top or bottom, so it creates disconnected rings. See below for examples showing this tile in use.
// Figure(3D): This is an example of a tile that has no edges at the top or bottom, so it creates disconnected rings. See {{linear_sweep()}} for examples showing this tile in use.
// shape = skin([
// rect(2/5),
// rect(2/3),

View File

@ -1175,15 +1175,16 @@ module generic_threaded_rod(
higbee2 = thigbee2==0 ? true : thigbee2;
extra_thread1 = higbee1==false && internal ? 1 : 0;
extra_thread2 = higbee2==false && internal ? 1 : 0;
r1 = get_radius(d1=d1, d=d);
r2 = get_radius(d1=d2, d=d);
dummy0 =
assert(all_positive([pitch]),"Thread pitch must be a positive value")
assert(all_positive([l]),"Length must be a postive value")
assert(is_path(profile),"Profile must be a path")
assert(is_finite(higbee1) || is_bool(higbee1), str("higbee",is_undef(higbee)?"1":""," must be boolean or a number"))
assert(is_finite(higbee2) || is_bool(higbee2), str("higbee",is_undef(higbee)?"1":""," must be boolean or a number"))
assert(is_bool(left_handed));
r1 = get_radius(d1=d1, d=d);
r2 = get_radius(d1=d2, d=d);
assert(is_bool(left_handed))
assert(all_positive([r1,r2]), "Must give d or both d1 and d2 as positive values");
sides = quantup(segs(max(r1,r2)), starts);
rsc = internal? (1/cos(180/sides)) : 1;
islop = internal? 2*get_slop() : 0;
@ -1216,6 +1217,8 @@ module generic_threaded_rod(
* frame_map(x=[0,0,1], y=[1,0,0]) // Map profile to 3d, parallel to z axis
* scale(pitch); // scale profile by pitch
start_steps = sides / starts;
higlen = 4/32*360;//360*max(pitch/2, pmax-depth)/(2*PI*_r2);
echo(higlen=higlen);
thread_verts = [
// Outer loop constructs a vertical column of the screw at each angle
// covering 1/starts * 360 degrees of the cylinder.
@ -1227,14 +1230,15 @@ module generic_threaded_rod(
full_profile = [ // profile for the entire rod
for (thread = [-threads/2:1:threads/2-1])
let(
tang = (thread/starts) * 360 + ang,
adjusted_prof3d = tang < -twist/2+higang1 || tang > twist/2-higang2
? [for(v=prof3d) [v.x,internal?pmax/pitch:-pdepth,v.z]]
: prof3d
tang = thread/starts * 360 + ang,
hsc = tang < -twist/2+higang1 ? _taperfunc(1-(-twist/2+higang1-tang)/higlen )
: tang > twist/2-higang2 ? _taperfunc(1-(tang-twist/2+higang2)/higlen )
: 1,
higscale=scale([lerp(hsc,1,0.25),hsc,1], cp=[0,internal ? pmax/pitch:-pdepth, 0])
)
// The right movement finds the position of the thread along
// what will be the z axis after the profile is mapped to 3d
each apply(right(dz + thread) , adjusted_prof3d)
each apply(right(dz + thread) * higscale, prof3d)
]
)
[
@ -1271,13 +1275,12 @@ module generic_threaded_rod(
slope = (_r1-_r2)/l;
maxlen = 5*pitch;
attachable(anchor,spin,orient, r1=_r1, r2=_r2, l=l) {
union(){
// This method is faster but more complex code and it produces green tops
difference() {
vnf_polyhedron(vnf_quantize(thread_vnfs),convexity=10);
if (!internal){
if (bevel1 || bevel2)
rotate_extrude(){
@ -1544,8 +1547,9 @@ module thread_helix(
d1, d2, taper, taper1, taper2,
anchor, spin, orient
) {
dummy1=assert(is_undef(profile) || !any_defined([thread_depth, flank_angle]),"Cannot give thread_depth or flank_angle with a profile");
h = pitch*starts*turns;
dummy1=assert(is_undef(profile) || !any_defined([thread_depth, flank_angle]),"Cannot give thread_depth or flank_angle with a profile")
assert(all_positive([turns]), "The turns parameter must be a positive number");
h = pitch*starts*abs(turns);
r1 = get_radius(d1=d1, d=d, dflt=10);
r2 = get_radius(d1=d2, d=d, dflt=10);
profile = is_def(profile) ? profile :