Smoothness and derivatives for (cubic) curves#14306
Closed
mweatherley wants to merge 31 commits intobevyengine:mainfrom
Closed
Smoothness and derivatives for (cubic) curves#14306mweatherley wants to merge 31 commits intobevyengine:mainfrom
mweatherley wants to merge 31 commits intobevyengine:mainfrom
Conversation
This was referenced Jul 16, 2024
Contributor
Author
|
Closing in favor of #16503 for now, which makes much less sweeping changes. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is another prototype as part of the Curve project. Once again, I have ignored NURBS for the time being.
Objective
Provide a general framework for expressing smoothness for curves (up to C2) and integrate it with
bevy_math's existing cubic spline constructions.Solution
Continuous/differentiable curves
There are a few layers here. At the most basic level, we have a trait-enshrined way of expressing tangent spaces at the level of types:
The point of this is that it is used to define types
WithDerivative<T>andWithTwoDerivatives<T>that pair a point with derivatives at that point (elements of the tangent space). For example:Now, the central idea connecting this to curves is that a differentiable curve is a curve that returns
WithDerivative<T>when sampled, so that thepointcomponent provides the position andderivativeprovides the velocity. We have introduced some new traits that work this way: they are just marker traits on top ofCurve<...>:Of course, with these traits, it's worth keeping in mind that they will not be preserved by the abstract
Curveinterface methods. For example, applyingCurve::mapto a differentiable curve, the result need not generally be differentiable. The same is true for many operations, including simple ones likecompose(which joins two curves end-to-end).On the other hand, the result of calling such functions may actually be continuous, differentiable, and so on. To bridge this gap in expressivity, we have also introduced a wrapper struct
Blessedand a methodblessthat produces it so that the user can explicitly elevate to the level of these marker traits when necessary:Cubic segments and curves
The interoperation of cubic curves with this new technology comes in a few parts. Firstly,
CubicCurvehas an additional marker type parameterS: Smoothnesswhich indicates the global guarantees of smoothness that issue from the curve's construction. This parameter has four levels:Nothing,C0,C1, andC2.CubicCurve<P, S>is itself aCurve<P>, sampling from its position. If itsSmoothnessparameter is at leastC0, then it is aContinuousCurve.CubicSegment<P>is similar, but it is always aContinuousCurve(it has noSmoothnessparameter).To access higher derivative information through the
Curveinterface, there are a pair of new methods on bothCubicSegmentandCubicCurve:CubicCurveis similar. The wrapper typesSegmentDerivativeandSegmentTwoDerivatives(truly inspired nomenclature) implementDifferentiableCurveandTwiceDifferentiableCurverespectively. Similarly, the wrapper types forCubicCurve—CurveDerivativeandCurveTwoDerivatives— implementDifferentiableCurveandTwiceDifferentiableCurveif the underlyingSmoothnessparameter is at leastC1orC2respectively.Putting it together
For starters, we can use the Curve interface pretty seamlessly in conjunction with cubic splines:
For something more complex, let's imagine we have some geometric operation which wants a differentiable curve as input and produces some output:
For a cubic curve, we could do something like this:
On the other hand, if I specified my inputs with
CubicBezierbut I made sure it's differentiable using the folds of my brain (or am willing to accept the consequences of doing something weird), I can use theblessinterface to work with it:Migration Guide
Some existing uses of the
CubicCurvetype will need to be annotated with aSmoothnessparameter in order for the program to compile. This is becauseCubicCurvenow tracks its global continuity and differentiability guarantees. For similar reasons, existing uses ofCubicCurve::push_segmentorExtend::extendwill require first callingCubicCurve::without_smoothnessin order to destroy the smoothness guarantees from the curve's construction, since arbitrary concatenations of curve segments cannot be known by the compiler to maintain these guarantees.