Skip to content

Implement ParamCurveDeriv for Arc - #557

Open
tomcur wants to merge 2 commits into
linebender:mainfrom
tomcur:arc-deriv
Open

Implement ParamCurveDeriv for Arc#557
tomcur wants to merge 2 commits into
linebender:mainfrom
tomcur:arc-deriv

Conversation

@tomcur

@tomcur tomcur commented Mar 19, 2026

Copy link
Copy Markdown
Member

This solves a small part of #556. Namely: being able to compute the tangents of an elliptical Arc.

Similar to how e.g. CubicBez::deriv returns a QuadraticBez as a curve or how Line::deriv returns ConstPoint as a degenerate curve, even though the derivative actually is a tangent mapping, this implementation returns ArcDeriv as a curve. Numerically this implementation and the previous implementations are sound, but ParamCurveDeriv itself is muddying semantics a bit. We do document that already.

ArcDeriv is closed under repeated differentation.

Implementing ParamCurveDeriv gives the ability to use the result as a real object. Like the existing implementations, this makes it possible to find the second, third, etc., derivatives. You can compute the second derivative of an Arc as let arc_deriv2 = arc.deriv().deriv(), and use it to get at, e.g., the arc's curvature.

There's more detail in the discussion of the PR that triggered this, thinking of cleaner traits/types, and perhaps ways to get at tangents for curves that can't cleanly implement ParamCurveDeriv. This current PR intentionally does the simplest thing to make Arc differentiable.

This solves a small part of
linebender#556. Namely: being able to get
at the tangents of an `Arc`.

Similar to how e.g. `CubicBez::deriv` returns a `QuadraticBez` as a
curve or how `Line::deriv` returns `ConstPoint` as a degenerate curve,
even though the derivative actually is a tangent mapping, this
implementation returns `ArcDeriv` as a curve. Numerically this
implementation and the previous implementations are sound, but
`ParamCurveDeriv` itself is muddying semantics a bit. We do document
that already.

`ArcDeriv` is closed under repeated differentation.

Implementing `ParamCurveDeriv` gives the ability to use the result as a
real object. Like the existing implementations, this makes it possible
to find the second, third, etc., derivatives. You can compute the second
derivative of an `Arc` as `let arc_deriv2 = arc.deriv().deriv()`, and
use it to get at, e.g., the arc's curvature.

There's more detail in the discussion of the [PR that triggered
this](linebender#556), thinking of cleaner
traits/types, and perhaps ways to get at tangents for curves that can't
cleanly implement `ParamCurveDeriv`. This current PR intentionally does
the simplest thing to make `Arc` differentiable.
@waywardmonkeys

Copy link
Copy Markdown
Contributor

I've spent the last 2 days arguing about this with myself.

This has the advantage that some more code can work with arcs.

Should ArcDeriv be pub?

Should it have the same derives as our other similar types?

Should Arc now impl ParamCurveCurvature?

Should there be a test for an arc with negative sweep?

@tomcur

tomcur commented Mar 23, 2026

Copy link
Copy Markdown
Member Author

Should ArcDeriv be pub?

Yes (it is currently pub). With the current structure it has to be, otherwise ParamCurveDeriv for Arc is not usable, as the return type would be private.

Should it have the same derives as our other similar types?

Perhaps we should. If we do that and start treating an Arc's derivative as a first-class parametric object, then I'd be in favor of changing the ParamCurveDeriv for Arc introduced here to return another Arc, and remove ArcDeriv entirely. That's numerically consistent (ArcDeriv is just an Arc with statically-known zero center). In the current setup, users must promote an ArcDeriv into an Arc manually.

For simplicity, I'm slightly in favor of dropping ArcDeriv and letting the derivative just be an Arc.

Should Arc now impl ParamCurveCurvature?

Probably, yes. (As a separate discussion, it would be nice if ParamCurveCurvature would return an object for cheap evaluation.)

Should there be a test for an arc with negative sweep?

Yes.

@raphlinus

Copy link
Copy Markdown
Contributor

I'd also lean in favor of it just being Arc. It is cool that arc is closed under derivative - that's basically their jam (I believe logarithmic spirals are the other nontrivial curve family with this property). I think the statically known zero center is not worth the lift to encode in the type system.

I also agree that an acceleration structure for curvature would be worthwhile. I've been doing my own for the parallel curve work. But probably orthogonal to this PR.

@tomcur

tomcur commented Mar 24, 2026

Copy link
Copy Markdown
Member Author

It's now just Arc.

We can do the impl ParamCurveCurvature for Arc in a follow-up.

I also agree that an acceleration structure for curvature would be worthwhile. I've been doing my own for the parallel curve work. But probably orthogonal to this PR.

👍️

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.

3 participants