I’ll be first in line to say I’m a slow learner, particularly in terms of math. I’m the sort of guy that will need facts banged home with a sledgehammer for at least half a year before they finally stick, and then 6 months more before they start mingling with the other facts and i start being able to combine things into new things. I’m not embarrassed about that; it’s just my class of brain. I have no real education to speak of so everything I’ve learned has been on a per-project basis; experiences.
Splines is one of those concepts I’ve only recently started futzing about with. Bezier splines are neat for drawing, and i use Catmull-Rom splines for smoothly interpolating sequences of keyframes in animation. They’re neat, useful things. A toy I’m working on uses user-drawn Catmull-Rom splines as the basis of lofting and revolving 3d geometry. It’s not exactly NURBS, but it’s definitely in the same realm. It’s fascinating as hell. One of the earliest issues i ran into was getting the normal of a given point on a spline. And this is where it gets retarded, and i start over-engineering.
Instead of looking at the bigger picture, i immediately start looking for one-stop solutions for spline normals. After banging my head into that for a while, i realize a spline tangent is a more common goal, and i start banging my head into that one as well. The lesson here is that you don’t need one-stop solutions, and you don’t always have to use the smartest stuff if what you do winds up working. Turns out the easiest and most practical way to get a spline normal on a catmull-rom spline segment is to do the following:
- Sample the point on the spline you want a normal for (p1)
- Sample another point (p2) on the spline slightly further along; for instance if p1 is at 0.5, sample p2 at 0.51
- Subtract p2 from p1: Bam, you have a unit vector (v) parallel to the direction of the spline at p1
- Get the normal to v by swapping and inverting its components.
Since you’re sampling *along* the spline, the normal won’t ever flip.
It’s such an epic facepalm moment. Why did i think about it so hard? When you take a couple steps back and look at the problem “physically”, it’s dreamily clear! I’m sure there are “smarter” ways to get this information, but aside from the double spline sample (which is just a bunch of multiplications anyway) the rest of it is lightweight enough to be negligible. Unless you’re doing this a shit ton of times for a lot of geometry, the approach i outline works just fine, even for real-time purposes. In my naive fanciful mind, the “proper” solution is this overwrought slow thing that takes longer to execute. That might be complete bull, but hey
I Googled this problem and found nothing this straightforward, so i hope it’ll help someone else too.
