# [vtkusers] Bug in vtkQuaternion

David Gobbi david.gobbi at gmail.com
Thu Dec 5 16:30:08 EST 2013

```You say that for the identity quaternion the axis is (0,0,0) but that
is not really true.  For the identity quaternion, the axis is
undefined.

If you call SetRotationAngleAndAxis(1,0,0,0), then you are passing
invalid parameters to the method.  To get the identity quaternion, you
need to set the angle to zero, not to one.

I agree that the code should have an extra check, but it should be the
opposite of what you have in your sample code.  It should give the
identity quaternion if the angle is zero:

else if ( angle == 0.0 )
{
this->Set(1.0, 0.0, 0.0, 0.0);
}
else
{
this->Set(0.0, 0.0, 0.0, 0.0);
}

David

On Thu, Dec 5, 2013 at 2:14 PM, Mengda Wu <wumengda at gmail.com> wrote:
>
> But for the identity quaternion (1, 0, 0, 0), the axis is indeed (0,0,0).
> This is related to GetRotationAngleAndAxis, that function will give a nozero
> angle and axis (0,0,0) for the identity quaternion.
> Then if I plug this result to SetRotationAngleAndAxis, I will get a
> quaternion (0,0,0,0), which does not make sense.
> Then if I use ToMatrix3x3 on the quaternion (0,0,0,0), which will be wrong.
>
> So I suggest to change
>
> template<typename T> void
> vtkQuaternion<T>::SetRotationAngleAndAxis (const T& angle,
>                                            const T& x,
>                                            const T& y,
>                                            const T& z)
> {
>   T axisNorm = x*x + y*y + z*z;
>   if (axisNorm != 0.0)
>     {
>     T w = cos(angle / 2.0);
>     this->SetW(w);
>
>     T f = sin( angle / 2.0);
>     this->SetX((x / axisNorm) * f);
>     this->SetY((y / axisNorm) * f);
>     this->SetZ((z / axisNorm) * f);
>     }
>   else if ( angle != 0.0 )
>     {
>     this->Set(1.0, 0.0, 0.0, 0.0);
>     }
>  else
>    {
>    this->Set(0.0, 0.0, 0.0, 0.0);
>    }
> }
>
> How is that?
>
> Mengda
>
>
> On Thu, Dec 5, 2013 at 4:04 PM, David Gobbi <david.gobbi at gmail.com> wrote:
>>
>> Hi Mengda,
>>
>> The SetRotationAngleAndAxis(angle, x, y, z) method does not
>> directly set the quaternion elements, for that you would use the
>> method Set(w, x, y, z).
>>
>> For SetRotationAngleAndAxis, it does not make sense to specify
>> xyz=(0,0,0) with a nonzero angle because (0,0,0) is not a valid axis.
>>
>>   David
>>
>> On Thu, Dec 5, 2013 at 1:53 PM, Mengda Wu <wumengda at gmail.com> wrote:
>> > Hi all,
>> >
>> >    I think there is a bug in vtkQuaternion<T>::SetRotationAngleAndAxis.
>> > What
>> > if I want to
>> > set angle=1.0 and xyz=(0, 0, 0)? I need an identity matrix from this
>> > quaternion. Should it call this->Set(1.0, 0.0, 0.0, 0.0) instead of
>> > this->Set(0.0, 0.0, 0.0, 0.0) in this case?
>> >
>> > Thanks,
>> > Mengda
>> >
>> >
>> >
>> > The code is pasted here:
>> >
>> > template<typename T> void
>> > vtkQuaternion<T>::SetRotationAngleAndAxis (const T& angle,
>> >                                            const T& x,
>> >                                            const T& y,
>> >                                            const T& z)
>> > {
>> >   T axisNorm = x*x + y*y + z*z;
>> >   if (axisNorm != 0.0)
>> >     {
>> >     T w = cos(angle / 2.0);
>> >     this->SetW(w);
>> >
>> >     T f = sin( angle / 2.0);
>> >     this->SetX((x / axisNorm) * f);
>> >     this->SetY((y / axisNorm) * f);
>> >     this->SetZ((z / axisNorm) * f);
>> >     }
>> >   else
>> >     {
>> >     this->Set(0.0, 0.0, 0.0, 0.0);
>> >     }
>> > }
>
>
```