# Quaternion rotation gives me oppostie z-value?

This topic is 4967 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hello, If i rotate a point P around two points P1 and P2, I get the good x and y values, but the opposite z-value. Here is my psuedo code. I dont know what is wrong. I checked everything a 1000 times. I hope there is a quaternion specialist online. Vector3D axis=P2-P1; Quaternion q; q.setFromRotation(axis, angle); q.rotate(P); void Quaternion::setFromRotation(const Vector3D& axis, float angle) { float sin=sinf(angle*0.5f); m_vector.setXYZ(axis.getX()*sin, axis.getY()*sin, axis.getZ()*sin); m_scalar=cosf(angle*0.5f); normalize(); } Vector3D Quaternion::rotate(const Vector3D &src) { // v' = q * [0, v] * con(q) Quaternion v(src, 0.0f); Quaternion tmp; tmp=*this; tmp.conjugate(); v.product(v,tmp); tmp.product(*this,v); return tmp.m_vector; } Thx

##### Share on other sites
You might post your conjugate and mult functions also, just to make sure they're right (unless you already know they're correct).

What axis are you using for testing? It's quite possible that the quaternion is rotating your vector in the opposite direction than you expect. If your test axis is [0 1 0], this might have the effect of negating z.

If instead you used [0 0 1] as your test axis, the z value shouldn't change at all, regardless of direction of rotation. So if your z is negated in that case, there may be something wrong with your other functions.

So, perhaps you could post those other two functions, and tell us what axis you're rotating around.

##### Share on other sites
You are right. If i rotate around (0,0,1), it gives the correct z value.
How does it come that if you rotate around the (0,1,0) axis that you get negative z value. Even if i negate the angle for the rotation, it keeps giving the opposite z-value.
I use the quaternion class also for my arcball implementation and there the rotations are perfect.

In my application, i have to rotate a 3d point around the common edge of two polygons A and B.
So my rotation axis is defined by the difference of the two vertices that form that common edge. AxisRot=Vertex1-Vertex0. rotationangle=acos(dotproduct(A.normal, B.normal)).

Vector3D axis=p1-p0;
q.setFromRotation(axis, rotAngle);
Vector3D newp=q.rotate(p);

Quaternions are cool if they work properly :-)

Here are my other function:

void Quaternion::conjugate()
{
m_vector= -(m_vector);
}

void Quaternion::product(const Quaternion& q1, const Quaternion& q2)
{
m_scalar=q1.m_scalar*q2.m_scalar-Vector3D::dotProduct(q1.m_vector, q2.m_vector);

Vector3D cross;
cross.crossProduct(q1.m_vector, q2.m_vector);

m_vector=q2.m_vector*q1.m_scalar+q1.m_vector*q2.m_scalar+cross;

normalize();
}

##### Share on other sites
Quote:
 How does it come that if you rotate around the (0,1,0) axis that you get negative z value. Even if i negate the angle for the rotation, it keeps giving the opposite z-value.
Negating the angle of rotation about axis [0 1 0] should result in either the x or z component of the rotated vector changing signs. So depending on the original vector and the angle of rotation, negating the angle could leave z unchanged and reverse the sign of x instead. So does x change signs when you negate the angle?

Perhaps you could give us a concrete example. Tell us what the axis and angle are, what the original vector is, and what the output vector is. Maybe give two or three different examples. That would make it easier to figure out what the problem is.

##### Share on other sites
Quote:
 Original post by takisSo my rotation axis is defined by the difference of the two vertices that form that common edge. AxisRot=Vertex1-Vertex0. rotationangle=acos(dotproduct(A.normal, B.normal)).Vector3D axis=p1-p0;

Are you sure your axis is normalized? Your setFromRotation() doesn't do that for you, and I guess your normalize() works on the full quaternion.

##### Share on other sites
jyk, you are right. If i negate the angle, then x-value changes sign.
Hopely you guys can help me.

An example:

Vector3D p0(2,3,10);
Vector3D p1(2,4,10);
Vector3D p(-2, 2, 10);
Vector3D axis=p1-p0;
axis.normalize();

q.setFromRotation(axis, MY_PI);
Vector3D newp=q.rotate(p);

Result is: (2, 2, -10)

##### Share on other sites
Quote:
 Original post by takisAn example:Vector3D p0(2,3,10);Vector3D p1(2,4,10);Vector3D p(-2, 2, 10);Vector3D axis=p1-p0;axis.normalize(); q.setFromRotation(axis, MY_PI);Vector3D newp=q.rotate(p);Result is: (2, 2, -10)

This result is correct, but probably not what you want.
What you ask it to do is a rotation around the line with direction given by axis, *passing through (0,0,0)*. You probably want some translations to get a rotation around the line passing through p0 and p1...

Try this:

Vector3D newp=q.rotate(p - p0);
newp += p0;

##### Share on other sites
The result is now : (6,2,10).

Shouldn't that be (2,2,10)?

##### Share on other sites
Quote:
 Original post by takisThe result is now : (6,2,10).Shouldn't that be (2,2,10)?

No, that seems correct. (If I have understood correctly what it is you want to do...)

Vector3D p0(2,3,10);
Vector3D p1(2,4,10);
Vector3D p(-2, 2, 10);
Vector3D axis=p1-p0;

could all be translated by (-2, -3, -10) to give:

Vector3D p0(0,0,0);
Vector3D p1(0,1,0);
Vector3D p(-4, -1, 0);

When p is rotated by π around the y-axis it should become (4,-1,0).
Translating it back (by adding (2, 3, 10)), it becomes (6, 2, 10).

##### Share on other sites
thank you very much. I think i understand it.
Instinctive (sorry dont know the english word for it) you would say that the correct result is (2,2,10).
I wanna thank everyone who have helped me with my quaternions ;)

Greetings
takis

1. 1
2. 2
3. 3
Rutin
15
4. 4
5. 5

• 14
• 9
• 9
• 9
• 10
• ### Forum Statistics

• Total Topics
632912
• Total Posts
3009197
• ### Who's Online (See full list)

There are no registered users currently online

×