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

Reply via email to