Extending Splines and Calculating Curvature

   8169   3   1
User Avatar
Member
45 posts
Joined: March 2010
Offline
Hey guys,

So, I've been working on trying to implement parts of Cinema4D's “MoSpline” into Houdini - if you're not familiar with it, it's a nifty tool that, among other things, provides a very artist-friendly way of creating all sorts of lovely spliney spirally shapes. I'm not a Cinema4D guy at all, so it's hard for me to determine what's going on “under the hood,” but… it's been fun trying to figure out how to recreate a lot of those features in Houdini. And I'll have a bunch more questions about other parts of that in the not-too-distant future.

One of the very neat things about MoSpline is its ability to extend a spline past its endpoints, in either direction; and there are some controls, as I understand them, for the amount of “curve” (how much of the curvature to inherit in the extension), “spiral” (how much of additional spirally behavior should be inherited from the curvature), and “scale” (width-wise) that govern the behavior of the extended portion of the spline.

So, I'm trying to break this apart, and figure out how to best create this kind of control in Houdini. Would love any suggestions or pointers. Specifically, I'm having trouble figuring out how to stably calculate the curvature of the last segment of the spline.

Provided I have a curvy spline with a bunch (say, 100) of resampled segments, with each point oriented properly and consistently (parallel frame transport), I'm able offset, orient, and then use the stitch or join tools to connect another line with G2 continuity. That's cool. And then I can recursively “march” the points on the line through a loop that rotates each point relative to the previous point by a certain angle, as per… one of the examples that ships with Houdini, can't remember which, but it's a good one. Also neat. I get spirally spirals that continue for as many line segments as I have.
(I feel like there must be a way to use CHOPs to achieve a similar effect, possibly without having to use a second curve - I'd love to hear what anyone has to say in this regard, because I really need to work on my CHOPs chops)

Ideally, I'd like to be able to use the curvature of the last bit of my initial spline to dictate the angle for the extended bit. If I'm understanding, say, b-splines correctly, isn't the curvature of the endpoints intrinsically calculated? Is there a way to access that?

Otherwise, what I've been doing is normalizing the difference between the positions of the next and current points, and the current and previous points, and taking the acos of the dot product those (normalized) vectors. This works fine, for the most part, UNLESS the last two points are in different cartesian coordinate… err, quadrants, I guess you would call them - eg, if the sign of one of the position vector components is different between the two normalized vectors, it throws my whole acos(dot(v1,v2)) thing out of whack. So, is there a better way I could be calculating endpoint curvature?
*edit: i can't seem to recreate my own problem. Anyway, see below.

Thanks!
Edited by - Sept. 21, 2013 23:14:36
User Avatar
Member
45 posts
Joined: March 2010
Offline
Decided to be a bit more specific about the curvature thing. There's something off with my algorithm.

Does anyone know how the Measure SOP measures curvature (of curves)? It seems to depend quite heavily on how the normals are oriented; whereas my method is only concerned with the relative position of the points.

Here's some point wrangle code:

vector prev = normalize(@P-point(@OpInput1,“P”,@ptnum-1));
vector next = normalize(point(@OpInput1,“P”,@ptnum+1)-@P);
f@mycurve = 9e99; //inf
if( (@ptnum != Npt-1) && (@ptnum != 0))
@mycurve = degrees( acos( dot( prev,next)));


The interesting thing is, depending on how I calculate normals for the curve (eg, various modes on with a PolyFrame SOP, or a custom Python node to use the Parallel Frame Transport method, or that awesome “Tangent” digital asset from the old asset exchange), the Measure SOP will give me different results, which isn't so surprising. But what is surprising is that my calculations are off by a consistent factor, if all my points lie on the same plane.

If I use a Measure SOP to calculate a “curvature” attribute prior to the above point wrangle, I can calculate the ratio between my algorithm and SESI's:

f@ratio = degrees(@curvature) / @mycurve;

And, depending on the normal orientation, with my current curve, it'll either consistently be a ratio of ~3.125 or ~6.25.

Of course, the story is totally different if my curve spans three dimensions. That ratio changes accordingly as the normal in the Y-direction deviates from 0.

I've attached an example file too. If for some reason, the embedded digital assets don't work, you can just set the “switch_normals_calc” sop to 0, and it'll use a plain old facet and a polyframe to calculate normals.


Short version: How does the Measure SOP calculate curvature of curves? What am I doing differently?

Attachments:
curvature_question.hipnc (239.7 KB)

User Avatar
Member
517 posts
Joined: Dec. 2013
Offline
Okay this is a super old post but I have to say thanks for putting it up here!
I just spent way too long trying to get the measure sop to work for me and your simple wrangle did the job perfectly!



Thanks!
Pete
User Avatar
Member
20 posts
Joined: Nov. 2013
Offline
7 years after the original, this came in handy for me too. Quick note had to fix the “” marks in the point wrangle (just delete and retype) and had to change Npt to @Npt. (houdini 15.5) Thanks!
  • Quick Links