# CSharpGL(32)矩阵与四元数与角度旋转轴的相互转换

CSharpGL(32)矩阵与四元数与角度旋转轴的相互转换

+BIT祝威+悄悄在此留下版了个权的信息说：

# 四元数

+BIT祝威+悄悄在此留下版了个权的信息说：

## 定义(angleDegree+axis到四元数)

1     public struct Quaternion
2     {
3         private float w;
4         private float x;
5         private float y;
6         private float z;
7
8         /// <summary>
9         /// Quaternion from a rotation angle and axis.
10         /// </summary>
11         /// <param name="angleDegree">angle in degree.</param>
12         /// <param name="axis">rotation axis.</param>
13         public Quaternion(float angleDegree, vec3 axis)
14         {
15             vec3 normalized = axis.normalize();
16             double radian = angleDegree * Math.PI / 180.0;
20             this.x = sin * normalized.x;
21             this.y = sin * normalized.y;
22             this.z = sin * normalized.z;
23         }
24     }

+BIT祝威+悄悄在此留下版了个权的信息说：

## 四元数到angleDegree+axis

1         public void Parse(out float angleDegree, out vec3 axis)
2         {
3             angleDegree = (float)(Math.Acos(w) * 2 * 180.0 / Math.PI);
4             axis = (new vec3(x, y, z)).normalize();
5         }
+BIT祝威+悄悄在此留下版了个权的信息说：

## 四元数到矩阵

1         /// <summary>
2         /// Transform this quaternion to equivalent matrix.
3         /// </summary>
4         /// <returns></returns>
5         public mat3 ToRotationMatrix()
6         {
7             vec3 col0 = new vec3(
8                 2 * (x * x + w * w) - 1,
9                 2 * x * y + 2 * w * z,
10                 2 * x * z - 2 * w * y);
11             vec3 col1 = new vec3(
12                 2 * x * y - 2 * w * z,
13                 2 * (y * y + w * w) - 1,
14                 2 * y * z + 2 * w * x);
15             vec3 col2 = new vec3(
16                 2 * x * z + 2 * w * y,
17                 2 * y * z - 2 * w * x,
18                 2 * (z * z + w * w) - 1);
19
20             return new mat3(col0, col1, col2);
21         }

+BIT祝威+悄悄在此留下版了个权的信息说：

## 矩阵到四元数

1         /// <summary>
2         /// Transform this matrix to a <see cref="Quaternion"/>.
3         /// </summary>
4         /// <returns></returns>
5 struct mat3
6 {
7     public Quaternion ToQuaternion()
8         {
9             // input matrix.
10             float m11 = this.col0.x, m12 = this.col1.x, m13 = this.col2.x;
11             float m21 = this.col0.y, m22 = this.col1.y, m23 = this.col2.y;
12             float m31 = this.col0.z, m32 = this.col1.z, m33 = this.col2.z;
13             // output quaternion
14             float x = 0, y = 0, z = 0, w = 0;
15             // detect biggest in w, x, y, z.
16             float fourWSquaredMinus1 = +m11 + m22 + m33;
17             float fourXSquaredMinus1 = +m11 - m22 - m33;
18             float fourYSquaredMinus1 = -m11 + m22 - m33;
19             float fourZSquaredMinus1 = -m11 - m22 + m33;
20             int biggestIndex = 0;
21             float biggest = fourWSquaredMinus1;
22             if (fourXSquaredMinus1 > biggest)
23             {
24                 biggest = fourXSquaredMinus1;
25                 biggestIndex = 1;
26             }
27             if (fourYSquaredMinus1 > biggest)
28             {
29                 biggest = fourYSquaredMinus1;
30                 biggestIndex = 2;
31             }
32             if (fourZSquaredMinus1 > biggest)
33             {
34                 biggest = fourZSquaredMinus1;
35                 biggestIndex = 3;
36             }
37             // sqrt and division
38             float biggestVal = (float)(Math.Sqrt(biggest + 1) * 0.5);
39             float mult = 0.25f / biggestVal;
40             // get output
41             switch (biggestIndex)
42             {
43                 case 0:
44                     w = biggestVal;
45                     x = (m23 - m32) * mult;
46                     y = (m31 - m13) * mult;
47                     z = (m12 - m21) * mult;
48                     break;
49
50                 case 1:
51                     x = biggestVal;
52                     w = (m23 - m32) * mult;
53                     y = (m12 + m21) * mult;
54                     z = (m31 + m13) * mult;
55                     break;
56
57                 case 2:
58                     y = biggestVal;
59                     w = (m31 - m13) * mult;
60                     x = (m12 + m21) * mult;
61                     z = (m23 + m32) * mult;
62                     break;
63
64                 case 3:
65                     z = biggestVal;
66                     w = (m12 - m21) * mult;
67                     x = (m31 + m13) * mult;
68                     y = (m23 + m32) * mult;
69                     break;
70
71                 default:
72                     break;
73             }
74
75             return new Quaternion(w, -x, -y, -z);
76         }
77     }
matrix to quaternion

BTW，OpenGL里的glRotate{fd}(angle, axis)里的angle是以角度为单位的。为了统一，我将CSharpGL里的所有angle都设定为以角度为单位了。

+BIT祝威+悄悄在此留下版了个权的信息说：

# 下载

CSharpGL已在GitHub开源，欢迎对OpenGL有兴趣的同学加入（https://github.com/bitzhuwei/CSharpGL

+BIT祝威+悄悄在此留下版了个权的信息说：

# 总结

posted @ 2016-09-23 03:32 BIT祝威 阅读(...) 评论(...) 编辑 收藏