avc81's picture

conversion from matrix to quaternion and back

Project:The Open Toolkit library
Version:1.1-2014-01-02
Component:Code
Category:feature request
Priority:normal
Assigned:avc81
Status:closed
Description

why don't we add these methods to Matrix,Matrix4d and Quaternion,Quaternion4d? They will be useful


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
avc81's picture

#1

(add to the previous request)
i noticed that there are no + and - operators(or functions) for matrices

flopoloco's picture

#2

Can you submit a patch to the repository?

avc81's picture

#3

today i'm gonna test the functions i wrote. then i will submit a patch (never done that before for opentk, do u use svn?)

the Fiddler's picture

#5

Yes, we are still on svn. Please create the patch against trunk, as it would be easier to test and merge.

avc81's picture

#6

you trunk link doesn't work
may i use https://opentk.svn.sourceforge.net/svnroot/opentk/trunk/?
i see that your last commit is dated 2 months ago

the Fiddler's picture

#7

Yes please use that (the previous link pointed to instructions, not the svn server).

avc81's picture

#8

patch created. how can i commit it?

the Fiddler's picture

#9

Status:open» in progress

Please attach it here and I will commit it!

avc81's picture

#10

no way to attach a file here. Anyway there are some redundancies and maybe too much refs but it works. fix it as u please.

p.s. i will add + and - later cause they are trivial and maybe u want to add them yourself

Index: Source/OpenTK/Math/Matrix4.cs
===================================================================
--- Source/OpenTK/Math/Matrix4.cs	(revision 3066)
+++ Source/OpenTK/Math/Matrix4.cs	(working copy)
@@ -275,6 +275,80 @@
 
         #region Static
 
+          #region CreateFromQuaternion
+        /// <summary>
+        /// Build a rotation matrix from the specified quaternion.
+        /// </summary>
+        /// <param name="q">Quaternion to translate.</param>
+        /// <param name="m">Matrix result.</param>
+        public static void CreateFromQuaternion(ref Quaternion q,ref Matrix4 m)
+        {
+            m = Matrix4.Identity;
+
+			float X = q.X;
+			float Y = q.Y;
+			float Z = q.Z;
+			float W = q.W;
+			
+			float xx = X * X;
+			float xy = X * Y;
+			float xz = X * Z;
+			float xw = X * W;
+			float yy = Y * Y;
+			float yz = Y * Z;
+			float yw = Y * W;
+			float zz = Z * Z;
+			float zw = Z * W;
+			
+			m.M11 = 1 - 2 * (yy + zz);
+			m.M21 = 2 * (xy - zw);
+			m.M31 = 2 * (xz + yw);
+			m.M12 = 2 * (xy + zw);
+			m.M22 = 1 - 2 * (xx + zz);
+			m.M32 = 2 * (yz - xw);
+			m.M13 = 2 * (xz - yw);
+			m.M23 = 2 * (yz + xw);
+			m.M33 = 1 - 2 * (xx + yy);
+        }
+
+        /// <summary>
+        /// Build a rotation matrix from the specified quaternion.
+        /// </summary>
+        /// <param name="q">Quaternion to translate.</param>
+        /// <returns>A matrix instance.</returns>
+        public static Matrix4 CreateFromQuaternion(ref Quaternion q)
+        {
+            Matrix4 result = Matrix4.Identity;
+
+			float X = q.X;
+			float Y = q.Y;
+			float Z = q.Z;
+			float W = q.W;
+			
+			float xx = X * X;
+			float xy = X * Y;
+			float xz = X * Z;
+			float xw = X * W;
+			float yy = Y * Y;
+			float yz = Y * Z;
+			float yw = Y * W;
+			float zz = Z * Z;
+			float zw = Z * W;
+			
+			result.M11 = 1 - 2 * (yy + zz);
+			result.M21 = 2 * (xy - zw);
+			result.M31 = 2 * (xz + yw);
+			result.M12 = 2 * (xy + zw);
+			result.M22 = 1 - 2 * (xx + zz);
+			result.M32 = 2 * (yz - xw);
+			result.M13 = 2 * (xz - yw);
+			result.M23 = 2 * (yz + xw);
+			result.M33 = 1 - 2 * (xx + yy);
+            return result;
+        }
+
+        #endregion
+        
         #region CreateFromAxisAngle
 
         /// <summary>
Index: Source/OpenTK/Math/Matrix4d.cs
===================================================================
--- Source/OpenTK/Math/Matrix4d.cs	(revision 3066)
+++ Source/OpenTK/Math/Matrix4d.cs	(working copy)
@@ -275,6 +275,80 @@
 
         #region Static
 
+        #region CreateFromQuaternion
+        /// <summary>
+        /// Build a rotation matrix from the specified quaternion.
+        /// </summary>
+        /// <param name="q">Quaternion to translate.</param>
+        /// <param name="m">Matrix result.</param>
+        public static void CreateFromQuaternion(ref Quaterniond q,ref Matrix4d m)
+        {
+            m = Matrix4d.Identity;
+
+			double X = q.X;
+			double Y = q.Y;
+			double Z = q.Z;
+			double W = q.W;
+			
+			double xx = X * X;
+			double xy = X * Y;
+			double xz = X * Z;
+			double xw = X * W;
+			double yy = Y * Y;
+			double yz = Y * Z;
+			double yw = Y * W;
+			double zz = Z * Z;
+			double zw = Z * W;
+			
+			m.M11 = 1 - 2 * (yy + zz);
+			m.M21 = 2 * (xy - zw);
+			m.M31 = 2 * (xz + yw);
+			m.M12 = 2 * (xy + zw);
+			m.M22 = 1 - 2 * (xx + zz);
+			m.M32 = 2 * (yz - xw);
+			m.M13 = 2 * (xz - yw);
+			m.M23 = 2 * (yz + xw);
+			m.M33 = 1 - 2 * (xx + yy);
+        }
+
+        /// <summary>
+        /// Build a rotation matrix from the specified quaternion.
+        /// </summary>
+        /// <param name="q">Quaternion to translate.</param>
+        /// <returns>A matrix instance.</returns>
+        public static Matrix4d CreateFromQuaternion(ref Quaterniond q)
+        {
+            Matrix4d result = Matrix4d.Identity;
+
+			double X = q.X;
+			double Y = q.Y;
+			double Z = q.Z;
+			double W = q.W;
+			
+			double xx = X * X;
+			double xy = X * Y;
+			double xz = X * Z;
+			double xw = X * W;
+			double yy = Y * Y;
+			double yz = Y * Z;
+			double yw = Y * W;
+			double zz = Z * Z;
+			double zw = Z * W;
+			
+			result.M11 = 1 - 2 * (yy + zz);
+			result.M21 = 2 * (xy - zw);
+			result.M31 = 2 * (xz + yw);
+			result.M12 = 2 * (xy + zw);
+			result.M22 = 1 - 2 * (xx + zz);
+			result.M32 = 2 * (yz - xw);
+			result.M13 = 2 * (xz - yw);
+			result.M23 = 2 * (yz + xw);
+			result.M33 = 1 - 2 * (xx + yy);
+            return result;
+        }
+
+        #endregion
+        
         #region CreateFromAxisAngle
 
         /// <summary>
Index: Source/OpenTK/Math/Quaternion.cs
===================================================================
--- Source/OpenTK/Math/Quaternion.cs	(revision 3066)
+++ Source/OpenTK/Math/Quaternion.cs	(working copy)
@@ -453,7 +453,122 @@
         }
 
         #endregion
