What is Quaternion

  • Invented by Sir William Rowan Hamilton as an extension to the complex numbers in 1843
  • Introduced to the field of computer graphics by Shoemake in 1985
  • q = (x, y, z, w)

Mathematical Background

  • Definition

q = (qv, qw) = iqx + iqy + iqz + qw

i2 = j2 = k2 = -1, jk = -kj = i, ki = -ik = j, ij = -ji = k

  • Multiplication

qr = (qv X rv+rwqv+qwrv) - qvrv

  • Addition

q + r = (qv + rv) + (qw+rw)

  • Conjugate

q* = (-qv, qw)

  • Norm

n(q) = (qx2 + qy2 + qz2 + qw2)1/2

  • Identity

qI = (0, 0, 0, 1)

  • Inverse

n(q)2 = qq* → qq*/n(q)2 = 1

q-1 = q*/n(q)2

Slerp(Spherical Linear Interpolation) of Quaternion Rotation:

Slerp(q0, q1, t) = q0(q0-1q1)t

                        = q0(1-t)q1t

                        = q0aq1b, a+b = 1 

=>Slerp(q0, q1, a, b)

所以是否可以推展成:

 Slerp(q0, q1, q2, a, b, c) = q0aq1bq2c, a+b+c = 1 ?

我覺得應該可以,推導如下:

q0aq1bq2c = (q0xq1y)zq2c; x = a/(a+b), y = b/(a+b), z = a+b

                 = Slerp(Slerp(q0, q1, x, y), q2, z, c); x+y = 1, c+z = a+b+c = 1

如此一來,就可以將一組quaternion的blending拆成各個獨立的運算式。即各自運算qn的結果,最後再乘起來即可:

quat q = Identity;

loop(1 to n) {
    q *= track[i].WeightedQuat();
}

Exponentiation of Quaternion:

q = cosq + vsinq

qt = costq + vsintq

 

Implementation Issue

在實作時發現上述的公式有兩個致命的問題:

  • When q = (0, 0, 0, -1), qt is undefined
  • 無法產生Shortest Path Slerp

因此必須將公式改成:

Slerp(q0, q1, t) = [(sin(1-t)a)/sina]q0 + [sinta/sina]q1, sina = (x0*x1 + y0*y1 + z0*z1 + w0*w1)

程式必須改成:

QuatWithWeight qw = (q, t);

loop(1 to n) {
    qw = SlerpWithWeight(qw, track[i].Quat(), track[i].Weight());
}

QuatWithWeight SlerpWithWeight(qw, q1, w1)
{
    QuatWithWeight qw1
    weight = qw.w/(qw.w+w1);
    qw1.q = SlerpSP(qw.q, q1, weight);
    qw1.w = weight;
    return qw1;
}

Quat SlerpSP(q1, q2, w)
{
    cos = dot(q1, q2);
    if (cos < 0) {
         q1 = -q1;
    }
    if (cos -> 1) {
        q3 = q1*w + q2*(1-w);
    } else {
        theta = acos(cos);
        q3 = sin(theta*w)*q1 + sin(theta*(1-w))*q2;
        q3 = q3/sin(theta);
    }
    return q3;
}

但無論是哪一個算式,他們的計算順序都會影響最後的結果。換句話說,同樣一組quaternions及weights卻可能得到各種不同的結果,以算式表示就是:

Slerp(q1, q2, q3, a, b, c) ≠ Slerp(q1, q3, q2, a, c, b)

所以如果想要得到一個唯一解也許只有簡化Slerp成Qlerp(In "Spherical blend skinning: A real-time deformation of articulated models" SIGGRAPH 2005)這一途吧

創作者介紹
創作者 Duke Rabbit's Game Zone 的頭像
lijy

Duke Rabbit's Game Zone

lijy 發表在 痞客邦 留言(0) 人氣( 705 )