arc doc improvements; change point counts for rounded arcs for consistency

This commit is contained in:
Adrian Mariano
2025-08-23 11:18:52 -04:00
parent 4d7f1fa847
commit e70b057e60
2 changed files with 51 additions and 23 deletions

View File

@@ -696,15 +696,20 @@ module dashed_stroke(path, dashpat=[3,3], width=1, closed=false, fit=true, round
// Usage: as module
// arc(...) [ATTACHMENTS];
// Description:
// If called as a function, returns a 2D or 3D path forming an arc. If `wedge` is true, the centerpoint of the arc appears as the first point in the result.
// If called as a module, creates a 2D arc polygon or pie slice shape. Numerous methods are available to specify the arc.
// If called as a function, returns a 2D or 3D path forming an arc. Numerous methods are available to specify the arc as listed in the Arguments section.
// If `wedge` is true, the centerpoint of the arc appears as the first point in the result.
// If called as a module, the arc must be 2D and the module creates the 2D arc polygon or pie slice shape.
// .
// The `rounding` parameter is permitted only when `wedge=true` and applies specified radius roundings at each of the corners, with `rounding[0]` giving
// If `endpoint=false`, which is only accepted by the functional form, then the arc stops one step before the final point.
// The `rounding` parameter, which is permitted only when `wedge=true`, applies specified radius roundings at each of the corners, with `rounding[0]` giving
// the rounding at the center point, and then the other two the two outer corners in the direction that the arc travels.
// If you give `n` then each arc section in your curve uses `n` points, so the total number of points is `n` times one plus the number of non-zero roundings
// you specified. If you don't need to control the exact point count, you should use `$fs` and `$fa` to control the number of points on the roundings and arc.
// When you do not give the `n` argument, the minimum number of points on the arc is two if `wedge` is true but three if `wedge` is false.
// Recall that if you do use `$fn` it specifies the number of **segments** not points on the whole circle.
// .
// If you give `n` for an arc without roundings then the curve of the arc will use `n` points. If `endpoint=false` the arc still has `n` points, but
// they are closer together. When wedge is true the output has an extra point. If you use rounding on a wedge then each rounding will have the specified
// number of points, but note that the points of adjacent rounded areas overlap. It may be easier to think that each curve in the output has n-1 facets. With rounding,
// the total number of points on a wedge will be $n + 1 + (n-1) k$ where $k$ is the number of roundings that are nonzero.
// To get enough points on corner roundings you may need an `n` that is very large and produces more points than needed on the main curved portion of the arc.
// Using `$fs` and `$fa` makes it possible to have differing numbers of points on the various roundings in your arc based on their radius and angle.
// Arguments:
// n = Number of vertices to use in the arc. If `wedge=true` you will get `n+1` points.
// r = Radius of the arc.
@@ -894,15 +899,16 @@ function arc(n, r, angle, d, cp, points, corner, width, thickness, start, wedge=
module arc(n, r, angle, d, cp, points, corner, width, thickness, start, wedge=false, rounding, anchor=CENTER, spin=0)
{
path = arc(n=n, r=r, angle=angle, d=d, cp=cp, points=points, corner=corner, width=width, thickness=thickness, start=start, wedge=wedge, rounding=rounding);
attachable(anchor,spin, two_d=true, path=path, extent=false) {
polygon(path);
assert(len(path[0])==2 || sum(v_abs(column(path,2)))==0, "Module form of arc() only works with 2D inputs.");
path2d = path2d(path);
attachable(anchor,spin, two_d=true, path=path2d, extent=false) {
polygon(path2d);
children();
}
}
function _rounded_arc(radius, rounding=0, angle, n) =
assert(is_finite(angle) && abs(angle)<360, "angle must be strictly between -360 and 360")
assert(is_finite(rounding) || is_vector(rounding,3), "rounding must be a scalar or 3-vector")
@@ -930,7 +936,6 @@ function _rounded_arc(radius, rounding=0, angle, n) =
edge_gap1=radius-arc1_cut-radius_of_ctrpt_edge,
edge_gap2=radius-arc2_cut-radius_of_ctrpt_edge,
angle_span1 = rounding[1]>0 ? [-dir*90, dir*arc1_angle] : -[dir*90, dir*180 - arc1_angle],
angle_span2 = [angle-dir*arc2_angle + (rounding[2]<0 ? dir*180 : 0), angle+dir*90]
)
@@ -944,9 +949,11 @@ function _rounded_arc(radius, rounding=0, angle, n) =
polar_to_xy(r=radius_of_ctrpt_edge, theta=0)],
endpoint=edge_gap1!=0,n=n)
else repeat([0,0],rounding[0]>0 && abs(angle)==180 && is_def(n) ? n : 1),
each if (rounding[1]!=0) arc(r=abs(rounding[1]),cp=pt1,angle=angle_span1,endpoint=dir*arc1_angle==angle,n=n), // first corner
each if (rounding[1]!=0) arc(r=abs(rounding[1]),cp=pt1,angle=angle_span1,
endpoint=dir*arc1_angle==angle,n=u_add(n,dir*arc1_angle==angle?0:-1)), // first corner
each if (arc1_angle+arc2_angle<abs(angle))
arc(r=radius, angle=[dir*arc1_angle,angle - dir*arc2_angle], endpoint=rounding[2]==0, n=n), // main arc section
arc(r=radius, angle=[dir*arc1_angle,angle - dir*arc2_angle], endpoint=rounding[2]==0, // main arc section
n=u_add(n,rounding[2]==0?0:-1)),
each if (rounding[2]!=0) arc(r=abs(rounding[2]),cp=pt3, angle=angle_span2, endpoint=edge_gap2!=0, n=n) // second corner
];