+        
+        #region FromMatrix
+         /// <summary>
+        /// Build a quaternion from the specified rotation matrix.
+        /// </summary>
+        /// <param name="m">Matrix to translate</param>
+        /// <param name="q">Quaternion result</param>
+        public static void CreateFromMatrix(ref Matrix4 m, ref Quaternion q)
+        {
+            float trace = 1 + m.M11 + m.M22 + m.M33;
+			float S = 0;
+			float X = 0;
+			float Y = 0;
+			float Z = 0;
+			float W = 0;
+			
+			if (trace > 0.0000001) 
+			{
+				S = (float)Math.Sqrt(trace) * 2;
+				X = (m.M23 - m.M32) / S;
+				Y = (m.M31 - m.M13) / S;
+				Z = (m.M12 - m.M21) / S;
+				W = 0.25f * S;
+			} 
+			else 
+			{
+				if (m.M11 > m.M22 && m.M11 > m.M33) 
+				{
+					// Column 0: 
+					S = (float)Math.Sqrt(1.0 + m.M11 - m.M22 - m.M33) * 2;
+					X = 0.25f * S;
+					Y = (m.M12 + m.M21) / S;
+					Z = (m.M31 + m.M13) / S;
+					W = (m.M23 - m.M32) / S;
+				} 
+				else if (m.M22 > m.M33) 
+				{
+					// Column 1: 
+					S = (float)Math.Sqrt(1.0 + m.M22 - m.M11 - m.M33) * 2;
+					X = (m.M12 + m.M21) / S;
+					Y = 0.25f * S;
+					Z = (m.M23 + m.M32) / S;
+					W = (m.M31 - m.M13) / S;
+				} 
+				else 
+				{
+					// Column 2:
+					S = (float)Math.Sqrt(1.0 + m.M33 - m.M11 - m.M22) * 2;
+					X = (m.M31 + m.M13) / S;
+					Y = (m.M23 + m.M32) / S;
+					Z = 0.25f * S;
+					W = (m.M12 - m.M21) / S;
+				}
+			}
+			q = new Quaternion(X, Y, Z, W);
+        }
 
+        /// <summary>
+        /// Build a quaternion from the specified rotation matrix.
+        /// </summary>
+        /// <param name="m">Matrix to translate.</param>
+        /// <returns>A quaternion</returns>
+        public static Quaternion CreateFromMatrix(ref Matrix4 m)
+        {
+        	Quaternion q;
+        	
+            float trace = 1 + m.M11 + m.M22 + m.M33;
+			float S = 0;
+			float X = 0;
+			float Y = 0;
+			float Z = 0;
+			float W = 0;
+			
+			if (trace > 0.0000001) 
+			{
+				S = (float)Math.Sqrt(trace) * 2;
+				X = (m.M23 - m.M32) / S;
+				Y = (m.M31 - m.M13) / S;
+				Z = (m.M12 - m.M21) / S;
+				W = 0.25f * S;
+			} 
+			else 
+			{
+				if (m.M11 > m.M22 && m.M11 > m.M33) 
+				{
+					// Column 0: 
+					S = (float)Math.Sqrt(1.0 + m.M11 - m.M22 - m.M33) * 2;
+					X = 0.25f * S;
+					Y = (m.M12 + m.M21) / S;
+					Z = (m.M31 + m.M13) / S;
+					W = (m.M23 - m.M32) / S;
+				} 
+				else if (m.M22 > m.M33) 
+				{
+					// Column 1: 
+					S = (float)Math.Sqrt(1.0 + m.M22 - m.M11 - m.M33) * 2;
+					X = (m.M12 + m.M21) / S;
+					Y = 0.25f * S;
+					Z = (m.M23 + m.M32) / S;
+					W = (m.M31 - m.M13) / S;
+				} 
+				else 
+				{
+					// Column 2:
+					S = (float)Math.Sqrt(1.0 + m.M33 - m.M11 - m.M22) * 2;
+					X = (m.M31 + m.M13) / S;
+					Y = (m.M23 + m.M32) / S;
+					Z = 0.25f * S;
+					W = (m.M12 - m.M21) / S;
+				}
+			}
+			q = new Quaternion(X, Y, Z, W);
+			return q;
+        }
+        #endregion        
+
         #region FromAxisAngle
 
         /// <summary>
Index: Source/OpenTK/Math/Quaterniond.cs
===================================================================
--- Source/OpenTK/Math/Quaterniond.cs	(revision 3066)
+++ Source/OpenTK/Math/Quaterniond.cs	(working copy)
@@ -453,7 +453,122 @@
         }
 
         #endregion
