2
$\begingroup$

I'm reading pbrt and trying to better understanding the return value of Dot(). The Dot() function takes two quaternions and returns their inner product. Also note, internally, when it comes to the inner product, a quaternion is treated as a 4D vector. I know when two vectors, or in this case the two quaternions, are parallel, then their inner product is equal to 1.0.

Things get little confusing for me when I read the implementation of Slerp()

Quaternion Slerp(float t, const Quaternion &q1,                  const Quaternion &q2) {     float cosTheta = Dot(q1, q2);     if (cosTheta > .9995){         return Normalize((1.f - t) * q1 + t * q2);     } else {       // ...     } } 

I don't quite understand the if(cosTheta > .9995) part. If two quaternions are parallel, then their inner product is 1.0, correct? The only reason I can think of for having a greater-than operator is because Slerp() is meant to work with quaternions and unit quaternions. Is that right?

My ultimate goal is to replace if(cosTheta > .9995) with something more accurate, such as:

if( approxEqual(cosTheta, 1.0) or cosTheta > 1.0 ){ ... } 

approxEqual computes whether the two arguments are ap­prox­i­mately equal based on their relative difference.

Would my new if statement be mathematically correct?

In the book Slerp() is described as:

$$ slerp(q1,q2,t) = \frac{ q1 \sin((1-t) \theta) + q2 \sin(t\theta) }{ \sin \theta } $$

...given the quaternions to interpolate between, $q1$ and $q2$, denote by \theta the angle between them. Then, given a parameter value t ∈[0,1], we'd like to find the intermediate quaternion $q'$ that makes angle $\theta' = \theta t$ between it and $q1$, along the path from $q1$ to $q2$. --page 95

The implementation of the Slerp() function checks to see if the two quaternions are nearly parallel, in which case it uses regular linear interpolation of quaternion components in order to avoid numerical instability. Otherwise, ...

  • 0
    When two vectors are parallel, their inner product is equal to the product of their lengths. Perhaps you're thinking of _unit_ vectors? Also, what is Slerp supposed to compute? And what is $f$? Offhand my guess is that the if statement has to do with numerical stability, but I don't have enough information to know for sure.2011-12-23
  • 0
    @QiaochuYuan _f_ is nothing. It just means that the number is float. I removed it.2011-12-23
  • 0
    @QiaochuYuan As far as the inner product, yes I was thinking of unit vector, but I'm not sure if pbrt makes the same assumption. I also added the definition of _slerp_ from the book.2011-12-23
  • 3
    Looks like the explanation is right there in the book: if the quaternions are nearly parallel, the algorithm uses linear interpolation to avoid numerical instability.2011-12-23
  • 0
    @QiaochuYuan so you're saying my `if` statement would work too? As far as I can tell mine is better than using the magic number `0.9995`.2011-12-23

1 Answers 1