<div dir="ltr"><div>BTW, I think the slerp function in vtkQuaternion also has issues:<br><br></div>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?<br>
</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Dec 5, 2013 at 5:30 PM, David Gobbi <span dir="ltr"><<a href="mailto:david.gobbi@gmail.com" target="_blank">david.gobbi@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The unit quaternion is qw,qx,qy,qz = (1,0,0,0). But (qx,qy,qz) is not<br>
the "axis". The axis is what you get when you divide (qx,qy,qz) by<br>
sin(theta/2).<br>
<br>
An identity quaternion is (1, 0, 0, 0), but it is wrong to say that<br>
for the identity quaternion the axis is (0,0,0). The axis of an<br>
identity quaternion could be anything, because the axis of an identity<br>
quaternion is (0,0,0) / sin(0/2), hence "undefined".<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
<br>
On Thu, Dec 5, 2013 at 3:05 PM, Mengda Wu <<a href="mailto:wumengda@gmail.com">wumengda@gmail.com</a>> wrote:<br>
> OK. I am a little confused.<br>
> For an identity quaternion. The code is now<br>
> template<typename T> void vtkQuaternion<T>::ToIdentity()<br>
><br>
> {<br>
> this->Set(1.0, 0.0 ,0.0, 0.0);<br>
> }<br>
><br>
> which means the axis is (0,0,0). Isn't (0,0,0) a good way to represent<br>
> undefined axis?<br>
> So how to represent an identity matrix (no rotation) with a quaternion?<br>
> Should it be (1, 0, 0, 0) or (0, 0, 0, 0)?<br>
><br>
><br>
><br>
><br>
> On Thu, Dec 5, 2013 at 4:30 PM, David Gobbi <<a href="mailto:david.gobbi@gmail.com">david.gobbi@gmail.com</a>> wrote:<br>
>><br>
>> You say that for the identity quaternion the axis is (0,0,0) but that<br>
>> is not really true. For the identity quaternion, the axis is<br>
>> undefined.<br>
>><br>
>> If you call SetRotationAngleAndAxis(1,0,0,0), then you are passing<br>
>> invalid parameters to the method. To get the identity quaternion, you<br>
>> need to set the angle to zero, not to one.<br>
>><br>
>> I agree that the code should have an extra check, but it should be the<br>
>> opposite of what you have in your sample code. It should give the<br>
>> identity quaternion if the angle is zero:<br>
>><br>
>> else if ( angle == 0.0 )<br>
>> {<br>
>> this->Set(1.0, 0.0, 0.0, 0.0);<br>
>> }<br>
>> else<br>
>> {<br>
>> this->Set(0.0, 0.0, 0.0, 0.0);<br>
>> }<br>
>><br>
>> David<br>
>><br>
>> On Thu, Dec 5, 2013 at 2:14 PM, Mengda Wu <<a href="mailto:wumengda@gmail.com">wumengda@gmail.com</a>> wrote:<br>
>> > Thanks a lot for your reply.<br>
>> ><br>
>> > But for the identity quaternion (1, 0, 0, 0), the axis is indeed<br>
>> > (0,0,0).<br>
>> > This is related to GetRotationAngleAndAxis, that function will give a<br>
>> > nozero<br>
>> > angle and axis (0,0,0) for the identity quaternion.<br>
>> > Then if I plug this result to SetRotationAngleAndAxis, I will get a<br>
>> > quaternion (0,0,0,0), which does not make sense.<br>
>> > Then if I use ToMatrix3x3 on the quaternion (0,0,0,0), which will be<br>
>> > wrong.<br>
>> ><br>
>> > So I suggest to change<br>
>> ><br>
>> > template<typename T> void<br>
>> > vtkQuaternion<T>::SetRotationAngleAndAxis (const T& angle,<br>
>> > const T& x,<br>
>> > const T& y,<br>
>> > const T& z)<br>
>> > {<br>
>> > T axisNorm = x*x + y*y + z*z;<br>
>> > if (axisNorm != 0.0)<br>
>> > {<br>
>> > T w = cos(angle / 2.0);<br>
>> > this->SetW(w);<br>
>> ><br>
>> > T f = sin( angle / 2.0);<br>
>> > this->SetX((x / axisNorm) * f);<br>
>> > this->SetY((y / axisNorm) * f);<br>
>> > this->SetZ((z / axisNorm) * f);<br>
>> > }<br>
>> > else if ( angle != 0.0 )<br>
>> > {<br>
>> > this->Set(1.0, 0.0, 0.0, 0.0);<br>
>> > }<br>
>> > else<br>
>> > {<br>
>> > this->Set(0.0, 0.0, 0.0, 0.0);<br>
>> > }<br>
>> > }<br>
>> ><br>
>> > How is that?<br>
>> ><br>
>> > Mengda<br>
>> ><br>
>> ><br>
>> > On Thu, Dec 5, 2013 at 4:04 PM, David Gobbi <<a href="mailto:david.gobbi@gmail.com">david.gobbi@gmail.com</a>><br>
>> > wrote:<br>
>> >><br>
>> >> Hi Mengda,<br>
>> >><br>
>> >> The SetRotationAngleAndAxis(angle, x, y, z) method does not<br>
>> >> directly set the quaternion elements, for that you would use the<br>
>> >> method Set(w, x, y, z).<br>
>> >><br>
>> >> For SetRotationAngleAndAxis, it does not make sense to specify<br>
>> >> xyz=(0,0,0) with a nonzero angle because (0,0,0) is not a valid axis.<br>
>> >><br>
>> >> David<br>
>> >><br>
>> >> On Thu, Dec 5, 2013 at 1:53 PM, Mengda Wu <<a href="mailto:wumengda@gmail.com">wumengda@gmail.com</a>> wrote:<br>
>> >> > Hi all,<br>
>> >> ><br>
>> >> > I think there is a bug in<br>
>> >> > vtkQuaternion<T>::SetRotationAngleAndAxis.<br>
>> >> > What<br>
>> >> > if I want to<br>
>> >> > set angle=1.0 and xyz=(0, 0, 0)? I need an identity matrix from this<br>
>> >> > quaternion. Should it call this->Set(1.0, 0.0, 0.0, 0.0) instead of<br>
>> >> > this->Set(0.0, 0.0, 0.0, 0.0) in this case?<br>
>> >> ><br>
>> >> > Thanks,<br>
>> >> > Mengda<br>
>> >> ><br>
>> >> ><br>
>> >> ><br>
>> >> > The code is pasted here:<br>
>> >> ><br>
>> >> > template<typename T> void<br>
>> >> > vtkQuaternion<T>::SetRotationAngleAndAxis (const T& angle,<br>
>> >> > const T& x,<br>
>> >> > const T& y,<br>
>> >> > const T& z)<br>
>> >> > {<br>
>> >> > T axisNorm = x*x + y*y + z*z;<br>
>> >> > if (axisNorm != 0.0)<br>
>> >> > {<br>
>> >> > T w = cos(angle / 2.0);<br>
>> >> > this->SetW(w);<br>
>> >> ><br>
>> >> > T f = sin( angle / 2.0);<br>
>> >> > this->SetX((x / axisNorm) * f);<br>
>> >> > this->SetY((y / axisNorm) * f);<br>
>> >> > this->SetZ((z / axisNorm) * f);<br>
>> >> > }<br>
>> >> > else<br>
>> >> > {<br>
>> >> > this->Set(0.0, 0.0, 0.0, 0.0);<br>
>> >> > }<br>
>> >> > }<br>
>> ><br>
>> ><br>
><br>
><br>
</div></div></blockquote></div><br></div>