+        
+        #region FromMatrix
+         /// <summary>
+        /// Build a quaternion from the specified rotation matrix.
+        /// </summary>
+        /// <param name="m">Matrix to translate</param>
+        /// <param name="q">Quaternion result</param>
+        public static void CreateFromMatrix(ref Matrix4d m, ref Quaterniond q)
+        {
+            double trace = 1 + m.M11 + m.M22 + m.M33;
+			double S = 0;
+			double X = 0;
+			double Y = 0;
+			double Z = 0;
+			double W = 0;
+			
+			if (trace > 0.0000001) 
+			{
+				S = Math.Sqrt(trace) * 2;
+				X = (m.M23 - m.M32) / S;
+				Y = (m.M31 - m.M13) / S;
+				Z = (m.M12 - m.M21) / S;
+				W = 0.25 * S;
+			} 
+			else 
+			{
+				if (m.M11 > m.M22 && m.M11 > m.M33) 
+				{
+					// Column 0: 
+					S = Math.Sqrt(1.0 + m.M11 - m.M22 - m.M33) * 2;
+					X = 0.25 * S;
+					Y = (m.M12 + m.M21) / S;
+					Z = (m.M31 + m.M13) / S;
+					W = (m.M23 - m.M32) / S;
+				} 
+				else if (m.M22 > m.M33) 
+				{
+					// Column 1: 
+					S = Math.Sqrt(1.0 + m.M22 - m.M11 - m.M33) * 2;
+					X = (m.M12 + m.M21) / S;
+					Y = 0.25 * S;
+					Z = (m.M23 + m.M32) / S;
+					W = (m.M31 - m.M13) / S;
+				} 
+				else 
+				{
+					// Column 2:
+					S = Math.Sqrt(1.0 + m.M33 - m.M11 - m.M22) * 2;
+					X = (m.M31 + m.M13) / S;
+					Y = (m.M23 + m.M32) / S;
+					Z = 0.25 * S;
+					W = (m.M12 - m.M21) / S;
+				}
+			}
+			q = new Quaterniond(X, Y, Z, W);
+        }
 
+        /// <summary>
+        /// Build a quaternion from the specified rotation matrix.
+        /// </summary>
+        /// <param name="m">Matrix to translate.</param>
+        /// <returns>A quaternion</returns>
+        public static Quaterniond CreateFromMatrix(ref Matrix4d m)
+        {
+        	Quaterniond q;
+        	
+            double trace = 1 + m.M11 + m.M22 + m.M33;
+			double S = 0;
+			double X = 0;
+			double Y = 0;
+			double Z = 0;
+			double W = 0;
+			
+			if (trace > 0.0000001) 
+			{
+				S = Math.Sqrt(trace) * 2;
+				X = (m.M23 - m.M32) / S;
+				Y = (m.M31 - m.M13) / S;
+				Z = (m.M12 - m.M21) / S;
+				W = 0.25 * S;
+			} 
+			else 
+			{
+				if (m.M11 > m.M22 && m.M11 > m.M33) 
+				{
+					// Column 0: 
+					S = Math.Sqrt(1.0 + m.M11 - m.M22 - m.M33) * 2;
+					X = 0.25 * S;
+					Y = (m.M12 + m.M21) / S;
+					Z = (m.M31 + m.M13) / S;
+					W = (m.M23 - m.M32) / S;
+				} 
+				else if (m.M22 > m.M33) 
+				{
+					// Column 1: 
+					S = Math.Sqrt(1.0 + m.M22 - m.M11 - m.M33) * 2;
+					X = (m.M12 + m.M21) / S;
+					Y = 0.25 * S;
+					Z = (m.M23 + m.M32) / S;
+					W = (m.M31 - m.M13) / S;
+				} 
+				else 
+				{
+					// Column 2:
+					S = Math.Sqrt(1.0 + m.M33 - m.M11 - m.M22) * 2;
+					X = (m.M31 + m.M13) / S;
+					Y = (m.M23 + m.M32) / S;
+					Z = 0.25 * S;
+					W = (m.M12 - m.M21) / S;
+				}
+			}
+			q = new Quaterniond(X, Y, Z, W);
+			return q;
+        }
+        #endregion
+
         #region FromAxisAngle
 
         /// <summary>
@@ -681,7 +796,9 @@
         #endregion
 
         #endregion
+        
 
+
 #if false
 
         #region Fields
avc81's picture

#12

Assigned to:Anonymous» avc81
Status:in progress» in progress (commit)