[Closed] Orientation along spline
Hi,
Is there any way to calculate the orientation as a quaternion along a spline, at vertices. I’m currently trying to export some data from splines using maxscript, and its working fine except for this problem.
I tried getting the tangents for a vertex using tangentBezier3D, (passing 0.0 as the float param, as the function works on segments, in order to get the tangent at the start of the segment i.e at the first vertex). As this returns a vector, i use arbAxis[font=‘Courier New’] [/font]to return a matrix.
Additionally, as this would essentially return the ‘forward’ orientation, i swapped the 2nd & 3rd rows of the matrix.
…but that didn’t even slightly work! So I’m now scratching my head trying to figure out another way to do this, but the only slight possibility I can think of at the moment is some hacky workaround using path constraints and snapshots or something.
Would really appreciate knowing how to correctly go about this, if anyone has a clue!
Thanks
cant you just build the tangential direction? (roughly)
p0 = lengthInterp spline 1 0.0
p1 = lengthInterp spline 1 0.1
z = (p1 – p0)
x = [1,0,0]
y = cross z x
x = cross z y
(orthogonalize (matrix3 x y z p0)) as quat
Its fine getting the tangent but the spin around the tangent is pretty much impossible unless it comes from some base reference. Because it could be anywhere – in my example is the x axis.
Plus the fact your gunna get issues with the binomial flipping, when the spline does odd shapes.
Thanks for your post. Unfortunately, the code snippet you posted doesn’t seem to return the correct quaternion (I tried plugging it into a test object’s .rotation property and, in addition to being incorrectly orientated, it was also positioned at a completely different location…)
My maths skills aren’t all that great tbh so I’m not really sure why this is going wrong, but if you have any suggestions (or anyone else for that matter), I’d love to hear them! I’ve spent a surprising number of hours on this today already…
Well… Simple version:
try(destroyDialog spRol) catch()
rollout spRol "Sline Matrix" width:180 height:80
(
fn setPositionOnSpline node: spline: index:1 pos:0.0 pathparam:on = if isvalidnode node and iskindof spline SplineShape do
(
pos = amin 1.0 (amax 0.0 pos)
p = interpCurve3D spline index pos pathparam:pathparam
a = tangentCurve3D spline index pos pathparam:pathparam
tm = arbAxis a
node.transform = translate tm p
)
spinner vParam "Spline Param: " range:[0,1,0] scale:0.01 type:#float align:#right offset:[0,4]
checkbox pParam "Contant Velocity" checked:on align:#left offset:[0,6]
fn setSplineMatrix = with undo off
(
setPositionOnSpline node:$matrix spline:$spline index:1 pos:vParam.value pathparam:(not pParam.state)
)
on pParam changed state do setSplineMatrix()
on vParam changed val do setSplineMatrix()
)
createdialog spRol
- Create SlpineShape and name it “spline”
- Create Any Node (Point helper with Axis ON for example) and name it “matrix”
and test.
It has to bihave exactly as Path Constaint (Follow = ON, Bank = OFF, Axis = Y)
The “orientation” will be rotationpart of $matrix.transform (tm in the main fuction).
if you want to get Bank effect it’s more complicated…
(clearlistener()
mapped fn createSplineBoxes s n =
(
l = curvelength s 1
len =(l-1)/(n-1)
col = red
for v in 1. to n-1 do
(
col.hue+=5
box pos:(lengthInterp s ( (v-1)/(n-1) ) ) \
width:2 height:len length:2 \
transform:(matrixFromNormal (lengthTangent s (v/n)) ) \
wirecolor:col
)
)
createSplineBoxes selection 50.
forceCompleteRedraw()
)
But all these examples uses a tangent, that is like a velocity vector, so depending on the method/interval, one might be less accurate than the other
Thanks for all your replies! I still haven’t actually figured this out, but given that I’m still unable to get the results I’m looking for, I’m starting to suspect my error may lie elsewhere in my code so I’m going to go through that now…
(Just fyi, what I’m actually trying to do is export a spine to a c++ openGL application I’m writing, so that I then can have an object follow it. I have everything working aside from the actual orientation along spline. Technically, the better/correct way of doing it would be to export the ‘up’ vector as a pseudo-spline to interpolate with along with spline, so I can build the orientation… which is actually what I’m doing now, but for some reason that I can’t see at all, the orientation works but is actually facing backwards & upside down… gah, i’ll figure it out hopefully!)
Anyway, thanks for all your help so far, really useful stuff for me
TBQH I don’t understand what can make it possible… What do you actually export? Snapshot of a spline or its Knots and their types, in and out Vectors… If last one – your math skills are very good!!!
Actually, the last one is what I’m doing! I make a copy of the spline and convert it to a splineShape (just in case it’s a shape), then fill arrays with position vertices and their in/out vectors. The maths to interpolate position along the spline it isn’t overly difficult, although I do recall it taking me a little while to work it all out…
I should perhaps mention that my opengl spline implementation only does vertex-length interpolation (length-interpolation would likely be too slow for realtime… plus, you know… extra maths :)), so requires pre-normalised splines for constant velocity. I suppose my math isn’t that bad (for a high-school dropout, anyway), its largely the matrix maths that i’ve never been fully been able to grasp despite my best efforts!
Anyways, enough rambling for now, I suppose I should get back to the problem at hand… still haven’t worked out why the orientation is coming out backwards/upside-down, as it happens!
I know now that you are pretty good in math. But your original post was not really MAX Script question. And I’m sorry if was rough a bit…
OK. You have a tangent. It’s a vector and it needs another vector to become the matrix.
You need the quat (angle + axis) which means the matrix. To make the matrix you have to pick a second vector. MAX developers use Z ([0,0,1]) as world UP… Maya and OpenGL developers usually take Y (theirs default world’s UP)…
MAX Script’s MatrixFromNormal() and arbAxis() are both using Z (UP) as second vector to make a matrix.
Yep basically, vector for the tangent, vector for the spin – build a cross product, rebuild the spin vector from the new cross product and orthogonalize the matrix. You can get the derivative to make the values along the curve uniform.
Whoops, forgot to check back here, looks like I missed some useful replies!
I’ve since managed to sort it out now actually, it feels so satisfying to see it smoothly orientated along the spline now, after all the bumbling around… oh well, no pain no gain, I guess
Thanks for all the advice anyway, was all useful stuff for me!