Skip to content

Fix the sampled domain of a periodic spline (bounding box reached the origin) - #1225

Open
redbluevn wants to merge 1 commit into
DomCR:masterfrom
redbluevn:moredwg/pr73-periodic-spline-domain
Open

Fix the sampled domain of a periodic spline (bounding box reached the origin)#1225
redbluevn wants to merge 1 commit into
DomCR:masterfrom
redbluevn:moredwg/pr73-periodic-spline-domain

Conversation

@redbluevn

Copy link
Copy Markdown

The problem

getStartAndEndKnots tests IsClosed before IsPeriodic:

if (this.IsClosed)          { uStart = knots[0];            uEnd = knots[^1]; }
else if (this.IsPeriodic)   { uStart = knots[this.Degree];  uEnd = knots[^(this.Degree + 1)]; }

A periodic spline forms a closed loop and therefore carries the closed flag too, so the periodic branch never runs and the domain is taken as knots[0] .. knots[last].

For an unclamped knot vector the domain starts at knots[degree]. Evaluating below it makes every basis function vanish, and PolygonalVertexes returns the zero vector for that sample.

What it costs

Measured on a periodic spline out of a real drawing — degree 3, 7 control points, 11 knots spanning 0..2, IsClosed = IsPeriodic = true:

CTRLBOX     (4021467.1, -9264141.7) .. (4021541.2, -9264045.6)
SAMPLED     256 points, zeros=1, at index [0]
BOX         (0, -9264141.7) .. (4021541.2, 0)

A spline about 59 by 74 units across reports a box four million by nine million, because one sample came back as (0,0,0) and BoundingBox.FromPoints honoured it. It lives inside a block, so every reference to that block inherited the box, and the drawing's extents with it.

After the fix, zeros=0 and the box is the spline's own (4021482.2, -9264138.8) .. (4021541.2, -9264067.2).

The fix

Ask about periodic first. The knot vector decides the domain; the closed flag does not override it.

Tests

New GetBoundingBoxOfAPeriodicSplineStaysOnTheCurve builds a periodic spline away from the origin and asserts the box stays within the convex hull of the control points — a property every B-spline has, and one the previous behaviour violated. It fails against the current implementation.

dotnet test on this branch: 2314 passed / 17 failed. master at 592d70a on this machine is 2313 passed / 17 failed — the same failures (SingleMLeader, GeoData, InsertWithSpatialFilter), plus the one test this PR adds.

Related

Found while reconciling computed extents with the extents AutoCAD reports for eighteen architectural drawings, alongside #1223 and #1224.

getStartAndEndKnots tested IsClosed before IsPeriodic. A periodic spline forms a
closed loop and so carries the closed flag as well, which meant the periodic
branch never ran and the domain was taken as knots[0]..knots[last].

For an unclamped knot vector the domain starts at knots[degree]. Evaluating
below it makes every basis function vanish, so the first sampled point came back
as the zero vector - and BoundingBox.FromPoints then stretched the box from the
spline all the way to the origin.

A drawing measured here has a periodic spline about 59 by 74 units across,
sitting four million units from the origin. Its bounding box was reported as
(0, -9264141) to (4021541, 0). It sits inside a block, so every reference to
that block inherited the same box.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@redbluevn
redbluevn force-pushed the moredwg/pr73-periodic-spline-domain branch from 4a13687 to bd05822 Compare September 5, 2026 07:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant