[vtkusers] Bug in vtkQuaternion

Mengda Wu wumengda at gmail.com
Sat Dec 7 11:33:27 EST 2013


hmmm...
It looks like we need to revisit quaternion class by some quaternion expert.


On Fri, Dec 6, 2013 at 1:50 AM, David Gobbi <david.gobbi at gmail.com> wrote:

> The slerp function looks suspicious to me, too, but for a different
> reason.  A quaternion slerp function should _not_ convert the
> quaternions to an angle & axis representation in order to do the
> slerp.  It should be computing the slerp via quaternion algebra,
> not via trigonometry.
>
> On Thu, Dec 5, 2013 at 10:51 PM, Mengda Wu <wumengda at gmail.com> wrote:
> > BTW, I think the slerp function in vtkQuaternion also has issues:
> >
> > What if I would like to interpolate an identity quaternion (no rotation)
> > with an slightly non-identity (a slight rotation). Then axis0=(0,0,0) and
> > e.g. axis1=(1,0,0), will the result be wrong?
> >
> >
> > On Thu, Dec 5, 2013 at 5:30 PM, David Gobbi <david.gobbi at gmail.com>
> wrote:
> >>
> >> The unit quaternion is qw,qx,qy,qz = (1,0,0,0).  But (qx,qy,qz) is not
> >> the "axis".  The axis is what you get when you divide (qx,qy,qz) by
> >> sin(theta/2).
> >>
> >> An identity quaternion is (1, 0, 0, 0), but it is wrong to say that
> >> for the identity quaternion the axis is (0,0,0).  The axis of an
> >> identity quaternion could be anything, because the axis of an identity
> >> quaternion is (0,0,0) / sin(0/2), hence "undefined".
> >>
> >>
> >>
> >> On Thu, Dec 5, 2013 at 3:05 PM, Mengda Wu <wumengda at gmail.com> wrote:
> >> > OK. I am a little confused.
> >> > For an identity quaternion. The code is now
> >> > template<typename T> void vtkQuaternion<T>::ToIdentity()
> >> >
> >> > {
> >> >   this->Set(1.0, 0.0 ,0.0, 0.0);
> >> > }
> >> >
> >> > which means the axis is (0,0,0). Isn't (0,0,0) a good way to represent
> >> > undefined axis?
> >> > So how to represent an identity matrix (no rotation) with a
> quaternion?
> >> > Should it be (1, 0, 0, 0) or (0, 0, 0, 0)?
> >> >
> >> >
> >> >
> >> >
> >> > On Thu, Dec 5, 2013 at 4:30 PM, David Gobbi <david.gobbi at gmail.com>
> >> > wrote:
> >> >>
> >> >> 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:
> >> >> > Thanks a lot for your reply.
> >> >> >
> >> >> > 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);
> >> >> >> >     }
> >> >> >> > }
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20131207/5c19b59d/attachment.htm>


More information about the vtkusers mailing list