3

I have recently been reading about quaternions and was wondering if it is possible to create a system which allows you to create a twist system which doesn't flip at +/-180 and allows for 360 degree twisting?

Every test I've done keeps coming back to calculating an angle between two vectors which always gives you an angle between 0 and 180.

If you're unsure of exactly what I'm looking for then this video from Jorn-Harald Paulsen should make it clear, I'd like to do it with quaternions but I'm not sure what method he uses.

I've read Felix Joleanes' article on his website about preventing flipping, he has a section dedicated to a twist setup, but it's more like an aim/lookAt constraint and this setup wouldn't work for distributing twist along for multiple joints. It's also depends on using some tricks/hacks with Euler angles which I would rather avoid in favour of quaternions.

Peter O.
  • 32,158
  • 14
  • 82
  • 96
Hazmondo
  • 31
  • 2

4 Answers4

1

The quaternions

q = cos(t/2) + (u_x i + u_y j + u_z k) sin(t/2)

give a smooth mapping of angles to rotations. At 360 degrees, you have q = -1 but that doesn't matter when you map the quaternion to a rotation; the rotation is just the identity, exactly what you want it to be. There is no "flip" in the rotation. So I don't understand what the problem is ...

Edward Doolittle
  • 4,002
  • 2
  • 14
  • 27
  • OP is interested in a representation which has the gimbal-less behavior of quats but can be specified to rotate past +/- pi, I think – theodox Jun 23 '15 at 18:31
  • That would be quaternions ... they can rotate past +/- several gazilion. I think he's just constructing the quaternions incorrectly. If he uses the formula I gave to construct quaternions, everything will be all right. – Edward Doolittle Jun 24 '15 at 00:17
  • 1
    From the linked material and context it sounds like what he wants is to be able to have an transform that both smoothly interpolates between other rotations -- but can also be over-driven , eg, to rotate N times around one axis or something. Quat could display any point in that interpolation but he have to track the total over-driven rotation separately and convert it to quat at each sample, the quat won't preserve the notion of multiple revolutions over time. Your formula would definitely do the conversion but he'd have to provide the interpolation on his own if I'm reading it right. – theodox Jun 24 '15 at 05:54
  • Ah, I think I understand, then. A 720 degree rotation divided into 10 steps is 72 degrees each, but quaternion interpolation would see the rotation as 0 degrees and each of the 10 steps would also be 0 degrees. He could keep track of the angle instead of the rotation, so 720 instead of q=1, or he could keep track of the slowest rotating part then the other 10 would be q^2, q^3, ..., q^10. – Edward Doolittle Jun 24 '15 at 06:34
  • Imagine you have a piece of rectangular cloth (such as a ribbon), one end of the cloth is attached to an object and the opposite end is attached to another. When the objects move apart the cloth is pulled taut and the surface normals of the cloth all point in the same direction. When one of the controls is rotated 360 degrees along an axis running down the centre of the cloth, the normal vector at the middle of the cloth rotates 180 degrees along the same axis, this is what I want but I want to orient the control in any way and only get the rotation in the axis down the centre of the "cloth". – Hazmondo Jun 24 '15 at 22:49
  • If the control is the part of the cloth that rotates least (but still rotated a little) by a quaternion q, then the other parts of the cloth will rotate by q^2, q^3, etc. All easy to calculate within the framework of quats alone. Going the other way (starting from part of cloth that rotates most) you need to calculate roots of quats, much harder. It can be done if you pull back to angles, but it's really hard in quat algebra. – Edward Doolittle Jun 24 '15 at 23:36
0

Quaternions represent "Orientation" , angular position in space. But it can't represent 360 degree "rotation" as orientation changing during time.

If you want to represent angular motion (rotation) about fixed axis you can use "Axis Angle" representation https://en.wikipedia.org/wiki/Axis%E2%80%93angle_representation

or "exponential map" https://en.wikipedia.org/wiki/Rotation_group_SO(3)#Exponential_map

If your axis of rotation fit to frame axis , than you can use "Euler angels"

All this representations can be converted to quaternions or rotation matrices.

minorlogic
  • 1,872
  • 1
  • 17
  • 24
0

I've recently developed a twist extraction algorithm in our project. I'll just describe it and you decide if it's what you need.

Assume we have an arm, its two ends called E1 and E2, whose orientations are described in quaternions. When E2 is rotated around the arm direction for angle r, we expect E1 rotates f*r.

Let's see why the flipping occurs (assume f = 0.5 in this example). At some point, E2 may have been rotated for 170 degree, which means E1 is rotated for 85 degree.

Then we continue to rotate E2 for 20 degree, as f is 0.5, we expect E1 to rotate 10 degree, results in a 95 degree rotation. But quaternion can't represent a 190 degree rotation of E2, it tells us E2 is actually rotated for -170 degree, so E1 ends up in a -85 degree rotation. Compared with its former 85 degree rotation, it's a flipping.

Obviously, flipping only occurs when you have a 'reference angle'. In our example, 'reference angle' is 85 degree. We have no way to prevent quaternion giving a -170 degree result, but utilizing the information of reference angle can fix the flipping.

Before we multiply -170 by 0.5, we should check current rotation angle of E1, which is the reference angle, 85 degree. Divided by 0.5, we'll know in last frame, E2 has a rotation of 170 degree. Then we add n*360 degree to -170 to make it as close to 170 as possible. This procedure can be done using remquo in C++.

float FindClosestEquavilentAngle (float angle, float reference)
{
    int cycle = 0;
    remquo(reference - angle, 360, &cycle);
    return angle + 360 * cycle;
}

This function converts -170 degree to 190 degree. Now we can multiply 190 by 0.5, and apply the result to E1.

This works in my case.

Bei
  • 71
  • 6
0

If you want to represent your rotations using quaternions as opposed to angles, then you will always have the problem you encountered. Here's a simple example: suppose you start working on your program when the clock says 10, and you finish when the clock says 12. When are you halfway done? Most people say 11, but if you start at 10 pm and finish at 12 noon you were halfway done when the clock says 5 (7 hours through a marathon 14 hour session).

The point is, there's no way of telling which is the correct answer from the given data. Similarly, there's no universal way of correctly interpolating half a rotation, or a third of a rotation, or whatever.

If you want a quaternion-only solution, I suggest "extrapolating" instead of interpolating angles. That is, set the control element to be the element which turns or moves the least, then let all the others be multiples of the quaternion representing the minimal rotation. So if q is the smallest twist, closest to the socket of the arm, q^2 rotates twice as far, q^3 rotates three times as far, and so on.

Edward Doolittle
  • 4,002
  • 2
  • 14
  • 27