四元数(クォータニオン)の計算やらなんやらができます.主に演算子オーバーロードの練習で作りました.温かい目で見てやってください.

Dependencies:   Vector3

Dependents:   Hybrid_main_FirstEdtion MadgwickFilter MadgwickFilter

Fork of Quaternion by Gaku Matsumoto

Committer:
Gaku0606
Date:
Sun Feb 25 19:44:47 2018 +0000
Revision:
8:0b4374931b0e
Parent:
7:631c068aded7
double -> float;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Gaku0606 0:31fe79c6544c 1 #ifndef _QUATERNION_HPP_
Gaku0606 0:31fe79c6544c 2 #define _QUATERNION_HPP_
Gaku0606 8:0b4374931b0e 3 #include "Vector3/Vector3.hpp"
Gaku0606 5:3c531c1f56cc 4 /**
Gaku0606 2:7c23225b23dc 5 * クォータニオンの足し,引き,掛け算などを簡単にできるようになります.
Gaku0606 2:7c23225b23dc 6 * @author Gaku MATSUMOTO
Gaku0606 2:7c23225b23dc 7 * @bref クォータニオンを使えるクラスです.
Gaku0606 0:31fe79c6544c 8 */
Gaku0606 5:3c531c1f56cc 9
Gaku0606 0:31fe79c6544c 10 class Quaternion{
Gaku0606 0:31fe79c6544c 11 public:
Gaku0606 0:31fe79c6544c 12 /**
Gaku0606 0:31fe79c6544c 13 @bref Quaternionインスタンスを生成します
Gaku0606 0:31fe79c6544c 14 */
Gaku0606 0:31fe79c6544c 15 Quaternion(){
Gaku0606 7:631c068aded7 16 w = 1.0f;
Gaku0606 7:631c068aded7 17 x = 0.0f;
Gaku0606 7:631c068aded7 18 y = 0.0f;
Gaku0606 7:631c068aded7 19 z = 0.0f;
Gaku0606 0:31fe79c6544c 20 };
Gaku0606 5:3c531c1f56cc 21
Gaku0606 0:31fe79c6544c 22 /**
Gaku0606 5:3c531c1f56cc 23 * @bref Vector3クラスからクォータニオンを作ります
Gaku0606 5:3c531c1f56cc 24 */
Gaku0606 5:3c531c1f56cc 25 Quaternion(Vector3 vector){
Gaku0606 7:631c068aded7 26 Set(vector);
Gaku0606 5:3c531c1f56cc 27 }
Gaku0606 5:3c531c1f56cc 28
Gaku0606 5:3c531c1f56cc 29 /**
Gaku0606 5:3c531c1f56cc 30 * @bref クォータニオンを回転軸と回転角度によって初期化します。
Gaku0606 7:631c068aded7 31 * @param vec 回転軸となる3次元ベクトル
Gaku0606 7:631c068aded7 32 * @param angle 回転角 [rad]
Gaku0606 5:3c531c1f56cc 33 */
Gaku0606 7:631c068aded7 34 Quaternion(Vector3 vec, float angle){
Gaku0606 7:631c068aded7 35 Set(vec, angle);
Gaku0606 5:3c531c1f56cc 36 }
Gaku0606 5:3c531c1f56cc 37
Gaku0606 5:3c531c1f56cc 38 /**
Gaku0606 5:3c531c1f56cc 39 @bref 要素を代入しながら,インスタンスを生成します.
Gaku0606 5:3c531c1f56cc 40 @param[in] _w 実部wの初期値
Gaku0606 5:3c531c1f56cc 41 @param[in] _x 虚部iの初期値
Gaku0606 5:3c531c1f56cc 42 @param[in] _y 虚部jの初期値
Gaku0606 5:3c531c1f56cc 43 @param[in] _z 虚部kの初期値
Gaku0606 0:31fe79c6544c 44 */
Gaku0606 7:631c068aded7 45 Quaternion(float _w, float _x, float _y, float _z){
Gaku0606 0:31fe79c6544c 46 w = _w; x = _x; y = _y; z = _z;
Gaku0606 0:31fe79c6544c 47 };
Gaku0606 0:31fe79c6544c 48
Gaku0606 0:31fe79c6544c 49 public:
Gaku0606 7:631c068aded7 50 float w;
Gaku0606 7:631c068aded7 51 float x;
Gaku0606 7:631c068aded7 52 float y;
Gaku0606 7:631c068aded7 53 float z;
Gaku0606 0:31fe79c6544c 54
Gaku0606 7:631c068aded7 55
Gaku0606 0:31fe79c6544c 56 public:
Gaku0606 0:31fe79c6544c 57
Gaku0606 0:31fe79c6544c 58 /**
Gaku0606 5:3c531c1f56cc 59 @bref クォータニオンの要素をコピーします.
Gaku0606 5:3c531c1f56cc 60 @note 通常の数のように代入できます
Gaku0606 0:31fe79c6544c 61 */
Gaku0606 0:31fe79c6544c 62 Quaternion operator=(Quaternion r){
Gaku0606 0:31fe79c6544c 63 w = r.w;
Gaku0606 0:31fe79c6544c 64 x = r.x;
Gaku0606 0:31fe79c6544c 65 y = r.y;
Gaku0606 0:31fe79c6544c 66 z = r.z;
Gaku0606 0:31fe79c6544c 67 return *this;
Gaku0606 0:31fe79c6544c 68 };
Gaku0606 0:31fe79c6544c 69
Gaku0606 0:31fe79c6544c 70 /**
Gaku0606 5:3c531c1f56cc 71 @bref クォータニオンを足して代入します.
Gaku0606 5:3c531c1f56cc 72 @note 通常の数のように代入できます
Gaku0606 0:31fe79c6544c 73 */
Gaku0606 0:31fe79c6544c 74 Quaternion operator+=(Quaternion r){
Gaku0606 0:31fe79c6544c 75 w += r.w;
Gaku0606 0:31fe79c6544c 76 x += r.x;
Gaku0606 0:31fe79c6544c 77 y += r.y;
Gaku0606 0:31fe79c6544c 78 z += r.z;
Gaku0606 0:31fe79c6544c 79 return *this;
Gaku0606 0:31fe79c6544c 80 };
Gaku0606 0:31fe79c6544c 81
Gaku0606 0:31fe79c6544c 82 /**
Gaku0606 5:3c531c1f56cc 83 @bref クォータニオンを引いて代入します.
Gaku0606 5:3c531c1f56cc 84 @note 通常の数のように代入できます
Gaku0606 0:31fe79c6544c 85 */
Gaku0606 0:31fe79c6544c 86 Quaternion operator-=(Quaternion r){
Gaku0606 0:31fe79c6544c 87 w -= r.w;
Gaku0606 0:31fe79c6544c 88 x -= r.x;
Gaku0606 0:31fe79c6544c 89 y -= r.y;
Gaku0606 0:31fe79c6544c 90 z -= r.z;
Gaku0606 0:31fe79c6544c 91 return *this;
Gaku0606 0:31fe79c6544c 92 };
Gaku0606 0:31fe79c6544c 93
Gaku0606 0:31fe79c6544c 94 /**
Gaku0606 0:31fe79c6544c 95 * @bref クォータニオンの掛け算をします.
Gaku0606 0:31fe79c6544c 96 * @note この際も順序は重要です.
Gaku0606 0:31fe79c6544c 97 */
Gaku0606 0:31fe79c6544c 98 Quaternion operator*=(Quaternion r){
Gaku0606 0:31fe79c6544c 99 static Quaternion QQ;
Gaku0606 7:631c068aded7 100 QQ.w = w*r.w - x*r.x - y*r.y - z*r.z;
Gaku0606 0:31fe79c6544c 101 QQ.x = x*r.w + w*r.x - z*r.y + y*r.z;
Gaku0606 0:31fe79c6544c 102 QQ.y = y*r.w + z*r.x + w*r.y - x*r.z;
Gaku0606 0:31fe79c6544c 103 QQ.z = z*r.w - y*r.x + x*r.y + w*r.z;
Gaku0606 0:31fe79c6544c 104 w = QQ.w;
Gaku0606 0:31fe79c6544c 105 x = QQ.x;
Gaku0606 0:31fe79c6544c 106 y = QQ.y;
Gaku0606 0:31fe79c6544c 107 z = QQ.z;
Gaku0606 0:31fe79c6544c 108 return *this;
Gaku0606 0:31fe79c6544c 109 };
Gaku0606 0:31fe79c6544c 110
Gaku0606 0:31fe79c6544c 111 /**
Gaku0606 0:31fe79c6544c 112 @bref クォータニオンの複素共役を返します.
Gaku0606 0:31fe79c6544c 113 @note 本当はアスタリスクが良かったのですが,ポインタと紛らわしいのでマイナスにしました.
Gaku0606 0:31fe79c6544c 114 */
Gaku0606 0:31fe79c6544c 115 Quaternion operator-(){
Gaku0606 0:31fe79c6544c 116 Quaternion Q;
Gaku0606 0:31fe79c6544c 117 Q.w = w;
Gaku0606 0:31fe79c6544c 118 Q.x = -x;
Gaku0606 0:31fe79c6544c 119 Q.y = -y;
Gaku0606 0:31fe79c6544c 120 Q.z = -z;
Gaku0606 0:31fe79c6544c 121 return Q;
Gaku0606 0:31fe79c6544c 122 };
Gaku0606 0:31fe79c6544c 123
Gaku0606 0:31fe79c6544c 124 /**
Gaku0606 0:31fe79c6544c 125 @bref クォータニオンを正規化して,単位クォータニオンにします.
Gaku0606 0:31fe79c6544c 126 @note 掛け算などを行うたびに実行することをお勧めします.
Gaku0606 5:3c531c1f56cc 127 @note ただ、クォータニオンの時間微分は正規化してはいけません
Gaku0606 0:31fe79c6544c 128 */
Gaku0606 5:3c531c1f56cc 129 void Normalize(){
Gaku0606 7:631c068aded7 130 float norm = sqrt(w*w + x*x + y*y + z*z);
Gaku0606 7:631c068aded7 131 if (norm != 0.0f){
Gaku0606 0:31fe79c6544c 132 w /= norm;
Gaku0606 0:31fe79c6544c 133 x /= norm;
Gaku0606 0:31fe79c6544c 134 y /= norm;
Gaku0606 0:31fe79c6544c 135 z /= norm;
Gaku0606 0:31fe79c6544c 136 return;
Gaku0606 0:31fe79c6544c 137 }
Gaku0606 0:31fe79c6544c 138 else{
Gaku0606 0:31fe79c6544c 139 return;
Gaku0606 0:31fe79c6544c 140 }
Gaku0606 0:31fe79c6544c 141 };
Gaku0606 5:3c531c1f56cc 142
Gaku0606 5:3c531c1f56cc 143 /**
Gaku0606 5:3c531c1f56cc 144 * @bref クォータニオンを初期化します
Gaku0606 5:3c531c1f56cc 145 */
Gaku0606 7:631c068aded7 146 template <typename T> void Set(T _w, T _x, T _y, T _z);
Gaku0606 5:3c531c1f56cc 147 /**
Gaku0606 5:3c531c1f56cc 148 * @bref クォータニオンをVector3クラスで初期化します。
Gaku0606 5:3c531c1f56cc 149 */
Gaku0606 7:631c068aded7 150 void Set(Vector3 vec);
Gaku0606 5:3c531c1f56cc 151
Gaku0606 5:3c531c1f56cc 152 /**
Gaku0606 5:3c531c1f56cc 153 * @bref クォータニオンを回転軸と回転角度によって初期化します。
Gaku0606 5:3c531c1f56cc 154 * param vec 回転軸となる3次元ベクトル
Gaku0606 5:3c531c1f56cc 155 * param angle 回転角 [rad]
Gaku0606 5:3c531c1f56cc 156 */
Gaku0606 7:631c068aded7 157 void Set(Vector3 vec, float angle){
Gaku0606 5:3c531c1f56cc 158 vec.Normalize();
Gaku0606 7:631c068aded7 159 float halfAngle = 0.5f * angle ;
Gaku0606 5:3c531c1f56cc 160
Gaku0606 8:0b4374931b0e 161 w = cosf(halfAngle);
Gaku0606 8:0b4374931b0e 162 x = vec.x * sinf(halfAngle);
Gaku0606 8:0b4374931b0e 163 y = vec.y * sinf(halfAngle);
Gaku0606 8:0b4374931b0e 164 z = vec.z * sinf(halfAngle);
Gaku0606 5:3c531c1f56cc 165 }
Gaku0606 5:3c531c1f56cc 166
Gaku0606 5:3c531c1f56cc 167 /**
Gaku0606 5:3c531c1f56cc 168 * @bref クォータニオンの各要素に配列のようにアクセスします
Gaku0606 5:3c531c1f56cc 169 */
Gaku0606 8:0b4374931b0e 170 float q(int i){
Gaku0606 8:0b4374931b0e 171 float ans = 0.0;
Gaku0606 5:3c531c1f56cc 172 switch (i){
Gaku0606 5:3c531c1f56cc 173 case 1:
Gaku0606 5:3c531c1f56cc 174 ans = w;
Gaku0606 5:3c531c1f56cc 175 break;
Gaku0606 5:3c531c1f56cc 176 case 2:
Gaku0606 5:3c531c1f56cc 177 ans = x;
Gaku0606 5:3c531c1f56cc 178 break;
Gaku0606 5:3c531c1f56cc 179 case 3:
Gaku0606 5:3c531c1f56cc 180 ans = y;
Gaku0606 5:3c531c1f56cc 181 break;
Gaku0606 5:3c531c1f56cc 182 case 4:
Gaku0606 5:3c531c1f56cc 183 ans = z;
Gaku0606 5:3c531c1f56cc 184 break;
Gaku0606 5:3c531c1f56cc 185 }
Gaku0606 5:3c531c1f56cc 186 return ans;
Gaku0606 5:3c531c1f56cc 187 }
Gaku0606 5:3c531c1f56cc 188
Gaku0606 5:3c531c1f56cc 189 /**
Gaku0606 5:3c531c1f56cc 190 * @bref クォータニオンのノルムを計算します
Gaku0606 5:3c531c1f56cc 191 */
Gaku0606 8:0b4374931b0e 192 float Norm(){
Gaku0606 8:0b4374931b0e 193 return fabsf(w*w + x*x + y*y + z*z);
Gaku0606 5:3c531c1f56cc 194 }
Gaku0606 5:3c531c1f56cc 195
Gaku0606 5:3c531c1f56cc 196
Gaku0606 5:3c531c1f56cc 197 /** クォータニオンとクォータニオンを比較して等しければtrue 等しくなければfalse*/
Gaku0606 5:3c531c1f56cc 198 bool operator==(Quaternion Q){
Gaku0606 5:3c531c1f56cc 199 if (w == Q.w && x == Q.x && y == Q.y && z == Q.z){
Gaku0606 5:3c531c1f56cc 200 return true;
Gaku0606 5:3c531c1f56cc 201 }
Gaku0606 5:3c531c1f56cc 202 return false;
Gaku0606 5:3c531c1f56cc 203 }
Gaku0606 5:3c531c1f56cc 204 /** クォータニオンとクォータニオンを比較して等しくなければtrue 等しければfalse*/
Gaku0606 5:3c531c1f56cc 205 bool operator!=(Quaternion Q){
Gaku0606 5:3c531c1f56cc 206 if (w == Q.w && x == Q.x && y == Q.y && z == Q.z){
Gaku0606 5:3c531c1f56cc 207 return false;
Gaku0606 5:3c531c1f56cc 208 }
Gaku0606 5:3c531c1f56cc 209 return true;
Gaku0606 5:3c531c1f56cc 210 }
Gaku0606 5:3c531c1f56cc 211
Gaku0606 5:3c531c1f56cc 212 /**
Gaku0606 5:3c531c1f56cc 213 * @bref 2つの3次元ベクトルを一致させるクォータニオンを計算
Gaku0606 5:3c531c1f56cc 214 * @param from 始点となるベクトルのインスタンス
Gaku0606 5:3c531c1f56cc 215 * @param to 終点となるベクトルのインスタンス
Gaku0606 5:3c531c1f56cc 216 */
Gaku0606 5:3c531c1f56cc 217 void FromToRotation(Vector3 from, Vector3 to);
Gaku0606 5:3c531c1f56cc 218
Gaku0606 5:3c531c1f56cc 219 /**
Gaku0606 5:3c531c1f56cc 220 @bref オイラー角で姿勢を取得します.
Gaku0606 5:3c531c1f56cc 221 @param val ロール,ピッチ,ヨーの順に配列に格納します.3つ以上の要素の配列を入れてください.
Gaku0606 5:3c531c1f56cc 222 @note 値は[rad]です.[degree]に変換が必要な場合は別途計算して下さい.
Gaku0606 5:3c531c1f56cc 223 */
Gaku0606 7:631c068aded7 224 void GetEulerAngle(float *val){
Gaku0606 7:631c068aded7 225 float q0q0 = w * w, q1q1q2q2 = x * x - y * y, q3q3 = z * z;
Gaku0606 8:0b4374931b0e 226 val[0] = (atan2f(2.0f * (w * x + y * z), q0q0 - q1q1q2q2 + q3q3));
Gaku0606 8:0b4374931b0e 227 val[1] = (-asinf(2.0f * (x * z - w * y)));
Gaku0606 8:0b4374931b0e 228 val[2] = (atan2f(2.0f * (x * y + w * z), q0q0 + q1q1q2q2 - q3q3));
Gaku0606 8:0b4374931b0e 229 }
Gaku0606 8:0b4374931b0e 230
Gaku0606 8:0b4374931b0e 231 /**
Gaku0606 8:0b4374931b0e 232 @bref オイラー角で姿勢を取得します.
Gaku0606 8:0b4374931b0e 233 @param val ロール,ピッチ,ヨーの順に配列に格納します.3つ以上の要素の配列を入れてください.
Gaku0606 8:0b4374931b0e 234 @note 値は[rad]です.[degree]に変換が必要な場合は別途計算して下さい.
Gaku0606 8:0b4374931b0e 235 */
Gaku0606 8:0b4374931b0e 236 void GetEulerAngle(Vector3 *v) {
Gaku0606 8:0b4374931b0e 237 float q0q0 = w * w, q1q1q2q2 = x * x - y * y, q3q3 = z * z;
Gaku0606 8:0b4374931b0e 238 v->x = (atan2f(2.0f * (w * x + y * z), q0q0 - q1q1q2q2 + q3q3));
Gaku0606 8:0b4374931b0e 239 v->y = (-asinf(2.0f * (x * z - w * y)));
Gaku0606 8:0b4374931b0e 240 v->z = (atan2f(2.0f * (x * y + w * z), q0q0 + q1q1q2q2 - q3q3));
Gaku0606 5:3c531c1f56cc 241 }
Gaku0606 5:3c531c1f56cc 242
Gaku0606 7:631c068aded7 243 /**
Gaku0606 7:631c068aded7 244 * @bref クォータニオンをVector3クラスに変換します
Gaku0606 7:631c068aded7 245 * @note クォータニオンのx,y,z成分を持ったベクトルを作ります
Gaku0606 7:631c068aded7 246 */
Gaku0606 7:631c068aded7 247 Vector3 ToVector3(){
Gaku0606 7:631c068aded7 248 Vector3 vec3(x, y, z);
Gaku0606 7:631c068aded7 249 return vec3;
Gaku0606 7:631c068aded7 250 }
Gaku0606 5:3c531c1f56cc 251
Gaku0606 7:631c068aded7 252 /**
Gaku0606 7:631c068aded7 253 * @bref 3次元ベクトルを回転します
Gaku0606 7:631c068aded7 254 * @param v 回転させたい3次元ベクトルのポインタ
Gaku0606 7:631c068aded7 255 * @note 余計なオブジェクトを作りません
Gaku0606 7:631c068aded7 256 */
Gaku0606 7:631c068aded7 257 void Rotation(Vector3* v) {
Gaku0606 7:631c068aded7 258 if (v == NULL) return;
Gaku0606 7:631c068aded7 259 static float ww = 0.0f;
Gaku0606 7:631c068aded7 260 static float xx = 0.0f;
Gaku0606 7:631c068aded7 261 static float yy = 0.0f;
Gaku0606 7:631c068aded7 262 static float zz = 0.0f;
Gaku0606 7:631c068aded7 263
Gaku0606 7:631c068aded7 264 static float vx = 0.0f, vy = 0.0f, vz = 0.0f;
Gaku0606 8:0b4374931b0e 265 static float _wx, _wy, _wz, _xy, _zx, _yz;
Gaku0606 7:631c068aded7 266 ww = w * w;
Gaku0606 7:631c068aded7 267 xx = x * x;
Gaku0606 7:631c068aded7 268 yy = y * y;
Gaku0606 7:631c068aded7 269 zz = z * z;
Gaku0606 7:631c068aded7 270
Gaku0606 7:631c068aded7 271 _wx = w * x;
Gaku0606 7:631c068aded7 272 _wy = w * y;
Gaku0606 7:631c068aded7 273 _wz = w * z;
Gaku0606 7:631c068aded7 274 _xy = x * y;
Gaku0606 8:0b4374931b0e 275 _zx = z * x;
Gaku0606 7:631c068aded7 276 _yz = y * z;
Gaku0606 7:631c068aded7 277
Gaku0606 8:0b4374931b0e 278 vx = (ww + xx - yy - zz) * v->x + 2.0f*(_xy - _wz)*v->y + 2.0f*(_zx + _wy) * v->z;
Gaku0606 7:631c068aded7 279 vy = 2.0f * (_xy + _wz) * v->x + (ww - xx + yy - zz) * v->y + 2.0f*(_yz - _wx)*v->z;
Gaku0606 8:0b4374931b0e 280 vz = 2.0f * (_zx - _wy) * v->x + 2.0f * (_wx + _yz)*v->y + (ww - xx - yy + zz)*v->z;
Gaku0606 7:631c068aded7 281
Gaku0606 7:631c068aded7 282 v->x = vx;
Gaku0606 7:631c068aded7 283 v->y = vy;
Gaku0606 7:631c068aded7 284 v->z = vz;
Gaku0606 7:631c068aded7 285 }
Gaku0606 7:631c068aded7 286
Gaku0606 7:631c068aded7 287 /**
Gaku0606 7:631c068aded7 288 * @bref 3次元ベクトルを回転します.ただし逆回転です
Gaku0606 7:631c068aded7 289 * @param v 回転させたい3次元ベクトルのポインタ
Gaku0606 7:631c068aded7 290 * @note 余計なオブジェクトを作りません
Gaku0606 7:631c068aded7 291 */
Gaku0606 7:631c068aded7 292 void InvRotation(Vector3* v) {
Gaku0606 7:631c068aded7 293 if (v == NULL) return;
Gaku0606 7:631c068aded7 294 static float ww = 0.0f;
Gaku0606 7:631c068aded7 295 static float xx = 0.0f;
Gaku0606 7:631c068aded7 296 static float yy = 0.0f;
Gaku0606 7:631c068aded7 297 static float zz = 0.0f;
Gaku0606 7:631c068aded7 298
Gaku0606 7:631c068aded7 299 static float vx = 0.0f, vy = 0.0f, vz = 0.0f;
Gaku0606 7:631c068aded7 300 static float _wx, _wy, _wz, _xy, _xz, _yz;
Gaku0606 7:631c068aded7 301 ww = w * w;
Gaku0606 7:631c068aded7 302 xx = x * x;
Gaku0606 7:631c068aded7 303 yy = y * y;
Gaku0606 7:631c068aded7 304 zz = z * z;
Gaku0606 7:631c068aded7 305
Gaku0606 7:631c068aded7 306 _wx = w * x;
Gaku0606 7:631c068aded7 307 _wy = w * y;
Gaku0606 7:631c068aded7 308 _wz = w * z;
Gaku0606 7:631c068aded7 309 _xy = x * y;
Gaku0606 7:631c068aded7 310 _xz = x * z;
Gaku0606 7:631c068aded7 311 _yz = y * z;
Gaku0606 7:631c068aded7 312
Gaku0606 7:631c068aded7 313 vx = (ww + xx - yy - zz) * v->x + 2.0f*(_xy + _wz)*v->y + 2.0f*(_xz - _wy) * v->z;
Gaku0606 7:631c068aded7 314 vy = 2.0f * (_xy - _wz) * v->x + (ww - xx + yy - zz) * v->y + 2.0f*(_yz + _wx)*v->z;
Gaku0606 7:631c068aded7 315 vz = 2.0f * (_xz + _wy) * v->x + 2.0f * (-_wx + _yz)*v->y + (ww - xx - yy + zz)*v->z;
Gaku0606 7:631c068aded7 316
Gaku0606 7:631c068aded7 317 v->x = vx;
Gaku0606 7:631c068aded7 318 v->y = vy;
Gaku0606 7:631c068aded7 319 v->z = vz;
Gaku0606 7:631c068aded7 320 }
Gaku0606 0:31fe79c6544c 321 };
Gaku0606 0:31fe79c6544c 322
Gaku0606 5:3c531c1f56cc 323 void Quaternion::FromToRotation(Vector3 from, Vector3 to){
Gaku0606 7:631c068aded7 324 float halfTheta = 0.5f * from.Angle(to);//回転角度 0からpi/2
Gaku0606 5:3c531c1f56cc 325 Vector3 axis = from * to;
Gaku0606 5:3c531c1f56cc 326 axis.Normalize();
Gaku0606 5:3c531c1f56cc 327
Gaku0606 5:3c531c1f56cc 328 w = cos(halfTheta);
Gaku0606 5:3c531c1f56cc 329 x = axis.x * sin(halfTheta);
Gaku0606 5:3c531c1f56cc 330 y = axis.y * sin(halfTheta);
Gaku0606 5:3c531c1f56cc 331 z = axis.z * sin(halfTheta);
Gaku0606 5:3c531c1f56cc 332 }
Gaku0606 5:3c531c1f56cc 333
Gaku0606 5:3c531c1f56cc 334
Gaku0606 5:3c531c1f56cc 335
Gaku0606 7:631c068aded7 336 template<typename T>void Quaternion::Set(T _w, T _x, T _y, T _z){
Gaku0606 5:3c531c1f56cc 337 w = _w;
Gaku0606 5:3c531c1f56cc 338 x = _x;
Gaku0606 5:3c531c1f56cc 339 y = _y;
Gaku0606 5:3c531c1f56cc 340 z = _z;
Gaku0606 5:3c531c1f56cc 341 return;
Gaku0606 5:3c531c1f56cc 342 }
Gaku0606 5:3c531c1f56cc 343
Gaku0606 7:631c068aded7 344 void Quaternion::Set(Vector3 vec){
Gaku0606 5:3c531c1f56cc 345 w = 0.0;
Gaku0606 5:3c531c1f56cc 346 x = vec.x;
Gaku0606 5:3c531c1f56cc 347 y = vec.y;
Gaku0606 5:3c531c1f56cc 348 z = vec.z;
Gaku0606 5:3c531c1f56cc 349 return;
Gaku0606 5:3c531c1f56cc 350 }
Gaku0606 5:3c531c1f56cc 351
Gaku0606 5:3c531c1f56cc 352 /**
Gaku0606 4:a914c6c3b74d 353 * @fn Quaternion operator*(Quaternion l, Quaternion r)
Gaku0606 4:a914c6c3b74d 354 * @bref クォータニオンの掛け算をします.この際,順序が重要です.
Gaku0606 4:a914c6c3b74d 355 */
Gaku0606 0:31fe79c6544c 356 Quaternion operator*(Quaternion l, Quaternion r){
Gaku0606 0:31fe79c6544c 357 static Quaternion Q;
Gaku0606 0:31fe79c6544c 358 Q.w = l.w*r.w - l.x*r.x - l.y*r.y - l.z*r.z;
Gaku0606 0:31fe79c6544c 359 Q.x = l.x*r.w + l.w*r.x - l.z*r.y + l.y*r.z;
Gaku0606 0:31fe79c6544c 360 Q.y = l.y*r.w + l.z*r.x + l.w*r.y - l.x*r.z;
Gaku0606 0:31fe79c6544c 361 Q.z = l.z*r.w - l.y*r.x + l.x*r.y + l.w*r.z;
Gaku0606 5:3c531c1f56cc 362
Gaku0606 0:31fe79c6544c 363 return Q;
Gaku0606 0:31fe79c6544c 364 };
Gaku0606 1:81bcd478f8d7 365
Gaku0606 5:3c531c1f56cc 366 /**
Gaku0606 4:a914c6c3b74d 367 * @fn Quaternion operator*(double s, Quaternion q)
Gaku0606 7:631c068aded7 368 * @bref クォータニオンをスカラー倍します.
Gaku0606 4:a914c6c3b74d 369 */
Gaku0606 7:631c068aded7 370 Quaternion operator*(float s, Quaternion q){
Gaku0606 0:31fe79c6544c 371 static Quaternion Q;
Gaku0606 0:31fe79c6544c 372 Q.w = q.w * s;
Gaku0606 0:31fe79c6544c 373 Q.x = q.x * s;
Gaku0606 0:31fe79c6544c 374 Q.y = q.y * s;
Gaku0606 0:31fe79c6544c 375 Q.z = q.z * s;
Gaku0606 0:31fe79c6544c 376 return Q;
Gaku0606 0:31fe79c6544c 377 };
Gaku0606 1:81bcd478f8d7 378
Gaku0606 4:a914c6c3b74d 379 /**
Gaku0606 4:a914c6c3b74d 380 * @fn Quaternion operator*(Quaternion q, double s)
Gaku0606 7:631c068aded7 381 * @bref クォータニオンをスカラー倍します.
Gaku0606 4:a914c6c3b74d 382 */
Gaku0606 7:631c068aded7 383 Quaternion operator*(Quaternion q, float s){
Gaku0606 0:31fe79c6544c 384 static Quaternion Q;
Gaku0606 0:31fe79c6544c 385 Q.w = q.w * s;
Gaku0606 0:31fe79c6544c 386 Q.x = q.x * s;
Gaku0606 0:31fe79c6544c 387 Q.y = q.y * s;
Gaku0606 0:31fe79c6544c 388 Q.z = q.z * s;
Gaku0606 0:31fe79c6544c 389 return Q;
Gaku0606 0:31fe79c6544c 390 };
Gaku0606 0:31fe79c6544c 391
Gaku0606 8:0b4374931b0e 392 /**
Gaku0606 8:0b4374931b0e 393 */
Gaku0606 8:0b4374931b0e 394 Vector3 operator*(Quaternion q, Vector3 v) {
Gaku0606 8:0b4374931b0e 395
Gaku0606 8:0b4374931b0e 396 static Vector3 ans;
Gaku0606 8:0b4374931b0e 397 static float ww = 0.0f;
Gaku0606 8:0b4374931b0e 398 static float xx = 0.0f;
Gaku0606 8:0b4374931b0e 399 static float yy = 0.0f;
Gaku0606 8:0b4374931b0e 400 static float zz = 0.0f;
Gaku0606 8:0b4374931b0e 401
Gaku0606 8:0b4374931b0e 402 //static float vx = 0.0f, vy = 0.0f, vz = 0.0f;
Gaku0606 8:0b4374931b0e 403 static float _wx, _wy, _wz, _xy, _zx, _yz;
Gaku0606 8:0b4374931b0e 404 ww = q.w * q.w;
Gaku0606 8:0b4374931b0e 405 xx = q.x * q.x;
Gaku0606 8:0b4374931b0e 406 yy = q.y * q.y;
Gaku0606 8:0b4374931b0e 407 zz = q.z * q.z;
Gaku0606 8:0b4374931b0e 408
Gaku0606 8:0b4374931b0e 409 _wx = q.w * q.x;
Gaku0606 8:0b4374931b0e 410 _wy = q.w * q.y;
Gaku0606 8:0b4374931b0e 411 _wz = q.w * q.z;
Gaku0606 8:0b4374931b0e 412 _xy = q.x * q.y;
Gaku0606 8:0b4374931b0e 413 _zx = q.z * q.x;
Gaku0606 8:0b4374931b0e 414 _yz = q.y * q.z;
Gaku0606 8:0b4374931b0e 415
Gaku0606 8:0b4374931b0e 416 ans.x = (ww + xx - yy - zz) * v.x + 2.0f*(_xy - _wz)*v.y + 2.0f*(_zx + _wy) * v.z;
Gaku0606 8:0b4374931b0e 417 ans.y = 2.0f * (_xy + _wz) * v.x + (ww - xx + yy - zz) * v.y + 2.0f*(_yz - _wx)*v.z;
Gaku0606 8:0b4374931b0e 418 ans.z = 2.0f * (_zx - _wy) * v.x + 2.0f * (_wx + _yz)*v.y + (ww - xx - yy + zz)*v.z;
Gaku0606 8:0b4374931b0e 419
Gaku0606 8:0b4374931b0e 420 return ans;
Gaku0606 8:0b4374931b0e 421 }
Gaku0606 8:0b4374931b0e 422
Gaku0606 5:3c531c1f56cc 423
Gaku0606 4:a914c6c3b74d 424 /**
Gaku0606 5:3c531c1f56cc 425 @bref クォータニオンの足し算をします.
Gaku0606 4:a914c6c3b74d 426 */
Gaku0606 0:31fe79c6544c 427 Quaternion operator+(Quaternion l, Quaternion r){
Gaku0606 0:31fe79c6544c 428 static Quaternion Q;
Gaku0606 0:31fe79c6544c 429 Q.w = l.w + r.w;
Gaku0606 0:31fe79c6544c 430 Q.x = l.x + r.x;
Gaku0606 0:31fe79c6544c 431 Q.y = l.y + r.y;
Gaku0606 0:31fe79c6544c 432 Q.z = l.z + r.z;
Gaku0606 0:31fe79c6544c 433 return Q;
Gaku0606 0:31fe79c6544c 434 }
Gaku0606 0:31fe79c6544c 435
Gaku0606 4:a914c6c3b74d 436 /**
Gaku0606 5:3c531c1f56cc 437 @bref クォータニオンの引き算をします.
Gaku0606 4:a914c6c3b74d 438 */
Gaku0606 0:31fe79c6544c 439 Quaternion operator-(Quaternion l, Quaternion r){
Gaku0606 0:31fe79c6544c 440 static Quaternion Q;
Gaku0606 0:31fe79c6544c 441 Q.w = l.w - r.w;
Gaku0606 0:31fe79c6544c 442 Q.x = l.x - r.x;
Gaku0606 0:31fe79c6544c 443 Q.y = l.y - r.y;
Gaku0606 0:31fe79c6544c 444 Q.z = l.z - r.z;
Gaku0606 0:31fe79c6544c 445 return Q;
Gaku0606 0:31fe79c6544c 446 }
Gaku0606 0:31fe79c6544c 447
Gaku0606 0:31fe79c6544c 448 #endif