PDA

View Full Version : Rotating object



3DPrgmer
12-26-2016, 03:05 AM
Hi,

How would i rotate an object always that way i'm looking at it?

Example: dice

3
1265
4

^y
|
+->x


We are looking at 1 (so right of it is the 2, left the 5, behind 6, upside 3, downside 4)
And when i press my mouse move from left to right, i want to see the 5. When moving the mouse upside down i want the 3,...

That's no problem this code can do it:

void OglViewerWidget::mouseMoveEvent(QMouseEvent *e)
{
if (m_mouse.left)
{
// get the difference between last press and now
QVector2D diff = QVector2D(e->localPos()) - m_mouse.position;

// update the new position
m_mouse.position = QVector2D(e->localPos());

// calculate the rotation axis and rotate
QVector3D rotationAxis = QVector3D(diff.y(), diff.x(), 0.0).normalized();
m_rotation *= QQuaternion::fromAxisAndAngle(rotationAxis * 0.75, diff.length());

// request an update
update();
}
}

But the problem is, when i rotate the model in y direction (upside down) 180 (you can see the 6 upside down) and then i move the mouse from left to right, it rotates in the opposite direction it should move.

Any help about how to fix that??

Harukoxd
12-26-2016, 07:38 AM
As you can see in the following link:

http://quaternions.online

When you rotate a quaternion the sign change for every turn around the rotation's axis.

m_rotation *= QQuaternion::fromAxisAndAngle(rotationAxis * 0.75, diff.length());

Always work with normalized vectors! That * 0.75, remove it.

Also this: QVector3D rotationAxis = QVector3D(diff.y(), diff.x(), 0.0).normalized();

Why are you doing it like that? Take a look at this:

Rotate UP FRONT: Quaternion(Vector3(1,0,0), ToRadians(90))
Rotate UP SIDE: Quaternion(Vector3(0,0,1), ToRadians(90))
Rotate DOWN FRONT: Quaternion(Vector3(1,0,0), ToRadians(270))
Rotate DOWN SIDE: Quaternion(Vector3(0,0,1), ToRadians(270))
Rotate Right: Quaternion(Vector3(0,1,0), ToRadians(90))
Rotate Left: Quaternion(Vector3(0,1,0), ToRadians(270))

Use them in the next way(to rotate left):

m_rotation *= Quaternion(Vector3(0,1,0), ToRadians(270))

If you want to move it a specific radius:

DistanceToRotate = (PointA - PointB).length();

m_rotation *= Quaternion(Vector3(0,1,0), DistanceToRotate )

Also take as default rotation: Quaternion(0,0,0,1)

Also i see that you are not catching right how to obtein a axis from the object's perspective. Ill place here some examples:


Vector3f GetForward() const
{
return Vector3f(0, 0, 1).Rotate(*this).Normalize();
}

Vector3f GetBack() const
{
return Vector3f(0, 0, -1).Rotate(*this).Normalize();
}

Vector3f GetUp() const
{
return Vector3f(0, 1, 0).Rotate(*this).Normalize();
}

Vector3f GetDown() const
{
return Vector3f(0, -1, 0).Rotate(*this).Normalize();
}

Vector3f GetRight() const
{
return Vector3f(1, 0, 0).Rotate(*this).Normalize();
}

Vector3f GetLeft() const
{
return Vector3f(-1, 0, 0).Rotate(*this).Normalize();
}

Vector3f Vector3f::Rotate(const Quaternion & rotation) const
{
Quaternion conjugateQ = rotation.Conjugate();
Quaternion w = rotation * (*this) * conjugateQ;
return Vector3f (w.x, w.y, w.z);
}


You can use this axis instead of the world axis if you want to rotate respect this ones.