/// <summary> /// Creates a translation matrix. /// </summary> public static Matrix Translation(EVector vec) { return(new Matrix(new EVector(1, 0, 0), new EVector(0, 1, 0), new EVector(0, 0, 1), vec)); }
/// <summary> /// Creates a possibly non-uniform scaling matrix. /// </summary> public static Matrix Scaling(EVector scale) { return(new Matrix(new EVector(scale.X, 0, 0), new EVector(0, scale.Y, 0), new EVector(0, 0, scale.Z), EVector.Zero)); }
/// <summary> /// Constructs a matrix from four column vectors. /// </summary> private Matrix(EVector u, EVector v, EVector w, EVector t) { this.u = u; this.v = v; this.w = w; this.t = t; }
private static Tuple <Ray, float> RayFromVertices(Point3f a, Point3f b) { EPoint pt = new EPoint(a.X, a.Y, a.Z); EVector vec = new EVector(b.X - a.X, b.Y - a.Y, b.Z - a.Z); Ray ray = new Ray(pt, vec); float mag = EVector.Length(vec); return(new Tuple <Ray, float>(ray, mag)); }
/// <summary> /// Returns the azimuth of a vector. /// </summary> /// <remarks> /// Horizontal angle, zero towards the z-axis. /// </remarks> public static float Azimuth(EVector u) { var len = Length(u); if (len > 0) { return((float)Math.Atan2(u.Z, u.X)); } else { throw new InvalidOperationException("Vector has no direction"); } }
/// <summary> /// Returns the inclination of a vector. /// </summary> /// <remarks> /// Vertical angle, zero on the xz-plane. /// </remarks> public static float Inclination(EVector u) { var len = Length(u); if (len > 0) { return((float)(Math.Acos(u.Y / len) - Math.PI / 2)); } else { throw new InvalidOperationException("Vector has no direction"); } }
/// <summary> /// Normalizes a vector to unit length. /// </summary> public static EVector Normalize(EVector u) { var len = Length(u); if (len > 0) { return(u / len); } else { throw new InvalidOperationException("Vector has no direction"); } }
/// <summary> /// Returns the inverse of a matrix. /// </summary> public static Matrix Invert(Matrix mat) { // Work out determinant of the 3x3 submatrix. var det = mat.U.X * (mat.V.Y * mat.W.Z - mat.W.Y * mat.V.Z) - mat.V.X * (mat.W.Z * mat.U.Y - mat.W.Y * mat.U.Z) + mat.W.X * (mat.U.Y * mat.V.Z - mat.V.Y * mat.U.Z); if (Math.Abs(det) < 0) { throw new ArgumentException("Matrix is not invertible"); } // Compute inv(submatrix) = transpose(submatrix) / det. var inv_u = new EVector(mat.U.X, mat.V.X, mat.W.X) / det; var inv_v = new EVector(mat.U.Y, mat.V.Y, mat.W.Y) / det; var inv_w = new EVector(mat.U.Z, mat.V.Z, mat.W.Z) / det; // Transform the translation column by this inverse matrix. var inv_t = -(mat.T.X * inv_u + mat.T.Y * inv_v + mat.T.Z * inv_w); return(new Matrix(inv_u, inv_v, inv_w, inv_t)); }
/// <summary> /// Constructs a ray with an origin and a direction. /// </summary> public Ray(EPoint origin, EVector direction) { this.origin = origin; this.direction = direction.Normalize(); }
/// <summary> /// Converts a vector into a point. /// </summary> /// <remarks> /// This is meaningless mathematically. /// </remarks> public static EPoint ToPoint(EVector u) { return(EPoint.Zero + u); }
/// <summary> /// Returns the cross product of this vector with another. /// </summary> public EVector Cross(EVector v) { return(Cross(this, v)); }
/// <summary> /// Transforms a vector by this matrix. /// </summary> public EVector Transform(EVector vec) { return(Transform(this, vec)); }
/// <summary> /// Returns the cross product of two vectors. /// </summary> public static EVector Cross(EVector u, EVector v) { return(new EVector(u.Y * v.Z - u.Z * v.Y, u.Z * v.X - u.X * v.Z, u.X * v.Y - u.Y * v.X)); }
/// <summary> /// Returns the dot product of two vectors. /// </summary> public static float Dot(EVector u, EVector v) { return(u.X * v.X + u.Y * v.Y + u.Z * v.Z); }
/// <summary> /// Returns the length of a vector. /// </summary> public static float Length(EVector u) { return((float)Math.Sqrt(Dot(u, u))); }
/// <summary> /// Reflects a vector about a normal. /// </summary> public static EVector Reflect(EVector i, EVector n) { return(i - 2 * n * Dot(i, n)); }
/// <summary> /// Transforms a vector by a matrix. /// </summary> public static EVector Transform(Matrix mat, EVector vec) { return(vec.X * mat.U + vec.Y * mat.V + vec.Z * mat.W); }
/// <summary> /// Reflects this vector about a normal. /// </summary> public EVector Reflect(EVector n) { return(Reflect(this, n)); }
/// <summary> /// Returns the dot product of this vector with another. /// </summary> public float Dot(EVector v) { return(Dot(this, v)); }
/// <summary> /// Corrects an Embree.NET normal, which is unnormalized /// and in object space, to a world space normal vector. /// </summary> public EVector CorrectNormal(EVector normal) { return((inverseTranspose * normal).Normalize()); }