An immersed curve is a curve whose speed is always positive. CatRom assumes that its splines are immersed anywhere that Segment:SolveVelocity and Segment:SolveTangent are used internally (and really, in my head, I assume this to always be true). However, a spline with tension 1 has a speed of zero at times t = 0 and t = 1. Moreover, completely straight splines are susceptible to zeros in speed when the spline backtracks on itself, which happens with tensions outside of [0, 1].
This leaves us with three solutions:
- Gracefully handle non-immersed curves
- Disallow certain values of tension
- Do nothing and warn the user that bad things could happen when tension is outside of [0, 1) (seems like a footgun waiting to happen)
For option 1, a graceful way to handle non-immersion with Segment:SolveTangent is to introduce an internal "safe" version that computes a discrete approximation of the tangent. There's not a great way to make Segment:SolveVelocity safe, but given how it's used, I don't think it should be. However, "fixing" these problems feels wrong since the parametrization should always be immersed to begin with. The only exception would be unit-speed parametrizations, which are by definition immersed. But if we choose to gracefully handle unit-speed curves, then I suppose we should also gracefully handle non-unit-speed cases as well.
Bookkeeping
Note that we use Segment:SolveVelocity in
Segment:SolveTangent
Segment:SolveNormal
Segment:SolveCurvature
Segment:SolveTorsion
Segment:SolveCFrameLookAlong
getLengthIntegrand
Segment:_ReparametrizeNewtonBisection
and we use Segment:SolveTangent in
Segment:SolveNormal (on Vector2 splines)
Segment:SolveBinormal
Segment:SolveCFrameFrenet
Segment:SolveCFrameRMF
Segment:PrecomputeRMFs
Catrom:PrecomputeRMFs
An immersed curve is a curve whose speed is always positive. CatRom assumes that its splines are immersed anywhere that
Segment:SolveVelocityandSegment:SolveTangentare used internally (and really, in my head, I assume this to always be true). However, a spline with tension 1 has a speed of zero at times t = 0 and t = 1. Moreover, completely straight splines are susceptible to zeros in speed when the spline backtracks on itself, which happens with tensions outside of [0, 1].This leaves us with three solutions:
For option 1, a graceful way to handle non-immersion with
Segment:SolveTangentis to introduce an internal "safe" version that computes a discrete approximation of the tangent. There's not a great way to makeSegment:SolveVelocitysafe, but given how it's used, I don't think it should be. However, "fixing" these problems feels wrong since the parametrization should always be immersed to begin with. The only exception would be unit-speed parametrizations, which are by definition immersed. But if we choose to gracefully handle unit-speed curves, then I suppose we should also gracefully handle non-unit-speed cases as well.Bookkeeping
Note that we use
Segment:SolveVelocityinSegment:SolveTangentSegment:SolveNormalSegment:SolveCurvatureSegment:SolveTorsionSegment:SolveCFrameLookAlonggetLengthIntegrandSegment:_ReparametrizeNewtonBisectionand we use
Segment:SolveTangentinSegment:SolveNormal(on Vector2 splines)Segment:SolveBinormalSegment:SolveCFrameFrenetSegment:SolveCFrameRMFSegment:PrecomputeRMFsCatrom:PrecomputeRMFs