/// <summary> /// Transforms a <see cref="M34f"/> to a <see cref="M33f"/> by deleting the /// specified row and column. Internally the <see cref="M34f"/> is tarnsformed /// to a <see cref="M44f"/> to delete the row and column. /// </summary> /// <param name="deleted_row">Row to delete.</param> /// <param name="deleted_column">Column to delete.</param> /// <returns>A <see cref="M33f"/>.</returns> public M33f Minor(int deleted_row, int deleted_column) { M44f temp = (M44f)this; M33f result = new M33f(); int checked_row = 0; for (int actual_row = 0; actual_row < 4; actual_row++) { int checked_column = 0; if (actual_row != deleted_row) { for (int actual_column = 0; actual_column < 4; actual_column++) { if (actual_column != deleted_column) { result[checked_row, checked_column] = temp[actual_row, actual_column]; checked_column++; } } checked_row++; } } return(result); }
public Similarity3f(M44f m, float epsilon = (float)0.00001) { if (!(m.M30.IsTiny(epsilon) && m.M31.IsTiny(epsilon) && m.M32.IsTiny(epsilon))) { throw new ArgumentException("Matrix contains perspective components."); } if (m.M33.IsTiny(epsilon)) { throw new ArgumentException("Matrix is not homogeneous."); } m /= m.M33; //normalize it var m33 = (M33f)m; var s0 = m33.C0.Norm2; var s1 = m33.C1.Norm2; var s2 = m33.C2.Norm2; var s = (s0 * s1 * s2).Pow((float)1.0 / 3); //geometric mean of scale if (!((s0 / s - 1).IsTiny(epsilon) && (s1 / s - 1).IsTiny(epsilon) && (s2 / s - 1).IsTiny(epsilon))) { throw new ArgumentException("Matrix features non-uniform scaling"); } m33 /= s; Scale = s; EuclideanTransformation = new Euclidean3f(m33, m.C3.XYZ); }
public static M44f Add(M34f a, M44f b) { return(new M44f( a.M00 + b.M00, a.M01 + b.M01, a.M02 + b.M02, a.M03 + b.M03, a.M10 + b.M10, a.M11 + b.M11, a.M12 + b.M12, a.M13 + b.M13, a.M20 + b.M20, a.M21 + b.M21, a.M22 + b.M22, a.M23 + b.M23, b.M30, b.M31, b.M32, 1 + b.M33 )); }
public static M44f Subtract(M44f a, M34f b) { return(new M44f( a.M00 - b.M00, a.M01 - b.M01, a.M02 - b.M02, a.M03 - b.M03, a.M10 - b.M10, a.M11 - b.M11, a.M12 - b.M12, a.M13 - b.M13, a.M20 - b.M20, a.M21 - b.M21, a.M22 - b.M22, a.M23 - b.M23, a.M30, a.M31, a.M32, a.M33 - 1 )); }
/// <summary> /// Computes from a <see cref="V3f"/> point (origin) and /// a <see cref="V3f"/> normal the transformation matrix /// and its inverse. /// </summary> /// <param name="origin">The point which will become the new origin.</param> /// <param name="normal">The normal vector of the new ground plane.</param> /// <param name="local2global">A <see cref="M44f"/>The trafo from local to global system.</param> /// <param name="global2local">A <see cref="M44f"/>The trafofrom global to local system.</param> public static void NormalFrame(V3f origin, V3f normal, out M44f local2global, out M44f global2local ) { V3f min; float x = Fun.Abs(normal.X); float y = Fun.Abs(normal.Y); float z = Fun.Abs(normal.Z); if (x < y) { if (x < z) { min = V3f.XAxis; } else { min = V3f.ZAxis; } } else { if (y < z) { min = V3f.YAxis; } else { min = V3f.ZAxis; } } V3f xVec = Vec.Cross(normal, min); xVec.Normalize(); // this is now guaranteed to be normal to the input normal V3f yVec = Vec.Cross(normal, xVec); yVec.Normalize(); V3f zVec = normal; zVec.Normalize(); local2global = new M44f(xVec.X, yVec.X, zVec.X, origin.X, xVec.Y, yVec.Y, zVec.Y, origin.Y, xVec.Z, yVec.Z, zVec.Z, origin.Z, 0, 0, 0, 1); M44f mat = new M44f(xVec.X, xVec.Y, xVec.Z, 0, yVec.X, yVec.Y, yVec.Z, 0, zVec.X, zVec.Y, zVec.Z, 0, 0, 0, 0, 1); var shift = M44f.Translation(-origin); global2local = mat * shift; }
public static M44f Enlarge(M33f m) { M44f enlarged = new M44f( m.M00, m.M01, m.M02, 0, m.M10, m.M11, m.M12, 0, m.M20, m.M21, m.M22, 0, 0, 0, 0, 1.0f); return(enlarged); }
/// <summary> /// Creates a rigid transformation from a matrix <paramref name="m"/>. /// </summary> public Euclidean3f(M44f m, float epsilon = 1e-5f) : this(((M33f)m) / m.M33, m.C3.XYZ / m.M33, epsilon) { if (!(m.M30.IsTiny(epsilon) && m.M31.IsTiny(epsilon) && m.M32.IsTiny(epsilon))) { throw new ArgumentException("Matrix contains perspective components."); } if (m.M33.IsTiny(epsilon)) { throw new ArgumentException("Matrix is not homogeneous."); } }
/// <summary> /// Computes a Coordiante Frame Transformation (Basis) from current CS into /// the (X, Y, Z)-System at a given Origin. /// Note: you can use it, to transform from RH to LH and vice-versa, all depending /// how you will specifie your new basis-vectors. /// </summary> /// <param name="xVec">New X Vector</param> /// <param name="yVec">New Y Vector</param> /// <param name="zVec">New Z vector</param> /// <param name="oVec">New Origin.</param> /// <param name="viewTrafo"></param> /// <param name="viewTrafoInverse"></param> public static void CoordinateFrameTransform(V3f xVec, V3f yVec, V3f zVec, V3f oVec, out M44f viewTrafo, out M44f viewTrafoInverse) { oVec = -oVec; viewTrafo = new M44f( xVec.X, xVec.Y, xVec.Z, xVec.X * oVec.X + xVec.Y * oVec.Y + xVec.Z * oVec.Z, yVec.X, yVec.Y, yVec.Z, yVec.X * oVec.X + yVec.Y * oVec.Y + yVec.Z * oVec.Z, zVec.X, zVec.Y, zVec.Z, zVec.X * oVec.X + zVec.Y * oVec.Y + zVec.Z * oVec.Z, 0, 0, 0, 1 ); viewTrafoInverse = new M44f( xVec.X, yVec.X, zVec.X, -oVec.X, xVec.Y, yVec.Y, zVec.Y, -oVec.Y, xVec.Z, yVec.Z, zVec.Z, -oVec.Z, 0, 0, 0, 1 ); }
public static M44f Multiply(Rot2f rot, M44f mat) { float a = (float)System.Math.Cos(rot.Angle); float b = (float)System.Math.Sin(rot.Angle); return(new M44f(a * mat.M00 + b * mat.M10, a * mat.M01 + b * mat.M11, a * mat.M02 + b * mat.M12, a * mat.M03 + b * mat.M13, -b * mat.M00 + a * mat.M10, -b * mat.M01 + a * mat.M11, -b * mat.M02 + a * mat.M12, -b * mat.M03 + a * mat.M13, mat.M20, mat.M21, mat.M22, mat.M23, mat.M30, mat.M31, mat.M32, mat.M33)); }
/// <summary> /// Provides perspective projection matrix in terms of the vertical field of view angle a and the aspect ratio r. /// </summary> public static M44f PerspectiveProjectionTransformRH(float a, float r, float n, float f) { //F / r 0 0 0 // 0 F 0 0 // 0 0 A B // 0 0 -1 0 float F = 1 / Fun.Tan(a / 2); float A = f / (n - f); float B = f * n / (n - f); M44f P = new M44f( F / r, 0, 0, 0, 0, F, 0, 0, 0, 0, A, B, 0, 0, -1, 0); return(P); }
/// <summary> /// Provides perspective projection matrix. /// The parameters describe the dimensions of the view volume. /// </summary> public static M44f PerspectiveProjectionTransformRH(V2f size, float n, float f) { float w = size.X; float h = size.Y; // Fx 0 0 0 // 0 Fy 0 0 // 0 0 A B // 0 0 -1 0 float Fx = 2 * n / w; float Fy = 2 * n / h; float A = f / (n - f); float B = n * f / (n - f); M44f P = new M44f( Fx, 0, 0, 0, 0, Fy, 0, 0, 0, 0, A, B, 0, 0, -1, 0); return(P); }
/// <summary> /// Builds a customized, left-handed perspective Off-Center projection matrix. /// </summary> public static M44f PerspectiveProjectionTransformLH(float l, float r, float t, float b, float n, float f) { // Fx 0 0 0 // 0 Fy 0 0 // Sx Sy A 1 // 0 0 B 0 float Fx = 2 * n / (r - l); float Fy = 2 * n / (t - b); float Sx = (l + r) / (l - r); float Sy = (t + b) / (b - t); float A = f / (f - n); float B = n * f / (n - f); M44f P = new M44f( Fx, 0, 0, 0, 0, Fy, 0, 0, Sx, Sy, A, 1, 0, 0, B, 0); return(P); }
/// <summary> /// Builds a customized, right-handed perspective Off-Center projection matrix. /// </summary> public static M44f PerspectiveProjectionTransformRH(float l, float r, float t, float b, float n, float f) { // Fx 0 Sx 0 // 0 Fy Sy 0 // 0 0 A B // 0 0 -1 0 float Fx = 2 * n / (r - l); float Fy = 2 * n / (t - b); float Sx = (l + r) / (r - l); float Sy = (t + b) / (t - b); float A = f / (n - f); float B = n * f / (n - f); M44f P = new M44f( Fx, 0, Sx, 0, 0, Fy, Sy, 0, 0, 0, A, B, 0, 0, -1, 0); return(P); }
/// <summary> /// Multiplacation of a <see cref="Scale3f"/> with a <see cref="M44f"/>. /// </summary> public static M44f Multiply(Scale3f scale, M44f mat) { return(new M44f( scale.X * mat.M00, scale.X * mat.M01, scale.X * mat.M02, scale.X * mat.M03, scale.Y * mat.M10, scale.Y * mat.M11, scale.Y * mat.M12, scale.Y * mat.M13, scale.Z * mat.M20, scale.Z * mat.M21, scale.Z * mat.M22, scale.Z * mat.M23, mat.M30, mat.M31, mat.M32, mat.M33 )); }
/// <summary> /// Multiplacation of a <see cref="Shift3f"/> with a <see cref="M44f"/>. /// </summary> public static M44f Multiply(Shift3f shift, M44f m) { return(new M44f( m.M00 + shift.X * m.M30, m.M01 + shift.X * m.M31, m.M02 + shift.X * m.M32, m.M03 + shift.X * m.M33, m.M10 + shift.Y * m.M30, m.M11 + shift.Y * m.M31, m.M12 + shift.Y * m.M32, m.M13 + shift.Y * m.M33, m.M20 + shift.Z * m.M30, m.M21 + shift.Z * m.M31, m.M22 + shift.Z * m.M32, m.M23 + shift.Z * m.M33, m.M30, m.M31, m.M32, m.M33 )); }
/// <summary> /// Creates a rigid transformation from a matrix <paramref name="m"/>. /// </summary> public Euclidean3f(M44f m, float epsilon = 1e-5f) : this(((M33f)m) / m.M33, m.C3.XYZ / m.M33, epsilon) { Requires.That(m.M30.IsTiny(epsilon) && m.M31.IsTiny(epsilon) && m.M32.IsTiny(epsilon), "Matrix contains perspective components."); Requires.That(!m.M33.IsTiny(epsilon), "Matrix is not homogeneous."); }