UnityMol  0.9.6-875
UnityMol viewer / In developement
MathUtils.cs
Go to the documentation of this file.
1 
66 using UnityEngine;
67 using System.Collections;
68 
69 public class MathUtils{
70 
71  public static float GetQuatLength(Quaternion q){
72  return Mathf.Sqrt(q.x*q.x + q.y*q.y + q.z*q.z + q.w*q.w);
73  }
74 
75  //
76  public static Quaternion GetQuatConjugate(Quaternion q){
77  return new Quaternion(-q.x, -q.y, -q.z, q.w);
78  }
79 
80  //
81  // Logarithm of a unit quaternion. The result is not necessary a unit quaternion.
82  //
83  public static Quaternion GetQuatLog(Quaternion q ){
84  Quaternion res = q;
85  res.w = 0;
86 
87  if (Mathf.Abs(q.w) < 1.0){
88  float theta = Mathf.Acos(q.w);
89  float sin_theta = Mathf.Sin(theta);
90 
91  if (Mathf.Abs(sin_theta) > 0.0001){
92  float coef = theta/sin_theta;
93  res.x = q.x*coef;
94  res.y = q.y*coef;
95  res.z = q.z*coef;
96  }
97  }
98  return res;
99  }
100 
101  //
102  // Exp
103  //
104  public static Quaternion GetQuatExp(Quaternion q){
105  Quaternion res = q;
106  float fAngle = Mathf.Sqrt(q.x*q.x + q.y*q.y + q.z*q.z);
107  float fSin = Mathf.Sin(fAngle);
108 
109  res.w = Mathf.Cos(fAngle);
110 
111  if (Mathf.Abs(fSin) > 0.0001){
112  float coef = fSin/fAngle;
113  res.x = coef*q.x;
114  res.y = coef*q.y;
115  res.z = coef*q.z;
116  }
117  return res;
118  }
119 
120  //
121  // SQUAD Spherical Quadrangle interpolation [Shoe87]
122  //
123  public static Quaternion GetQuatSquad (float t, Quaternion q0, Quaternion q1, Quaternion a0,Quaternion a1){
124 
125  float slerpT = 2.0f*t*(1.0f-t);
126  Quaternion slerpP = Slerp(q0, q1, t);
127  Quaternion slerpQ = Slerp(a0, a1, t);
128 
129  return Slerp(slerpP, slerpQ, slerpT);
130 
131  }
132 
133  public static Quaternion GetSquadIntermediate (Quaternion q0uaternion,Quaternion q1uaternion,Quaternion q2uaternion){
134  Quaternion q1Inv = GetQuatConjugate(q1uaternion);
135  Quaternion p0 = GetQuatLog(q1Inv*q0uaternion);
136 
137  Quaternion p2 = GetQuatLog(q1Inv*q2uaternion);
138  Quaternion sum=new Quaternion(-0.25f*(p0.x+p2.x), -0.25f*(p0.y+p2.y), -0.25f*(p0.z+p2.z), -0.25f*(p0.w+p2.w));
139 
140  return q1uaternion*GetQuatExp(sum);
141  }
142 
143  //
144  // Smooths the input parameter t. If less than k1 ir greater than k2, it uses a sin. Between k1 and k2 it uses
145  // linear interp.
146  //
147  public static float Ease(float t,float k1,float k2){
148  float f;
149  float s;
150  f = k1*2/Mathf.PI + k2 - k1 + (1.0f-k2)*2/Mathf.PI;
151 
152  if (t < k1)
153  {
154  s = k1*(2/Mathf.PI)*(Mathf.Sin((t/k1)*Mathf.PI/2-Mathf.PI/2)+1);
155  }
156  else
157  if (t < k2)
158  {
159  s = (2*k1/Mathf.PI + t-k1);
160  }
161  else
162  {
163  s= 2*k1/Mathf.PI + k2-k1 + ((1-k2)*(2/Mathf.PI))*Mathf.Sin(((t-k2)/(1.0f-k2))*Mathf.PI/2);
164  }
165  f = k1*2/Mathf.PI + k2 - k1 + (1.0f-k2)*2/Mathf.PI;
166 
167  if (t < k1)
168  {
169  s = k1*(2/Mathf.PI)*(Mathf.Sin((t/k1)*Mathf.PI/2-Mathf.PI/2)+1);
170  }
171  else
172  if (t < k2)
173  {
174  s = (2*k1/Mathf.PI + t-k1);
175  }
176  else
177  {
178  s= 2*k1/Mathf.PI + k2-k1 + ((1-k2)*(2/Mathf.PI))*Mathf.Sin(((t-k2)/(1.0f-k2))*Mathf.PI/2);
179  }
180  return (s/f);
181  }
182 
183  //
184  // We need this because Quaternion.Slerp always does it using the shortest arc
185  //
186  public static Quaternion Slerp (Quaternion p ,Quaternion q,float t){
187  Quaternion ret;
188  float omega;
189  float invSin;
190  float fCoeff0;
191  float fCoeff1;
192 
193  float fCos = Quaternion.Dot(p, q);
194 
195  if ((1.0f + fCos) > 0.00001f){
196  if ((1.0f - fCos) > 0.00001f){
197  omega = Mathf.Acos(fCos);
198  invSin = 1.0f/Mathf.Sin(omega);
199  fCoeff0 = Mathf.Sin((1.0f-t)*omega)*invSin;
200  fCoeff1 = Mathf.Sin(t*omega)*invSin;
201  }
202  else{
203  fCoeff0 = 1.0f-t;
204  fCoeff1 = t;
205  }
206 
207  ret.x = fCoeff0*p.x + fCoeff1*q.x;
208  ret.y = fCoeff0*p.y + fCoeff1*q.y;
209  ret.z = fCoeff0*p.z + fCoeff1*q.z;
210  ret.w = fCoeff0*p.w + fCoeff1*q.w;
211  }
212  else{
213  fCoeff0 = Mathf.Sin((1.0f-t)*Mathf.PI*0.5f);
214  fCoeff1 = Mathf.Sin(t*Mathf.PI*0.5f);
215 
216  ret.x = fCoeff0*p.x - fCoeff1*p.y;
217  ret.y = fCoeff0*p.y + fCoeff1*p.x;
218  ret.z = fCoeff0*p.z - fCoeff1*p.w;
219  ret.w = p.z;
220  }
221  return ret;
222  }
223 }
224 
225 
static Quaternion Slerp(Quaternion p, Quaternion q, float t)
Definition: MathUtils.cs:186
static float GetQuatLength(Quaternion q)
Definition: MathUtils.cs:71
static Quaternion GetQuatSquad(float t, Quaternion q0, Quaternion q1, Quaternion a0, Quaternion a1)
Definition: MathUtils.cs:123
static float Ease(float t, float k1, float k2)
Definition: MathUtils.cs:147
static Quaternion GetQuatExp(Quaternion q)
Definition: MathUtils.cs:104
static Quaternion GetSquadIntermediate(Quaternion q0uaternion, Quaternion q1uaternion, Quaternion q2uaternion)
Definition: MathUtils.cs:133
static Quaternion GetQuatConjugate(Quaternion q)
Definition: MathUtils.cs:76
static Quaternion GetQuatLog(Quaternion q)
Definition: MathUtils.cs:83