# Tag Info

24

Multiplication At least in terms of Unity's implementation of Quaternions, the multiplication order described in the question is not correct. This is important because 3D rotation is not commutative. So, if I want to rotate an object by rotationChange starting from its currentOrientation I'd write it like this: Quaternion newOrientation = rotationChange * ...

15

Where's the dot product used? In Unity, one of the most common users of the dot product is whenever you check if two quaternions are equal via == or !=. Unity computes the dot product to check similarity rather than directly comparing the internal x,y,z,w values. It's worth keeping this one in mind as it makes the call more expensive than you might expect it ...

13

You should probably use glm::angleAxis() (documentation here): glm::quat rot = glm::angleAxis(glm::radians(90.f), glm::vec3(0.f, 1.f, 0.f));

12

One of the visualization methods I like is to represent quaternion (orientation in 3d space) as vector (x,y,z components) + spin (the rotation around that vector, stored in w component). If you are looking for some online visualizer for quaternions, you can always use wolframalpha: http://www.wolframalpha.com/input/?i=quaternion%3A+0%2B2i-j-3k&lk=3 ...

9

I can think of two reasons: if your quats represent infinitesimal rotations, adding them together actually yields the composite rotation, provided the result is infinitesimal too (i.e. an element of that algebraic group). Quaternion addition, as opposed to multiplication, is commutative and, well, numerically fast. One situation where this might be "a thing"...

8

You are correct that a combined axis-angle representation like the one you describe has a stronger expressive power than many other systems because it can more conveniently store a rotation speed. However, in practice, people actually use quaternions and 3×3 matrices to manipulate rotations a lot more than just represent them. One typical operation is the ...

6

rotationVelocity += addedRotation is actually fine. Angular velocity is a vector and adds in the usual way. The part you may be missing is that in your description of the desired motion, you have a rotation around a constant axis (the global up-vector) combined with a rotation about a rotating axis (the ship's roll axis, which is rotating because of the ...

6

A more generic approach is detailed on Wikipedia. Essentially, that article explains there's no non-iterative method to find the generalized combination of N quaternions with weigths w_i. Nevertheless, if you can supply an approximation of that quaternion "mean", you can iteratively refine it using these update equations: So you could start with m_0 as ...

6

A quaternion can be thought of as an angle-axis representation: quaternion.xyz = sin(angle/2) * axis.xyz quaternion.w = cos(angle/2) So, converting them between two coordinate systems can be broken down into two steps: Map the axis into the new coordinate system. If changing between left & right hand coordinates (eg. if there's an odd number of axis ...

5

This is a late response, but I figured this question illustrates a common problem that many people are likely to run into and that deserves an answer. Quaternion rotation uses half the angle you want to rotate by. Since you (in this example case) are rotating by 90 degrees, the quaternion needs to calculate the sine and cosine of 45 degrees, both of which ...

5

Each orientation in 3D space can be represented by 2 distinct unit quaternions, q and -q (component-wise negated q). For instance the orientation represented by the 3x3 identity matrix I can be represented by 2 quaternions: q: { 0, 0, 0}, 1 -q: {-0, -0, -0}, -1 Both represent the same orientation in 3D space, their dot product is exactly -1, each of ...

5

"Is it wrong that I am counting total rotation and then creating [a] quaternion from it?" Yes, because rotations do not combine like simple addition. (In mathematical terms, rotations in three dimensions are not commutative) Here's an example you can do with any old mug. Turn it 90 degrees on the vertical axis, then flip it over away from you (finish ...

5

Euler angles aren't necessarily a good way of expressing limits over arbitrary ranges, as their behaviour close to zero is very different from their behaviour away from zero. Below I've visualized the forward, right, and up vectors of an object rotated with Euler angles over various ranges. Here yaw ∈ [-50, 50] and roll ∈ [-10, 10]. From left to right, I ...

5

From http://www.euclideanspace.com/maths/geometry/rotations/conversions/angleToQuaternion/ qx = ax * sin(angle/2) qy = ay * sin(angle/2) qz = az * sin(angle/2) qw = cos(angle/2) But since your vector represents the rotation, and is not the axis of rotation, we need to compute the angle. Your axis of rotation is just 0,1,0 angle = atan2( vector.x, vector.z ...

4

Since it seems acceptable, I’ll go for the following suggestion: just interpolate the quaternion components, then normalise the resulting quaternion. pro: it’s fast and the code is short pro: and there is no need to handle the case when the angle reaches 360 degrees and warps back to zero. con: you can still get singularities if the quaternions aren’t ...

4

The three component vectors right, up, and forward probably point along the axes x, y, and z relative to the camera. So by adding these vectors together you can compose any other vector. It works the same as if you built a vector by specifying its three elements individually, except that you are adding three vectors which each have one non-zero element. ...

4

It depends on the coordinate system you're working in. In a right-handed coordinate system (eg. x right, y up, z points toward the viewer), the right-hand rule applies, as mklingen describes in the existing answer. In a left-handed coordinate system (eg. x right, y up, z points away from the viewer), the left-hand rule applies - you point your left thumb ...

4

the glm::quat(float, float, float, float); constructor doesn't do what you think it does. It sets the values directly. The values of the quaternion (w, x, y, z) are in order: the cosine of half the angle, the sine of half the angle times the x coordinate of the normalized rotation axis, and the same for the y and z components. So instead you want to use ...

4

Taking a look at your barrel rotation function... relPos = (target.position - transform.position).normalized; rot = Quaternion.LookRotation(relPos, new Vector3(0,1,0)); relPos is in world space, so rot is an absolute rotation (ie. relative to the world coordinate frame) transform.localRotation = Quaternion.Lerp( transform.localRotation, rot, ...

4

Rounding. If you attach the debugger and look at the values of your quaternion: You'll see that the values are just too small to be displayed with one tenth precision, as the debug value is displayed. You can confirm this by looking at: Debug.Log(LeftTurnLimit.eulerAngles); This will output the initial value you put in : 0.1, 0, 0 To address the ...

4

You may translate the orbiting object with the coordinates of an elliptical path. You can get the x and y values from the equations. x = centerX + (semi-major * sin T) y = centerY + (semi-minor * cos T) Use some code like below: float alpha = 0f; void Update () { //transform.position = new Vector2(center.x + (semiMajor * Mathf.Sin(AngleX)), ...

4

To convert the Quaternion, we need to convert the imaginary part (xyz) which represents the axis of rotation into the destination coordinate system. In this case, that means exchanging x & y while leaving z unchanged. Then, because we've changed the handedness of our coordinate system, our angle takes the opposite sign (a +ve rotation in a right-handed ...

4

Yes, in fact that's what quaternions are often used for - interpolating between two different orientations. Other methods of representing orientation suffer from issues like gimbal lock and wrap-around. Left is quaternions, right is Euler angles https://answers.unity.com/questions/717637/how-do-you-smoothly-transitionlerp-into-a-new-rota.html For accuracy, ...

4

As per the unit circle math, angle 0 means "pointing right". Your initial orientation is up, at 90 degrees, so that's why you need to offset by 90 degrees so that your zero is at top, and -90 at right. You can just keep doing this, or rotate your model to be oriented towards right by default. I find that the best practice, as then you can just swap content ...

4

The results are not what you expect, but they are not wrong. It’s just that for a given orientation there are at least two “paths” through Euler angles that lead there. For instance, the identity quaternion is trivially converted to Euler angles [0,0,0]. But doing three 180-degree rotations around each axis leaves you in the same orientation, too. That ...

4

Gimbal lock occurs when your internal structure for storing/composing rotations uses a gimbal model: Image via Wikipedia, attributed: "By Lookang many thanks to Fu-Kwun Hwang and author of Easy Java Simulation = Francisco Esquembre - Own work, CC BY-SA 3.0" That is, when you construct your orientation as a sequence of component rotations with ...

4

Multiplying two quaternions gives you a quaternion equivalent to performing the two rotations they represent in sequence. q3 = q1 * q2 q3 * object = q1 * (q2 * object) // "Perform rotation q2 with respect to the world axes, then q1" // Or equivalently: "Perform rotation q1 about your local axes, then q2" q4 = q2 * q1 q4 * object = q2 * (...

3

Yes, you can transform the inertia tensor from one coordinate system to another. This can be done by multiplying the inertia tensor by the inverse of the desired coordinate transformation on the right, and the inverse transpose of the coordinate transformation on the left. (This assumes column-vector math; if using row-vector math, reverse the order.) In ...

3

EDIT: Just to clarify, I mean using a 3D vector to represent a rotation around an arbitrary axis, with the magnitude being the rotation. That is nearly what is saved in a quaternion only in a representation more useful to do calculations with it. So basically, using a vector/angle pair directly: is not very convenient for the machine and the ...

3

You could try slerping between A and B based on their relative weights, then slerping the result to C based on its weight. For instance, in your example, A and B have a total weight of 90%. Use this to normalize their weights to get A' = 66.7% and B' = 33.3%, so slerp from A to B by 33.3% (or B to A by 66.7%, equivalently). Then slerp from that result to ...

Only top voted, non community-wiki answers of a minimum length are eligible