1
votes

Using a quaternion, if I rotate my cube along an axis by 90 degrees, I get a different front facing cube side, which appears as a straight-on square of a solid color. My cube has different colored sides, so changing the axis it is rotated along gives me these different colors as expected.

When I try to rotate by an arbitrary amount, I get quite the spectacular mess, and I don't know why since I'd expect the quaternion process to work well regardless of the angle:

enter image description here

I am creating a quaternion from 2 vectors using this:

inline QuaternionT<T> QuaternionT<T>::CreateFromVectors(const Vector3<T>& v0, const    Vector3<T>& v1)
 {
if (v0 == -v1)
    return QuaternionT<T>::CreateFromAxisAngle(vec3(1, 0, 0), Pi);

Vector3<T> c = v0.Cross(v1);
T d = v0.Dot(v1);
T s = std::sqrt((1 + d) * 2);

QuaternionT<T> q;
q.x = c.x / s;
q.y = c.y / s;
q.z = c.z / s;
q.w = s / 2.0f;
return q;
}

I think the above method is fine since I've seen plenty of sample code correctly using it.

With the above method, I do this:

    Quaternion quat1=Quaternion::CreateFromVectors(vec3(0,1,0), vec3(0,0,1));

It works, and it is a 90-degree rotation.

But suppose I want more like a 45-degree rotation?

    Quaternion quat1=Quaternion::CreateFromVectors(vec3(0,1,0), vec3(0,1,1));

This gives me the mess above. I also tried normalizing quat1 which provides different though similarly distorted results.

I am using the quaternion as a Modelview rotation matrix, using this:

inline Matrix3<T> QuaternionT<T>::ToMatrix() const
{
const T s = 2;
T xs, ys, zs;
T wx, wy, wz;
T xx, xy, xz;
T yy, yz, zz;
xs = x * s;  ys = y * s;  zs = z * s;
wx = w * xs; wy = w * ys; wz = w * zs;
xx = x * xs; xy = x * ys; xz = x * zs;
yy = y * ys; yz = y * zs; zz = z * zs;
Matrix3<T> m;
m.x.x = 1 - (yy + zz); m.y.x = xy - wz;  m.z.x = xz + wy;
m.x.y = xy + wz; m.y.y = 1 - (xx + zz); m.z.y = yz - wx;
m.x.z = xz - wy; m.y.z = yz + wx;  m.z.z = 1 - (xx + yy);
return m;
}

Any idea what's going on here?

1
I guess there is some kind of problem with your depth testing. It might pay to check it!SIGKILL
Not related, I don't think, but I can't see how that if (v0 == -v1) clause is supposed to work. If I want to rotate (1,0,0) onto (-1,0,0), how can a rotation around (1,0,0) ever produce the right orientation? For that matter, how can that work for any vector which is not perpendicular to the arbitrary (1,0,0) axis?JasonD
@JasonD good question. It's not my vector library, but one that is widely used.johnbakers
@SebbyJohanns widely used? That's worrying, if there are mistakes like that in there. Have you got a link?JasonD
@SebbyJohanns The original normalises the input vectors, with a note to say that this can be skipped if you know your inputs are already normalised (at least one of yours is not, in your example)JasonD

1 Answers

0
votes

What does your frustum look like? If you have a distorted "lens" such as an exceptionally wide-angle field of view, then angles that actually show the depth, such as an arbitrary rotation, might not look as you expect. (Just like how a fisheye lens on a camera makes perspective look unrealistic).

Make sure you are using a realistic frustum if you want to see realistic images.