mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2024-12-28 15:59:45 +00:00
Merge pull request #1065 from adrianVmariano/master
rename path functions
This commit is contained in:
commit
8b6e5aeefb
11 changed files with 164 additions and 70 deletions
|
@ -464,6 +464,47 @@ function deduplicate_indexed(list, indices, closed=false, eps=EPSILON) =
|
|||
|
||||
|
||||
|
||||
// Function: list_wrap()
|
||||
// Usage:
|
||||
// list_wrap(path, [eps]);
|
||||
// Description:
|
||||
// Force a list to wrap around so that its last point is equal to its first point: if the first and last entries are equal, simply returns the list unchanged.
|
||||
// Otherwise returns the list with the first point duplicated at the end of the list. Comparisons are done to the tolerance `eps`. Lists of length 0 or
|
||||
// 1 are returned unchanged.
|
||||
// Arguments:
|
||||
// list = list to unwrap
|
||||
// eps = epsilon for comparison. Default: EPSILON (1e-9)
|
||||
// See Also: list_unwrap(), deduplicate()
|
||||
|
||||
function list_wrap(list, eps=EPSILON) =
|
||||
assert(is_list(list))
|
||||
len(list)<2 || are_ends_equal(list,eps=eps)? list : [each list, list[0]];
|
||||
|
||||
|
||||
function cleanup_path(list,eps=EPSILON) =
|
||||
echo("***** Function cleanup_path() has been replaced by list_unwrap() and will be removed in a future version *****")
|
||||
list_unwrap(list,eps);
|
||||
|
||||
function close_path(list,eps=EPSILON) =
|
||||
echo("***** Function close_path() has been replaced by list_wrap() and will be removed in a future version *****")
|
||||
list_wrap(list,eps);
|
||||
|
||||
// Function: list_unwrap()
|
||||
// Usage:
|
||||
// list_unwrap(list, [eps]);
|
||||
// Description:
|
||||
// If a list's last point matches its first point then delete the last point. Inverse operation to {{list_wrap()}}. Note that if the first/last points
|
||||
// are repeated then the output may still have the first point equal to the last point. Comparisons are done to the tolerance `eps`. If the list has
|
||||
// length 0 or 1 it is returned unchanged.
|
||||
// Arguments:
|
||||
// list = list to unwrap
|
||||
// eps = epsilon for comparison. Default: EPSILON (1e-9)
|
||||
function list_unwrap(list, eps=EPSILON) =
|
||||
assert(is_list(list))
|
||||
len(list)>=2 && are_ends_equal(list,eps=eps)? [for (i=[0:1:len(list)-2]) list[i]] : list;
|
||||
|
||||
|
||||
|
||||
// Function: unique()
|
||||
// Usage:
|
||||
// ulist = unique(list);
|
||||
|
|
|
@ -285,7 +285,7 @@ module stroke(
|
|||
for (path = paths) {
|
||||
pathvalid = is_path(path,[2,3]) || same_shape(path,[[0,0]]) || same_shape(path,[[0,0,0]]);
|
||||
assert(pathvalid,"The path argument must be a list of 2D or 3D points, or a region.");
|
||||
path = deduplicate( closed? close_path(path) : path );
|
||||
path = deduplicate( closed? list_wrap(path) : path );
|
||||
|
||||
check4 = assert(is_num(width) || len(width)==len(path),
|
||||
"width must be a number or a vector the same length as the path (or all components of a region)");
|
||||
|
@ -576,7 +576,7 @@ function dashed_stroke(path, dashpat=[3,3], closed=false, fit=true, mindash=0.5)
|
|||
each dashed_stroke(p, dashpat, closed=true, fit=fit)
|
||||
] :
|
||||
let(
|
||||
path = closed? close_path(path) : path,
|
||||
path = closed? list_wrap(path) : path,
|
||||
dashpat = len(dashpat)%2==0? dashpat : concat(dashpat,[0]),
|
||||
plen = path_length(path),
|
||||
dlen = sum(dashpat),
|
||||
|
|
|
@ -2217,8 +2217,8 @@ function align_polygon(reference, poly, angles, cp, trans, return_ind=false) =
|
|||
// rot(90, p=pentagon(r=4))); // returns false
|
||||
function are_polygons_equal(poly1, poly2, eps=EPSILON) =
|
||||
let(
|
||||
poly1 = cleanup_path(poly1),
|
||||
poly2 = cleanup_path(poly2),
|
||||
poly1 = list_unwrap(poly1),
|
||||
poly2 = list_unwrap(poly2),
|
||||
l1 = len(poly1),
|
||||
l2 = len(poly2)
|
||||
) l1 != l2 ? false :
|
||||
|
|
26
paths.scad
26
paths.scad
|
@ -87,24 +87,6 @@ function force_path(path, name="path") =
|
|||
: path;
|
||||
|
||||
|
||||
// Function: close_path()
|
||||
// Usage:
|
||||
// close_path(path);
|
||||
// Description:
|
||||
// If a path's last point does not coincide with its first point, closes the path so it does.
|
||||
function close_path(path, eps=EPSILON) =
|
||||
are_ends_equal(path,eps=eps)? path : concat(path,[path[0]]);
|
||||
|
||||
|
||||
// Function: cleanup_path()
|
||||
// Usage:
|
||||
// cleanup_path(path);
|
||||
// Description:
|
||||
// If a path's last point coincides with its first point, deletes the last point in the path.
|
||||
function cleanup_path(path, eps=EPSILON) =
|
||||
are_ends_equal(path,eps=eps)? [for (i=[0:1:len(path)-2]) path[i]] : path;
|
||||
|
||||
|
||||
/// Internal Function: _path_select()
|
||||
/// Usage:
|
||||
/// _path_select(path,s1,u1,s2,u2,[closed]):
|
||||
|
@ -260,7 +242,7 @@ function path_length_fractions(path, closed) =
|
|||
/// for (isect=isects) translate(isect[0]) color("blue") sphere(d=10);
|
||||
function _path_self_intersections(path, closed=true, eps=EPSILON) =
|
||||
let(
|
||||
path = closed ? close_path(path,eps=eps) : path,
|
||||
path = closed ? list_wrap(path,eps=eps) : path,
|
||||
plen = len(path)
|
||||
)
|
||||
[ for (i = [0:1:plen-3]) let(
|
||||
|
@ -919,7 +901,7 @@ function split_path_at_self_crossings(path, closed=true, eps=EPSILON) =
|
|||
assert(is_path(path,2), "Must give a 2D path")
|
||||
assert(is_bool(closed))
|
||||
let(
|
||||
path = cleanup_path(path, eps=eps),
|
||||
path = list_unwrap(path, eps=eps),
|
||||
isects = deduplicate(
|
||||
eps=eps,
|
||||
concat(
|
||||
|
@ -1030,7 +1012,7 @@ function polygon_parts(poly, nonzero=false, eps=EPSILON) =
|
|||
assert(is_path(poly,2), "Must give 2D polygon")
|
||||
assert(is_bool(nonzero))
|
||||
let(
|
||||
poly = cleanup_path(poly, eps=eps),
|
||||
poly = list_unwrap(poly, eps=eps),
|
||||
tagged = _tag_self_crossing_subpaths(poly, nonzero=nonzero, closed=true, eps=eps),
|
||||
kept = [for (sub = tagged) if(sub[0] == "O") sub[1]],
|
||||
outregion = _assemble_path_fragments(kept, eps=eps)
|
||||
|
@ -1158,7 +1140,7 @@ function _assemble_path_fragments(fragments, eps=EPSILON, _finished=[]) =
|
|||
l_area = abs(polygon_area(result_l[0])),
|
||||
r_area = abs(polygon_area(result_r[0])),
|
||||
result = l_area < r_area? result_l : result_r,
|
||||
newpath = cleanup_path(result[0]),
|
||||
newpath = list_unwrap(result[0]),
|
||||
remainder = result[1],
|
||||
finished = min(l_area,r_area)<eps ? _finished : concat(_finished, [newpath])
|
||||
) _assemble_path_fragments(
|
||||
|
|
|
@ -421,7 +421,7 @@ function _region_region_intersections(region1, region2, closed1=true,closed2=tru
|
|||
intersections = [
|
||||
for(p1=idx(region1))
|
||||
let(
|
||||
path = closed1?close_path(region1[p1]):region1[p1]
|
||||
path = closed1?list_wrap(region1[p1]):region1[p1]
|
||||
)
|
||||
for(i = [0:1:len(path)-2])
|
||||
let(
|
||||
|
@ -442,7 +442,7 @@ function _region_region_intersections(region1, region2, closed1=true,closed2=tru
|
|||
// further tests can be discarded.
|
||||
for(p2=idx(region2))
|
||||
let(
|
||||
poly = closed2?close_path(region2[p2]):region2[p2],
|
||||
poly = closed2?list_wrap(region2[p2]):region2[p2],
|
||||
signs = [for(v=poly*seg_normal) abs(v-ref) < eps ? 0 : sign(v-ref) ]
|
||||
)
|
||||
if(max(signs)>=0 && min(signs)<=0) // some edge intersects line [a1,a2]
|
||||
|
|
|
@ -678,7 +678,7 @@ function smooth_path(path, tangents, size, relsize, splinesteps=10, uniform=fals
|
|||
bez = path_to_bezpath(path, tangents=tangents, size=size, relsize=relsize, uniform=uniform, closed=default(closed,false)),
|
||||
smoothed = bezpath_curve(bez,splinesteps=splinesteps)
|
||||
)
|
||||
closed ? cleanup_path(smoothed) : smoothed;
|
||||
closed ? list_unwrap(smoothed) : smoothed;
|
||||
|
||||
|
||||
function _scalar_to_vector(value,length,varname) =
|
||||
|
@ -815,7 +815,7 @@ function path_join(paths,joint=0,k=0.5,relocate=true,closed=false)=
|
|||
let(
|
||||
paths = !closed || len(paths)>1
|
||||
? paths
|
||||
: [close_path(paths[0])],
|
||||
: [list_wrap(paths[0])],
|
||||
N = len(paths) + (closed?0:-1),
|
||||
k = _scalar_to_vector(k,N),
|
||||
repjoint = is_num(joint) || (is_vector(joint,2) && len(paths)!=3),
|
||||
|
@ -828,7 +828,7 @@ function path_join(paths,joint=0,k=0.5,relocate=true,closed=false)=
|
|||
)
|
||||
assert(bad_j==[], str("Invalid joint values at indices ",bad_j))
|
||||
let(result=_path_join(paths,joint,k, relocate=relocate, closed=closed))
|
||||
closed ? cleanup_path(result) : result;
|
||||
closed ? list_unwrap(result) : result;
|
||||
|
||||
function _path_join(paths,joint,k=0.5,i=0,result=[],relocate=true,closed=false) =
|
||||
let(
|
||||
|
|
99
skin.scad
99
skin.scad
|
@ -771,7 +771,7 @@ function linear_sweep(
|
|||
trgns = [
|
||||
for (rgn = regions) [
|
||||
for (path = rgn) let(
|
||||
p = cleanup_path(path),
|
||||
p = list_unwrap(path),
|
||||
path = is_undef(maxseg)? p : [
|
||||
for (seg = pair(p,true)) each
|
||||
let( steps = ceil(norm(seg.y - seg.x) / maxseg) )
|
||||
|
@ -783,7 +783,7 @@ function linear_sweep(
|
|||
vnf = vnf_join([
|
||||
for (rgn = regions)
|
||||
for (pathnum = idx(rgn)) let(
|
||||
p = cleanup_path(rgn[pathnum]),
|
||||
p = list_unwrap(rgn[pathnum]),
|
||||
path = is_undef(maxseg)? p : [
|
||||
for (seg=pair(p,true)) each
|
||||
let(steps=ceil(norm(seg.y-seg.x)/maxseg))
|
||||
|
@ -1078,12 +1078,75 @@ module rotate_sweep(
|
|||
// Example:
|
||||
// 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) =
|
||||
function _taperfunc_orig_1d(x,L) =
|
||||
x>1 ? 1 : x<0 ? 0:
|
||||
let(higofs = pow(0.05,2)) // Smallest hig scale is the square root of this value
|
||||
let(
|
||||
higofs = pow(0.05,2) // Smallest hig scale is the square root of this value
|
||||
)
|
||||
sqrt((1-higofs)*x+higofs);
|
||||
|
||||
function _taperfunc_orig(x,L) =
|
||||
let(s=_taperfunc_orig_1d(x))
|
||||
x>1 ? [1,1]
|
||||
: x<0 ? [0,0]
|
||||
|
||||
: [lerp(s,1,.25),s];
|
||||
function _taperfunc_ellipse(x) =
|
||||
sqrt(1-(1-x)^2);
|
||||
function _taperfunc_linear(x) =
|
||||
x>1 ? 1 : x<0 ? 0 : x;
|
||||
function _taperfunc_ogive_width(x,L) =
|
||||
let( minscale = .2,
|
||||
r=(L^2+(1-minscale^2))/2/(1-minscale),
|
||||
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
|
||||
)
|
||||
x>1 ? [1,1]
|
||||
: x<0 ? [0,0]
|
||||
: [scale,1];
|
||||
function _taperfunc_ogive_width_circle(x,L,h) =
|
||||
let( minscale = .2,
|
||||
r=(L^2+(1-minscale^2))/2/(1-minscale),
|
||||
scale = sqrt(r^2-(L*(1-x))^2) -(r-1),
|
||||
vscale = x*L>h ? h : sqrt(h^2-(x*L-h)^2)
|
||||
)
|
||||
x>1 ? [1,1]
|
||||
: x<0.02 ? [0,0]
|
||||
: [scale,vscale/h];
|
||||
function _taperfunc_ogive_height(x,L) =
|
||||
let( minscale = .1,L=3*L,
|
||||
r=(L^2+(1-minscale^2))/2/(1-minscale),
|
||||
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
|
||||
)
|
||||
x>1 ? [1,1]
|
||||
: x<0 ? [0,0] //minscale,0]
|
||||
: [1,scale];
|
||||
function _taperfunc_ogive(x,L) =
|
||||
let( minscale = .3,
|
||||
r=(L^2+(1-minscale^2))/2/(1-minscale),
|
||||
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
|
||||
)
|
||||
x>1 ? [1,1]
|
||||
: x<0 ? [0,0]
|
||||
: [scale,scale];
|
||||
function _taperfunc_ogive_orig(x,L) =
|
||||
let( minscale = .3,
|
||||
r=(L^2+(1-minscale^2))/2/(1-minscale),
|
||||
scale = sqrt(r^2-(L*(1-x))^2) -(r-1)
|
||||
)
|
||||
x>1 ? [1,1]
|
||||
: x<0 ? [0,0]
|
||||
: [lerp(_taperfunc_orig_1d(x),1,.25),scale];
|
||||
|
||||
function _taperfunc_cut(x,L) = x>1 ? [1,1] : [0,0];
|
||||
|
||||
|
||||
function _taperfunc(x,L,h) = _taperfunc_ogive_width_circle(x,L,h);
|
||||
//function _taperfunc(x,L,h) = _taperfunc_orig(x,L);
|
||||
//function _taperfunc(x,L,h) = _taperfunc_ogive_width(x,L);
|
||||
function _taperfunc(x,L,h) = _taperfunc_orig(x,L);
|
||||
|
||||
|
||||
|
||||
function _ss_polygon_r(N,theta) =
|
||||
let( alpha = 360/N )
|
||||
cos(alpha/2)/(cos(posmod(theta,alpha)-alpha/2));
|
||||
|
@ -1144,16 +1207,16 @@ function spiral_sweep(poly, h, r, turns=1, taper, center, r1, r2, d, d1, d2, tap
|
|||
skewmat = affine3d_skew_xz(xa=atan2(r2-r1,h)),
|
||||
points = [
|
||||
for (a = interp_ang) let (
|
||||
hsc = a<tapercut1 ? _taperfunc((a-minang)/taperang1)
|
||||
: a>tapercut2 ? _taperfunc((maxang-a)/taperang2)
|
||||
: 1,
|
||||
hsc = a<tapercut1 ? _taperfunc((a-minang)/taperang1,abs(taper1),xmax-xmin)
|
||||
: a>tapercut2 ? _taperfunc((maxang-a)/taperang2,abs(taper2),xmax-xmin)
|
||||
: [1,1],
|
||||
u = a/(360*turns),
|
||||
r = lerp(r1,r2,u),
|
||||
mat = affine3d_zrot(dir*a)
|
||||
* 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]),
|
||||
* scale([hsc.y,hsc.x,1], cp=[internal ? xmax : xmin, yctr, 0]),
|
||||
pts = apply(mat, poly)
|
||||
) pts
|
||||
],
|
||||
|
@ -3425,8 +3488,8 @@ function _textured_linear_sweep(
|
|||
: [ceil(6*plen/h), 6],
|
||||
obases = resample_path(path, n=counts.x * samples, closed=true),
|
||||
onorms = path_normals(obases, closed=true),
|
||||
bases = close_path(obases),
|
||||
norms = close_path(onorms),
|
||||
bases = list_wrap(obases),
|
||||
norms = list_wrap(onorms),
|
||||
vnf = is_vnf(texture)
|
||||
? let( // VNF tile texture
|
||||
row_vnf = vnf_join([
|
||||
|
@ -3511,8 +3574,8 @@ function _textured_linear_sweep(
|
|||
: [ceil(6*plen/h), 6],
|
||||
obases = resample_path(path, n=counts.x * samples, closed=true),
|
||||
onorms = path_normals(obases, closed=true),
|
||||
bases = close_path(obases),
|
||||
norms = close_path(onorms),
|
||||
bases = list_wrap(obases),
|
||||
norms = list_wrap(onorms),
|
||||
nupath = [
|
||||
for (j = [0:1:counts.x-1], vert = tpath) let(
|
||||
part = (j + vert.x) * samples,
|
||||
|
@ -3699,8 +3762,8 @@ function _textured_revolution(
|
|||
is_vector(tex_size,2)? max(1,round(plen/tex_size.y)) : 6,
|
||||
obases = resample_path(path, n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
onorms = path_normals(obases, closed=closed),
|
||||
rbases = closed? close_path(obases) : obases,
|
||||
rnorms = closed? close_path(onorms) : onorms,
|
||||
rbases = closed? list_wrap(obases) : obases,
|
||||
rnorms = closed? list_wrap(onorms) : onorms,
|
||||
bases = xrot(90, p=path3d(rbases)),
|
||||
norms = xrot(90, p=path3d(rnorms)),
|
||||
vnf = is_vnf(texture)
|
||||
|
@ -3766,8 +3829,8 @@ function _textured_revolution(
|
|||
is_vector(tex_size,2)? max(1,round(plen/tex_size.y)) : 6,
|
||||
obases = resample_path(path, n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
onorms = path_normals(obases, closed=closed),
|
||||
bases = closed? close_path(obases) : obases,
|
||||
norms = closed? close_path(onorms) : onorms,
|
||||
bases = closed? list_wrap(obases) : obases,
|
||||
norms = closed? list_wrap(onorms) : onorms,
|
||||
ppath = is_vnf(texture)
|
||||
? [ // VNF tile texture
|
||||
for (j = [0:1:counts_y-1])
|
||||
|
@ -3816,8 +3879,8 @@ function _textured_revolution(
|
|||
is_vector(tex_size,2)? max(1,round(plen/tex_size.y)) : 6,
|
||||
obases = resample_path(rgn[0], n=counts_y * samples + (closed?0:1), closed=closed),
|
||||
onorms = path_normals(obases, closed=closed),
|
||||
rbases = closed? close_path(obases) : obases,
|
||||
rnorms = closed? close_path(onorms) : onorms,
|
||||
rbases = closed? list_wrap(obases) : obases,
|
||||
rnorms = closed? list_wrap(onorms) : onorms,
|
||||
bases = xrot(90, p=path3d(rbases)),
|
||||
norms = xrot(90, p=path3d(rnorms)),
|
||||
caps_vnf = vnf_join([
|
||||
|
|
|
@ -81,6 +81,26 @@ test_unique_count();
|
|||
|
||||
|
||||
|
||||
|
||||
module test_list_wrap() {
|
||||
assert(list_wrap([[1,2,3],[4,5,6],[1,8,9]]) == [[1,2,3],[4,5,6],[1,8,9],[1,2,3]]);
|
||||
assert(list_wrap([[1,2,3],[4,5,6],[1,8,9],[1,2,3]]) == [[1,2,3],[4,5,6],[1,8,9],[1,2,3]]);
|
||||
assert(list_wrap([])==[]);
|
||||
assert(list_wrap([3])==[3]);
|
||||
}
|
||||
test_list_wrap();
|
||||
|
||||
|
||||
module test_list_unwrap() {
|
||||
assert(list_unwrap([[1,2,3],[4,5,6],[1,8,9]]) == [[1,2,3],[4,5,6],[1,8,9]]);
|
||||
assert(list_unwrap([[1,2,3],[4,5,6],[1,8,9],[1,2,3]]) == [[1,2,3],[4,5,6],[1,8,9]]);
|
||||
assert(list_unwrap([])==[]);
|
||||
assert(list_unwrap([3])==[3]);
|
||||
}
|
||||
test_list_unwrap();
|
||||
|
||||
|
||||
|
||||
module test_is_increasing() {
|
||||
assert(is_increasing([1,2,3,4]) == true);
|
||||
assert(is_increasing([1,2,2,2]) == true);
|
||||
|
|
|
@ -32,21 +32,6 @@ module force_path() {
|
|||
test_is_1region();
|
||||
|
||||
|
||||
|
||||
module test_close_path() {
|
||||
assert(close_path([[1,2,3],[4,5,6],[1,8,9]]) == [[1,2,3],[4,5,6],[1,8,9],[1,2,3]]);
|
||||
assert(close_path([[1,2,3],[4,5,6],[1,8,9],[1,2,3]]) == [[1,2,3],[4,5,6],[1,8,9],[1,2,3]]);
|
||||
}
|
||||
test_close_path();
|
||||
|
||||
|
||||
module test_cleanup_path() {
|
||||
assert(cleanup_path([[1,2,3],[4,5,6],[1,8,9]]) == [[1,2,3],[4,5,6],[1,8,9]]);
|
||||
assert(cleanup_path([[1,2,3],[4,5,6],[1,8,9],[1,2,3]]) == [[1,2,3],[4,5,6],[1,8,9]]);
|
||||
}
|
||||
test_cleanup_path();
|
||||
|
||||
|
||||
module test_path_merge_collinear() {
|
||||
path = [[-20,-20], [-10,-20], [0,-10], [10,0], [20,10], [20,20], [15,30]];
|
||||
assert(path_merge_collinear(path) == [[-20,-20], [-10,-20], [20,10], [20,20], [15,30]]);
|
||||
|
|
|
@ -1217,7 +1217,7 @@ 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);
|
||||
higlen = 2/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
|
||||
|
@ -1231,10 +1231,13 @@ module generic_threaded_rod(
|
|||
for (thread = [-threads/2:1:threads/2-1])
|
||||
let(
|
||||
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])
|
||||
hsc = tang < -twist/2+higang1 ? _taperfunc(1-(-twist/2+higang1-tang)/higlen,PI*2*_r1*higlen/360 )
|
||||
: tang > twist/2-higang2 ? _taperfunc(1-(tang-twist/2+higang2)/higlen,PI*2*_r2*higlen/360 )
|
||||
: [1,1],
|
||||
higscale=scale([hsc.x, hsc.y,1], cp=[0,internal ? pmax/pitch:-pdepth, 0])
|
||||
// higscale=scale([lerp(hsc,1,0.25),hsc,1], cp=[0,internal ? pmax/pitch:-pdepth, 0])
|
||||
// higscale=scale([lerp(hsc,1,0.25),1,1], cp=[0,internal ? pmax/pitch:-pdepth, 0])
|
||||
// higscale=scale([1,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
|
||||
|
|
2
vnf.scad
2
vnf.scad
|
@ -826,7 +826,7 @@ function _split_polygon_at_x(poly, x) =
|
|||
if (len(out1)>=3) each split_path_at_self_crossings(out1),
|
||||
if (len(out2)>=3) each split_path_at_self_crossings(out2),
|
||||
],
|
||||
out = [for (p=out3) if (len(p) > 2) cleanup_path(p)]
|
||||
out = [for (p=out3) if (len(p) > 2) list_unwrap(p)]
|
||||
) out;
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue