Matrix stack from direction vector chain

I've implemented an IK system for a grabber arm based on several straight segments, starting from a fixed point. The IK is based on a mass-spring simulation, which eventually rests. What I'm left with is an array of positions in world space, one for each joint position, and an extra one at the end.

I need to convert these world positions into one quaternion rotation for each joint, so that I can build a hierarchy of transformation matrices (I'm using quaternion for the rotation part). each segment of the arm is an instance of a segment model that I want to translate into world space. The hierarchy works by inheriting previous rotations and translations. The issue I'm facing is describing each progressive joint rotation relative to the previous rotations (rather than relative to the world).

So far my approach is:

Initially the grabber arm point upwards, so the root rotation is described as the orientation difference from the vector (0, 1, 0) - (I'm using GL coordinates).

Keep the direction vector of the previous joint, prevDir, initially (0, 1, 0). Keep a quaternion of the accumulated rotations, rotChain, initially the identity quaternion. From root to tip, for each joint:

1. Take the next joint position and subtract the current position and normalize, to get a direction vector dir. This is why there's an extra point in the array, for the last joint
2. Compute the cross product between prevDir and dir, which should give a world rotation axis side, between the previous and current joint. Also compute the dot product, dot.
3. Rotate the side vector by rotChain, to bring it into the current joint's orientation.
4. Create a quaternion rot on the axis side and rotation acos(dot). This should represent the rotation of the current joint relative to the previous one.
5. Post-multiply rot onto rotChain, to add the effect of the current rotation.
6. Update prevDir to dir.

This only works as long as all the segments are on the YZ plane, which I think is a fluke. What am I doing wrong?

I'm only using quaternions as I'm trying to invert rotations easily. As per this answer, I get the sense I could instead directly derive an orientation matrix from dir and side. Would this work better?

migrated from stackoverflow.comDec 2 '15 at 19:30

This question came from our site for professional and enthusiast programmers.