BallAux.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. /***** BallAux.c *****/
  2. #include <math.h>
  3. #include "BallAux.h"
  4. Quat qOne = { 0, 0, 0, 1 };
  5. /* Return quaternion product qL * qR. Note: order is important!
  6. * To combine rotations, use the product Mul(qSecond, qFirst),
  7. * which gives the effect of rotating by qFirst then qSecond. */
  8. Quat Qt_Mul(Quat qL, Quat qR)
  9. {
  10. Quat qq;
  11. qq.w = qL.w * qR.w - qL.x * qR.x - qL.y * qR.y - qL.z * qR.z;
  12. qq.x = qL.w * qR.x + qL.x * qR.w + qL.y * qR.z - qL.z * qR.y;
  13. qq.y = qL.w * qR.y + qL.y * qR.w + qL.z * qR.x - qL.x * qR.z;
  14. qq.z = qL.w * qR.z + qL.z * qR.w + qL.x * qR.y - qL.y * qR.x;
  15. return (qq);
  16. }
  17. /* Construct rotation matrix from (possibly non-unit) quaternion.
  18. * Assumes matrix is used to multiply column vector on the left:
  19. * vnew = mat vold. Works correctly for right-handed coordinate system
  20. * and right-handed rotations. */
  21. HMatrix *Qt_ToMatrix(Quat q, HMatrix out)
  22. {
  23. double Nq = q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w;
  24. double s = (Nq > 0.0) ? (2.0 / Nq) : 0.0;
  25. double xs = q.x * s, ys = q.y * s, zs = q.z * s;
  26. double wx = q.w * xs, wy = q.w * ys, wz = q.w * zs;
  27. double xx = q.x * xs, xy = q.x * ys, xz = q.x * zs;
  28. double yy = q.y * ys, yz = q.y * zs, zz = q.z * zs;
  29. out[XX][XX] = 1.0 - (yy + zz);
  30. out[YY][XX] = xy + wz;
  31. out[ZZ][XX] = xz - wy;
  32. out[XX][YY] = xy - wz;
  33. out[YY][YY] = 1.0 - (xx + zz);
  34. out[ZZ][YY] = yz + wx;
  35. out[XX][ZZ] = xz + wy;
  36. out[YY][ZZ] = yz - wx;
  37. out[ZZ][ZZ] = 1.0 - (xx + yy);
  38. out[XX][WW] = out[YY][WW] = out[ZZ][WW] = out[WW][XX] = out[WW][YY] =
  39. out[WW][ZZ] = 0.0;
  40. out[WW][WW] = 1.0;
  41. return ((HMatrix *) & out);
  42. }
  43. Quat Matrix_to_Qt(HMatrix dircos)
  44. {
  45. Quat quat;
  46. float dummy;
  47. quat.w = .5 * sqrt(1. + dircos[0][0] + dircos[1][1] + dircos[2][2]);
  48. dummy = 4. * quat.w;
  49. quat.x = (dircos[2][1] - dircos[1][2]) / dummy;
  50. quat.y = (dircos[0][2] - dircos[2][0]) / dummy;
  51. quat.z = (dircos[1][0] - dircos[0][1]) / dummy;
  52. return (quat);
  53. }
  54. /* Return conjugate of quaternion. */
  55. Quat Qt_Conj(Quat q)
  56. {
  57. Quat qq;
  58. qq.x = -q.x;
  59. qq.y = -q.y;
  60. qq.z = -q.z;
  61. qq.w = q.w;
  62. return (qq);
  63. }
  64. /* Return vector formed from components */
  65. HVect V3_(float x, float y, float z)
  66. {
  67. HVect v;
  68. v.x = x;
  69. v.y = y;
  70. v.z = z;
  71. v.w = 0;
  72. return (v);
  73. }
  74. /* Return norm of v, defined as sum of squares of components */
  75. float V3_Norm(HVect v)
  76. {
  77. return (v.x * v.x + v.y * v.y + v.z * v.z);
  78. }
  79. /* Return unit magnitude vector in direction of v */
  80. HVect V3_Unit(HVect v)
  81. {
  82. HVect u = { 0, 0, 0, 0 };
  83. float vlen = sqrt(V3_Norm(v));
  84. if (vlen != 0.0) {
  85. u.x = v.x / vlen;
  86. u.y = v.y / vlen;
  87. u.z = v.z / vlen;
  88. }
  89. return (u);
  90. }
  91. /* Return version of v scaled by s */
  92. HVect V3_Scale(HVect v, float s)
  93. {
  94. HVect u;
  95. u.x = s * v.x;
  96. u.y = s * v.y;
  97. u.z = s * v.z;
  98. u.w = v.w;
  99. return (u);
  100. }
  101. /* Return negative of v */
  102. HVect V3_Negate(HVect v)
  103. {
  104. HVect u = { 0, 0, 0, 0 };
  105. u.x = -v.x;
  106. u.y = -v.y;
  107. u.z = -v.z;
  108. return (u);
  109. }
  110. /* Return sum of v1 and v2 */
  111. HVect V3_Add(HVect v1, HVect v2)
  112. {
  113. HVect v = { 0, 0, 0, 0 };
  114. v.x = v1.x + v2.x;
  115. v.y = v1.y + v2.y;
  116. v.z = v1.z + v2.z;
  117. return (v);
  118. }
  119. /* Return difference of v1 minus v2 */
  120. HVect V3_Sub(HVect v1, HVect v2)
  121. {
  122. HVect v = { 0, 0, 0, 0 };
  123. v.x = v1.x - v2.x;
  124. v.y = v1.y - v2.y;
  125. v.z = v1.z - v2.z;
  126. return (v);
  127. }
  128. /* Halve arc between unit vectors v0 and v1. */
  129. HVect V3_Bisect(HVect v0, HVect v1)
  130. {
  131. HVect v = { 0, 0, 0, 0 };
  132. float Nv;
  133. v = V3_Add(v0, v1);
  134. Nv = V3_Norm(v);
  135. if (Nv < 1.0e-5) {
  136. v = V3_(0, 0, 1);
  137. }
  138. else {
  139. v = V3_Scale(v, 1 / sqrt(Nv));
  140. }
  141. return (v);
  142. }
  143. /* Return dot product of v1 and v2 */
  144. float V3_Dot(HVect v1, HVect v2)
  145. {
  146. return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z);
  147. }
  148. /* Return cross product, v1 x v2 */
  149. HVect V3_Cross(HVect v1, HVect v2)
  150. {
  151. HVect v = { 0, 0, 0, 0 };
  152. v.x = v1.y * v2.z - v1.z * v2.y;
  153. v.y = v1.z * v2.x - v1.x * v2.z;
  154. v.z = v1.x * v2.y - v1.y * v2.x;
  155. return (v);
  156. }