Interesting. (hurries to check his own code for this problem....whew!)
My usage of this technique is (thankfully) insulated from this little
quirk.
I believe the problem is that using
Quaternion qD(a, b)
where a and b point in opposite directions leads to an ambiguity.
Suppose a and b are as you describe, (0, 1, 0) and (0, -1, 0). You can
rotate a into b by rotating 180 degrees around the x axis. You can also
do it by rotating around the z axis. The choice is arbitrary, and in
this case the code gives you an incorrect answer.
Take a look at the code for QuaternionBase::setValue(VectorType& from,
VectorType& to).... in 1.8 its at line 360 of OSGQuaternion.inl. There
are two checks - for parallel vectors and for anti-parallel vectors. In
the latter case there is a section which attempts to choose an axis to
rotate around.
I suppose the better solution here is Gerrit's.... or possibly just using
rotation.setValueAsAxisDeg(frontVec, angle);
for your rotations.
dan
Sebastian B. wrote:
> Thank you for your answere.
> I implemented your code and got almost the result i hoped for.
> There is one problem:
> I have a plane-modell and i calculate the axes for direction-vector,
> up-vector and side-vector in a way that i get an orthogonal coordinate
> system. To rotate the plane from origin into this coordinate-system i
> use your method implemented as shown beneath.
> This works well except if the planes-direction is the same as the
> world-x-axis and the up vector is (0, -1, 0) - than that the plane is
> rotated around his direction vector 180 degrees. Than instead of
> pointing as expected in the same direction, it ist turned around
> pointing to the oposite direction.
> The method fails in some other situations too. I'm not sure on which
> vector it depends.
>
> I could solve my problem using the method posted from Gerrit Voss on
> 02/28/08 and 03/04/08.
> But i am interested why this method is not working.
>
> OSG::Quaternion Mathematic::lookAt(OSG::Vec3f direction_new, OSG::Vec3f
> up_new)
> {
> OSG::Vec3f direction_old(1.0f, 0.0f, 0.0f);
> OSG::Vec3f up_old(0.0f, 1.0f, 0.0f);
>
> OSG::Quaternion qD(direction_old, direction_new);
>
> OSG::Vec3f up_temp;
> qD.multVec(up_old, up_temp);
>
> OSG::Quaternion qU(up_temp, up_new);
>
> OSG::Quaternion qResult;
> qResult = qU;
> qResult.mult(qD);
>
> return qResult;
> }
>
> void FlightState::rotateAroundFrontVector(float angle)
> {
> OSG::Quaternion rotation;
> rotation.setValueAsAxisDeg(frontVec, angle);
> rotation.multVec(upVec, upVec);
> rotation.multVec(downVec, downVec);
> rotation.multVec(leftVec, leftVec);
> rotation.multVec(rightVec, rightVec);
>
> // quaternionRotation is used to rotate the plane
> quaternionRotation = Mathematic::lookAt(frontVec, upVec);
> }
>
> void FlightState::rotateAroundUpVector(float angle)
> {
> ...
> }
>
> void FlightState::rotateAroundRightVector(float angle)
> {
> ...
> }
>
>
> Kind regards
>
> Sebastian B.
>
>
> Daniel Sperka schrieb:
>
>> IIRC, this is similar to the transforms done in the billboards. I
>> recently needed something similar to what you describe.
>>
>> First, I'll try to refer to the "direction" and "up" vectors, either the
>> "old" or "new". You're seeking a transform which takes you FROM the "old
>> direction and up" TO the "new direction and up".
>>
>> The quaternion you require is the product of two quaternions.
>>
>> One quaternion, call it qD, represents a rotation FROM the "old
>> direction" vector to the "new direction" vector. The second quaternion
>> takes care of the fact that qD does NOT necessarily rotate the "up"
>> vector correctly.
>>
>>
>> Vec3f direc_old, direc_new; // assume these get their values in
>> Vec3f up_old, up_new; // your code somewhere
>>
>> ...
>> ...
>>
>> Quaternion qD(direc_old, direc_new);
>>
>> // Now apply this transform to the "old up" vector
>>
>> Vec3f up_temp;
>> qD.multVec(up_old, up_temp);
>>
>> // Make a second quaternion which rotates up_temp into the "new up"
>> vector.
>> Quaternion qU(up_temp, up_new);
>>
>> // The result is the product of these quaternions
>> Quaternion qResult;
>> qResult = qU;
>> qResult.mult(qD);
>>
>>
>> Can't say that this code will compile ;). I've paraphrased my own
>> algorithm.... which does something similar but not quite the same. I
>> must say that exercise really taught me how to use quaternions!
>>
>> It took me a while to convince myself this was right. Think of the
>> qResult as the product of two transforms: first you transform the
>> direction/pointing vector, then you apply the "up" transformation. The
>> "up" transformation doesn't affect the first transform because it is
>> really a rotation around the direction vector!
>>
>>
>> Hope this helps!
>>
>> Dan
>>
>>
>>
>>
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Microsoft
> Defy all challenges. Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> Opensg-users mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/opensg-users
>
>
--
Daniel J. Sperka, Ph. D.
UC Davis Center for Neuroscience
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Opensg-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-users