Game Development Reference
In-Depth Information
used as an argument to slerp. This problem doesn't happen in 2D or 3D,
but the surface of a 4D hypersphere has a different topology than Euclidian
space. The solution is to choose the signs of q 0 and q 1 such that the dot
product q 0
q 1 is nonnegative. This has the effect of always selecting the
shortest rotational arc from q 0 to q 1 . The second complication is that if
q 0 and q 1 are very close, then ω is very small, and thus sinω is also very
small, which will cause problems with the division. To avoid this, if sinω
is very small, we will use simple linear interpolation. The code snippet in
Listing 8.3 applies all of this advice to compute the quaternion slerp.
/ /
The
two
i n p u t
q u a t e r n i o n s
f l o a t
w0 , x0 , y0 , z0 ;
f l o a t
w1 , x1 , y1 , z1 ;
/ /
The
i n t e r p o l a t i o n
p a r a m e t e r
f l o a t
t ;
/ /
The
o u t p u t
q u a t e r n i o n
w i l l
be
computed
h e r e
f l o a t
w, x , y , z ;
/ /
Compute
t h e
” c o s i n e
o f
t h e
a n g l e ”
between
t h e
/ /
q u a t e r n i o n s ,
u s i n g
t h e
d o t
p r o d u c t
f l o a t
cosOmega
=
w0 w1
+
x0 x1
+
y0 y1
+
z0 z1 ;
/ /
I f
n e g a t i v e
dot ,
n e g a t e
one
o f
t h e
i n p u t
/ /
q u a t e r n i o n s ,
t o
t a k e
t h e
s h o r t e r
4D ” a r c ”
i f
( cosOmega < 0 . 0 f )
{
w1 = w1 ;
x1 = x1 ;
y1 = y1 ;
z1 = z1 ;
cosOmega
= cosOmega ;
}
/ /
Check
i f
t h e y
a r e
v e r y
c l o s e
t o g e t h e r ,
t o
p r o t e c t
/ /
a g a i n s t
d i v i d e by z e r o
f l o a t
k0 ,
k1 ;
i f
( cosOmega > 0 . 9 9 9 9 f )
{
/ /
Very
c l o s e
j u s t
use
l i n e a r
i n t e r p o l a t i o n
k0
=
1 . 0 f t ;
k1
=
t ;
}
{
e l s e
/ /
Compute
t h e
s i n
o f
t h e
a n g l e
u s i n g
t h e
/ /
t r i g
i d e n t i t y
s i n ˆ 2 ( omega )
+
cos ˆ 2 ( omega )
= 1
f l o a t
sinOmega
=
s q r t ( 1 . 0 f
cosOmega cosOmega ) ;
/ /
Compute
t h e
a n g l e
from
i t s
s i n e
and
c o s i n e
f l o a t
omega
=
a t a n 2 ( sinOmega ,
cosOmega ) ;
/ /
Compute
i n v e r s e
o f
denominator ,
so we
o n l y
have
/ /
t o
d i v i d e
once
f l o a t
oneOverSinOmega
=
1 . 0 f
/
sinOmega ;
/ /
Compute
i n t e r p o l a t i o n
p a r a m e t e r s
k0
=
s i n ( ( 1 . 0 f
t )
omega )
oneOverSinOmega ;
k1
=
s i n ( t
omega )
oneOverSinOmega ;
Search WWH ::




Custom Search