示例#1
0
        /// <summary>
        /// Creates new quaternion that represents rotation defined by given 3x3 matrix.
        /// </summary>
        /// <param name="m">Matrix that defines the rotation.</param>
        /// <returns>
        /// Quaternion that represents rotation defined by given 3x3 matrix.
        /// </returns>
        public static Quaternion FromMatrix33(Matrix33 m)
        {
            float s, p, tr = m.M00 + m.M11 + m.M22;

            //check the diagonal
            if (tr > (float)0.0)
            {
                s = (float)Math.Sqrt(tr + 1.0f); p = 0.5f / s;
                return(new Quaternion(s * 0.5f, (m.M21 - m.M12) * p, (m.M02 - m.M20) * p, (m.M10 - m.M01) * p));
            }
            //diagonal is negative. now we have to find the biggest element on the diagonal
            //check if "M00" is the biggest element
            if ((m.M00 >= m.M11) && (m.M00 >= m.M22))
            {
                s = (float)Math.Sqrt(m.M00 - m.M11 - m.M22 + 1.0f); p = 0.5f / s;
                return(new Quaternion((m.M21 - m.M12) * p, s * 0.5f, (m.M10 + m.M01) * p, (m.M20 + m.M02) * p));
            }
            //check if "M11" is the biggest element
            if ((m.M11 >= m.M00) && (m.M11 >= m.M22))
            {
                s = (float)Math.Sqrt(m.M11 - m.M22 - m.M00 + 1.0f); p = 0.5f / s;
                return(new Quaternion((m.M02 - m.M20) * p, (m.M01 + m.M10) * p, s * 0.5f, (m.M21 + m.M12) * p));
            }
            //check if "M22" is the biggest element
            if ((m.M22 >= m.M00) && (m.M22 >= m.M11))
            {
                s = (float)Math.Sqrt(m.M22 - m.M00 - m.M11 + 1.0f); p = 0.5f / s;
                return(new Quaternion((m.M10 - m.M01) * p, (m.M02 + m.M20) * p, (m.M12 + m.M21) * p, s * 0.5f));
            }

            return(Quaternion.Identity);            // if it ends here, then we have no valid rotation matrix
        }