View File

@@ -934,6 +934,8 @@ function spur_gear(
let(
profile_shift = auto_profile_shift(teeth,PA,helical,profile_shift=profile_shift),
pr = pitch_radius(circ_pitch, teeth, helical),
feee=echo(pr_spur = pr, circ_pitch, teeth, helical),
or = outer_radius(circ_pitch, teeth, helical=helical, profile_shift=profile_shift, internal=internal,shorten=shorten),
rr = _root_radius_basic(circ_pitch, teeth, clearance, profile_shift=profile_shift, internal=internal),
anchor_rad = atype=="pitch" ? pr
@@ -2772,10 +2774,21 @@ function worm(
profile_shift=0
), 1, -2)
),
rack_profile = [
for (t = xcopies(trans_pitch, n=2*ceil(l/trans_pitch)+1))
each apply(t, tooth)
],
nrp = select(rack2d(
pitch=circ_pitch,
teeth=2*ceil(l/trans_pitch)+1,
pressure_angle=PA,
clearance=clearance,
backlash=backlash,
helical=helical,
profile_shift=0
), 1, -2),
ff=echo(tooth=tooth, rack_profile=rack_profile,nrp=nrp),
steps = max(36, segs(d/2)),
step = 360 / steps,
zsteps = ceil(l / trans_pitch / starts * steps),
@@ -3139,6 +3152,7 @@ function worm_gear(
let(
gear_arc = 2 * PA,
helical = asin(worm_starts * circ_pitch / PI / worm_diam),
fee=echo(helical=helical),
full_tooth = apply(
zrot(90) * scale(0.99),
_gear_tooth_profile(
@@ -3146,21 +3160,26 @@ function worm_gear(
pressure_angle=PA,
profile_shift=-profile_shift,
clearance=clearance,
helical=helical,
helical=helical, internal=false,
center=true
)
),
ftl = len(full_tooth),
tooth_half1 = (select(full_tooth, 0, ftl/2-1)),
tooth_half2 = (select(full_tooth, ftl/2, -1)),
fda= echo(th1=tooth_half1, th2=tooth_half2),
tang = 360 / teeth,
rteeth = quantdn(teeth * gear_arc / 360, 2) / 2 + 0.5,
rteeth = (quantdn(teeth * gear_arc / 360, 2) / 2 + 0.5),
pr = pitch_radius(circ_pitch, teeth, helical=helical),
feee=echo(pr_worm = pr, circ_pitch, teeth, helical),
circum = 2*PI*pr,
fdsa= echo(pr=pr),
tan_helical = tan(helical),
oslices = slices * 4,
rows = [
for (data = [[tooth_half1,1], [tooth_half2,-1]])
let (
tooth_half = data[0],
tooth_half = (data[0]),
dir = data[1]
)
for (pt = tooth_half) [
@@ -3168,14 +3187,16 @@ function worm_gear(
let (
u = i / oslices,
w_ang = worm_arc * (u - 0.5),
g_ang_delta = w_ang/360 * tang * worm_starts * (left_handed?1:-1),
m = zrot(dir*rteeth*tang+g_ang_delta, cp=[worm_diam/2+pr,0,0]) *
g_ang_delta = w_ang/360 * tang * worm_starts * (left_handed?1:-1) *0 ,
m = //zrot(dir*rteeth*tang+g_ang_delta, cp=[worm_diam/2+pr,0,0]) *
left(crowning) *
yrot(w_ang) *
right(worm_diam/2+crowning) *
zrot(-dir*rteeth*tang+g_ang_delta, cp=[pr,0,0]) *
xrot(180)
) apply(m, point3d(pt))
//zrot(-dir*rteeth*tang+g_ang_delta, cp=[pr,0,0]) *
xrot(180),
pt = apply(m, point3d(pt)),
angled_pt = zrot((left_handed?-1:1)*360*pt.z*tan_helical/circum,pt,cp=[worm_diam/2+pr,0,0])
) angled_pt
]
],
midrow = len(rows)/2,