Skip to main content

Module contour_lower

Module contour_lower 

Source
Expand description

Lower an arbitrary contour profile onto the arc-ring extruder (ADR 0053).

§Why this is an adapter, not new geometry

ContourProfile carries segments of any Curve2 kind. The arc-ring extruder already builds exact walls for the two kinds that matter here – Line2 becomes a planar wall, Circle2 becomes a cylindrical one – so lowering a contour to an ArcRing is a translation, not a construction.

A Polyline2 segment is exact too: one straight vertex per polyline vertex it passes (see lower_polyline).

Anything else is REFUSED rather than sampled. Tessellating an ellipse or a spline into short chords would produce a solid that looks right, passes every closure check, and silently is not the requested shape.

§Closure at Tolerance::ZERO (#250)

A ring is a cycle of vertices, each carrying the bulge of the edge that leaves it, so it is closed by construction: the vertex at a joint is ONE value, the end of the edge entering it and the start of the edge leaving it. It is the leaving segment’s start – a line’s stored origin bit for bit, an arc’s circle at its first parameter – and nothing is averaged or moved onto it.

The segments themselves cannot meet exactly in floating point, however carefully the producer shares its points (the section router computes every corner and tangent point once and hands that one value to both segments). A line stored as origin + t direction ends at origin + direction, which rounds, and its stored direction is already the rounded difference of the two points; an arc ends at the cos and sin of a transcendental sweep. No choice of Line2 or Circle2 makes both ends of every segment bit-exact. So the joint check compares the entering segment’s evaluated end with the leaving segment’s start against the larger of the caller’s tolerance and the rounding of those two evaluations: eight machine epsilons of the magnitudes they are computed from, a few ulps of the coordinates. That is what lets a section with non-dyadic sizes (IPE 300 left 2.6e-18 at the flange tip) lower at Tolerance::ZERO, while a contour open by more than its own rounding is still refused there. The check only decides WHETHER a ring is built, never what it is: a ring that lowered before is bit-identical, except at the vertices of an arc that land on a quarter turn (#379), below.

§Quarter turns evaluate exactly (#379)

At a quadrant parameter an arc’s cos or sin is the rounding of the parameter, not zero: for every form a producer writes (FRAC_PI_2, -PI / 2, 1.5 * PI, PI + FRAC_PI_2, TAU - FRAC_PI_2, …) |cos t| is 0.18 * t * EPSILON at the quadrants of a turn or two and up to 0.55 * t * EPSILON (at 20.5 * PI). That is the evaluation’s own error, but it decides whether an arc’s end lies on a revolution axis through its circle’s centre, which the exact revolution tests with an exact sign. A parameter within QUADRANT_ROUNDING * max(1, |t|) of a quarter turn therefore evaluates sin and cos as exactly 0 and +-1. This moves a point by less than the error of the point itself, and names no tolerance: a parameter further from the quadrant, by 1e-12 say, is its own angle. It is a rounding gate like the joint rule above, never reported. The vertices it moves are the arc’s ends and any split vertex (a sweep of a half turn or more is split) that lands on a quadrant; the joint rule reads the arc’s radius times max(1, |t|) in its scale (endpoint_scale), since the snap and an unsnapped sin_cos of a large parameter differ by that much.

Functions§

arc_ring_signed_area
Signed area of a bulge-encoded ring; positive when counter-clockwise.
contour_to_arc_ring
Convert one closed contour into an arc ring.
orient_arc_ring
Force a ring to the winding a boundary role requires.
reverse_arc_ring
Reverse an arc ring in place, preserving its arcs.