示例#2
0
        /// <summary>
        /// Creates a matrix that represents a spherical linear interpolation from one
        /// matrix to another.
        /// </summary>
        /// <remarks>
        /// <para>This is an implementation of interpolation without quaternions.</para>
        /// <para>
        /// Given two orthonormal 3x3 matrices this function calculates the shortest
        /// possible interpolation-path between the two rotations. The interpolation curve
        /// forms the shortest great arc on the rotation sphere (geodesic).
        /// </para>
        /// <para>Angular velocity of the interpolation is constant.</para>
        /// <para>Possible stability problems:</para>
        /// <para>
        /// There are two singularities at angle = 0 and angle = <see cref="Math.PI"/> .
        /// At 0 the interpolation-axis is arbitrary, which means any axis will produce
        /// the same result because we have no rotation. (1,0,0) axis is used in this
        /// case. At <see cref="Math.PI"/> the rotations point away from each other and
        /// the interpolation-axis is unpredictable. In this case axis (1,0,0) is used as
        /// well. If the angle is ~0 or ~PI, then a very small vector has to be normalized
        /// and this can cause numerical instability.
        /// </para>
        /// </remarks>
        /// <param name="m">First matrix.</param>
        /// <param name="n">Second matrix.</param>
        /// <param name="t">Interpolation parameter.</param>
        public void SetSlerp(Matrix34 m, Matrix34 n, float t)
        {
            // calculate delta-rotation between m and n (=39 flops)
            Matrix33 d = new Matrix33(), i = new Matrix33();

            d.M00 = m.M00 * n.M00 + m.M10 * n.M10 + m.M20 * n.M20; d.M01 = m.M00 * n.M01 + m.M10 * n.M11 + m.M20 * n.M21; d.M02 = m.M00 * n.M02 + m.M10 * n.M12 + m.M20 * n.M22;
            d.M10 = m.M01 * n.M00 + m.M11 * n.M10 + m.M21 * n.M20; d.M11 = m.M01 * n.M01 + m.M11 * n.M11 + m.M21 * n.M21; d.M12 = m.M01 * n.M02 + m.M11 * n.M12 + m.M21 * n.M22;
            d.M20 = d.M01 * d.M12 - d.M02 * d.M11; d.M21 = d.M02 * d.M10 - d.M00 * d.M12; d.M22 = d.M00 * d.M11 - d.M01 * d.M10;

            // extract angle and axis
            double cosine = MathHelpers.Clamp((d.M00 + d.M11 + d.M22 - 1.0) * 0.5, -1.0, +1.0);
            double angle  = Math.Atan2(Math.Sqrt(1.0 - cosine * cosine), cosine);
            var    axis   = new Vector3(d.M21 - d.M12, d.M02 - d.M20, d.M10 - d.M01);
            double l      = Math.Sqrt(axis | axis); if (l > 0.00001)

            {
                axis /= (float)l;
            }
            else
            {
                axis = new Vector3(1, 0, 0);
            }

            i.SetRotationAroundAxis((float)angle * t, axis);             // angle interpolation and calculation of new delta-matrix (=26 flops)

            // final concatenation (=39 flops)
            this.M00 = m.M00 * i.M00 + m.M01 * i.M10 + m.M02 * i.M20; this.M01 = m.M00 * i.M01 + m.M01 * i.M11 + m.M02 * i.M21; this.M02 = m.M00 * i.M02 + m.M01 * i.M12 + m.M02 * i.M22;
            this.M10 = m.M10 * i.M00 + m.M11 * i.M10 + m.M12 * i.M20; this.M11 = m.M10 * i.M01 + m.M11 * i.M11 + m.M12 * i.M21; this.M12 = m.M10 * i.M02 + m.M11 * i.M12 + m.M12 * i.M22;
            this.M20 = this.M01 * this.M12 - this.M02 * this.M11; this.M21 = this.M02 * this.M10 - this.M00 * this.M12; this.M22 = this.M00 * this.M11 - this.M01 * this.M10;

            this.M03 = m.M03 * (1 - t) + n.M03 * t;
            this.M13 = m.M13 * (1 - t) + n.M13 * t;
            this.M23 = m.M23 * (1 - t) + n.M23 * t;
        }
示例#3
0
 /// <summary>
 /// Creates new instance of type <see cref="Matrix34"/> .
 /// </summary>
 /// <param name="m33">
 /// <see cref="CryCil.Mathematics.Matrix33"/> to use to fill first 3 columns.
 /// </param>
 public Matrix34(Matrix33 m33)
     : this()
 {
     this.Row0 = new Vector4(m33.Row0, 0);
     this.Row1 = new Vector4(m33.Row1, 0);
     this.Row2 = new Vector4(m33.Row2, 1);
 }
示例#4
0
        /// <summary>
        /// Creates new matrix that is set to represent scaling operation.
        /// </summary>
        /// <param name="s">Scale to set.</param>
        /// <returns>New matrix.</returns>
        public static Matrix33 CreateScale(Vector3 s)
        {
            var matrix = new Matrix33();

            matrix.SetScale(s);

            return(matrix);
        }
示例#5
0
        /// <summary>
        /// Creates new matrix that is set to represent rotation around fixed Axes.
        /// </summary>
        /// <param name="rad">Angles of rotation.</param>
        /// <returns>New matrix.</returns>
        public static Matrix33 CreateRotationFromAngles(EulerAngles rad)
        {
            var matrix = new Matrix33();

            matrix.SetRotationFromAngles(rad);

            return(matrix);
        }
示例#6
0
        /// <summary>
        /// Creates new matrix that is set to represent rotation around Z axis.
        /// </summary>
        /// <param name="rad">Angle of rotation around Z axis.</param>
        /// <returns>New matrix.</returns>
        public static Matrix33 CreateRotationAroundZ(float rad)
        {
            var matrix = new Matrix33();

            matrix.SetRotationAroundZ(rad);

            return(matrix);
        }
