refactor(curve): draw a fit spline and an offset preview from the curve
Two places were left describing geometry for themselves. A fit-point SPLINE was drawn from a C² cubic solved in spline.rs while TRIM and snap cut a separate interpolation from the kernel. Near enough to look right, far enough apart that a trim landed beside the line it was aimed at. It now draws the curve those commands work on, and falls back to the local solve only where the kernel declines — a fit spline through points in space is not a planar curve, so there is nothing for it to say. Closed fit splines were worse than that: the kernel's interpolation is a clamped solve with no wrap in it, so the curve TRIM used never returned to its start and the seam cut nothing. Repeating the first fit point closes it. The seam is C¹ where the rest of the curve is C², which is the honest limit of a clamped solve — the alternative was a curve with a gap in it. OFFSET's preview sampling had drifted the same way TRIM's had: an arc and a circle read `center.x/.y` as world coordinates when the entity stores them in its OCS, so an extruded one previewed on the wrong side; every curved kind was cut at a fixed twenty segments per radian whatever its size; and an ellipse rebuilt its axis frame from the major axis' X and Y alone, dropping the Z the entity stores. A hundred lines of that become one tessellation. A RAY now previews as far as an XLINE does rather than as a stub the length of its direction vector. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
90abfc21a9
commit
ece440bcab
4 changed files with 122 additions and 184 deletions
|
|
@ -685,6 +685,31 @@ mod tests {
|
|||
assert_eq!(hints(&snap, SnapHint::Quadrant).len(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_closed_fit_point_spline_comes_back_closed() {
|
||||
// The interpolation behind a fit-point spline is a clamped solve and
|
||||
// does not model a wrap, so without closing the point list the curve
|
||||
// ended somewhere else entirely — and a TRIM against it cut nothing
|
||||
// along the seam.
|
||||
let mut spline = SplineEnt::default();
|
||||
spline.degree = 3;
|
||||
spline.flags.closed = true;
|
||||
spline.fit_points = vec![
|
||||
v3(0.0, 0.0, 0.0),
|
||||
v3(10.0, 0.0, 0.0),
|
||||
v3(10.0, 10.0, 0.0),
|
||||
v3(0.0, 10.0, 0.0),
|
||||
];
|
||||
spline.normal = v3(0.0, 0.0, 1.0);
|
||||
let curve = entity_curve(&EntityType::Spline(spline)).unwrap();
|
||||
let (start, end) = (curve.point_at(0.0), curve.point_at(1.0));
|
||||
assert!(
|
||||
(start[0] - end[0]).abs() < 1e-9 && (start[1] - end[1]).abs() < 1e-9,
|
||||
"{start:?} vs {end:?}"
|
||||
);
|
||||
assert!(curve.is_closed());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn entities_that_are_not_curves_say_so() {
|
||||
assert!(entity_curve(&EntityType::Point(Default::default())).is_none());
|
||||
|
|
|
|||
Loading…
Reference in a new issue