示例#7
0
        /// <summary>
        /// Creates new matrix that is set to represent rotation around given axis.
        /// </summary>
        /// <param name="rot">
        /// <see cref="Vector3"/> which length represents an angle of rotation, and that,
        /// once normalized, represents an axis of rotation.
        /// </param>
        /// <returns>New matrix.</returns>
        public static Matrix33 CreateRotationAroundAxis(Vector3 rot)
        {
            var matrix = new Matrix33();

            matrix.SetRotationAroundAxis(rot);

            return(matrix);
        }
示例#8
0
        /// <summary>
        /// Creates new matrix that is set to represent rotation around given axis.
        /// </summary>
        /// <param name="c">   Cosine of angle of rotation.</param>
        /// <param name="s">   Sine of angle of rotation.</param>
        /// <param name="axis">Axis of rotation.</param>
        /// <returns>New matrix.</returns>
        public static Matrix33 CreateRotationAroundAxis(float c, float s, Vector3 axis)
        {
            var matrix = new Matrix33();

            matrix.SetRotationAroundAxis(c, s, axis);

            return(matrix);
        }
示例#9
0
        /// <summary>
        /// Creates new matrix from vectors that represent rows.
        /// </summary>
        /// <param name="vx"><see cref="Vector3"/> object that contains first row.</param>
        /// <param name="vy">
        /// <see cref="Vector3"/> object that contains second row.
        /// </param>
        /// <param name="vz"><see cref="Vector3"/> object that contains third row.</param>
        /// <returns>New matrix.</returns>
        public static Matrix33 CreateFromVectors(Vector3 vx, Vector3 vy, Vector3 vz)
        {
            var matrix = new Matrix33();

            matrix.SetFromVectors(vx, vy, vz);

            return(matrix);
        }
示例#10
0
 /// <summary>
 /// Sets the values of this matrix to one that represents a rotation around an
 /// axis.
 /// </summary>
 /// <param name="c">   Cosine of the angle of the rotation.</param>
 /// <param name="s">   Sine of the angle of the rotation.</param>
 /// <param name="axis">
 /// <see cref="Vector3"/> object that represents axis of rotation.
 /// </param>
 /// <param name="t">   Optional translation vector.</param>
 public void SetRotationAroundAxis(float c, float s, Vector3 axis, Vector3 t = default(Vector3))
 {
     this = new Matrix34(Matrix33.CreateRotationAroundAxis(c, s, axis))
     {
         M03 = t.X,
         M13 = t.Y,
         M23 = t.Z
     };
 }
示例#11
0
 /// <summary>
 /// Creates new instance of <see cref="Matrix44" /> class.
 /// </summary>
 /// <param name="m"> <see cref="Matrix33" /> to fill new matrix with. </param>
 public Matrix44(ref Matrix33 m)
     : this()
 {
     if (!m.IsValid)
     {
         throw new ArgumentException("Parameter must be a valid matrix.");
     }
     this.Row0.X = m.Row1.X; this.Row0.Y = m.Row1.Y; this.Row0.Z = m.Row1.Z; this.Row0.W = 0;
     this.Row1.X = m.Row2.X; this.Row1.Y = m.Row2.Y; this.Row1.Z = m.Row2.Z; this.Row1.W = 0;
     this.Row2.X = m.Row2.X; this.Row2.Y = m.Row2.Y; this.Row2.Z = m.Row2.Z; this.Row2.W = 0;
     this.Row3.X = 0; this.Row3.Y = 0; this.Row3.Z = 0; this.Row3.W = 1;
 }
示例#12
0
 /// <summary>
 /// Creates new instance of <see cref="EulerAngles"/> struct.
 /// </summary>
 /// <param name="matrix">Matrix that defines new instance.</param>
 public EulerAngles(Matrix33 matrix)
 {
     // Assert matrix being orthonormal.
     this.Roll = (float)Math.Asin(Math.Max(-1.0f, Math.Min(1.0f, -matrix.M20)));
     if (Math.Abs(Math.Abs(this.Roll) - (float)(Math.PI * 0.5)) < 0.01f)
     {
         this.Pitch = 0;
         this.Yaw   = (float)Math.Atan2(-matrix.M01, matrix.M11);
     }
     else
     {
         this.Pitch = (float)Math.Atan2(matrix.M21, matrix.M22);
         this.Yaw   = (float)Math.Atan2(matrix.M10, matrix.M00);
     }
 }
示例#13
0
        /// <summary>
        /// Multiplies the matrix by other matrix.
        /// </summary>
        /// <param name="left"> Left operand.</param>
        /// <param name="right">Right opearnd.</param>
        /// <returns>Result of operation.</returns>
        public static Matrix33 operator *(Matrix33 left, Matrix33 right)
        {
            var m = new Matrix33
            {
                M00 = left.M00 * right.M00 + left.M01 * right.M10 + left.M02 * right.M20,
                M01 = left.M00 * right.M01 + left.M01 * right.M11 + left.M02 * right.M21,
                M02 = left.M00 * right.M02 + left.M01 * right.M12 + left.M02 * right.M22,
                M10 = left.M10 * right.M00 + left.M11 * right.M10 + left.M12 * right.M20,
                M11 = left.M10 * right.M01 + left.M11 * right.M11 + left.M12 * right.M21,
                M12 = left.M10 * right.M02 + left.M11 * right.M12 + left.M12 * right.M22,
                M20 = left.M20 * right.M00 + left.M21 * right.M10 + left.M22 * right.M20,
                M21 = left.M20 * right.M01 + left.M21 * right.M11 + left.M22 * right.M21,
                M22 = left.M20 * right.M02 + left.M21 * right.M12 + left.M22 * right.M22
            };

            return(m);
        }
示例#14
0
 /// <summary>
 /// Creates new instance of <see cref="Quaternion"/> struct.
 /// </summary>
 /// <param name="matrix">3x3 matrix that represents rotation.</param>
 public Quaternion(Matrix33 matrix)
 {
     this = FromMatrix33(matrix);
 }
示例#15
0
        /// <summary>
        /// Convert three Euler angles to 3x3 matrix (rotation order:XYZ)
        /// </summary>
        /// <param name="rad">Angles of rotation.</param>
        /// <param name="t">  Optional translation vector.</param>
        public void SetRotationWithEulerAngles(EulerAngles rad, Vector3 t = default(Vector3))
        {
            this = new Matrix34(Matrix33.CreateRotationFromAngles(rad));

            this.SetTranslation(t);
        }
示例#16
0
        /// <summary>
        /// Sets the values of this matrix to one that represents a rotation around Z
        /// axis.
        /// </summary>
        /// <param name="rad">Angle of rotation in radians.</param>
        /// <param name="t">  Optional translation vector.</param>
        public void SetRotationAroundZ(float rad, Vector3 t = default(Vector3))
        {
            this = new Matrix34(Matrix33.CreateRotationAroundZ(rad));

            this.SetTranslation(t);
        }
示例#17
0
        /// <summary>
        /// Sets the values of this matrix to one that represents a rotation around an
        /// axis.
        /// </summary>
        /// <param name="rot">
        /// <see cref="Vector3"/> object which length represents an angle of rotation and
        /// which direction represents an axis of rotation.
        /// </param>
        /// <param name="t">  Optional translation vector.</param>
        public void SetRotationAroundAxis(Vector3 rot, Vector3 t = default(Vector3))
        {
            this = new Matrix34(Matrix33.CreateRotationAroundAxis(rot));

            this.SetTranslation(t);
        }
示例#18
0
        /// <summary>
        /// Sets the value of the matrix to one that represents scaling.
        /// </summary>
        /// <param name="s"><see cref="Vector3"/> object that represents scale.</param>
        /// <param name="t">
        /// Optional <see cref="Vector3"/> object that represents translation.
        /// </param>
        public void SetScale(Vector3 s, Vector3 t = default(Vector3))
        {
            this = new Matrix34(Matrix33.CreateScale(s));

            this.SetTranslation(t);
        }