/// <inheritdoc/> protected override Matrix44F ComputeProjection() { var projection = Matrix44F.CreatePerspectiveOffCenter(Left, Right, Bottom, Top, Near, Far); if (_nearClipPlane.HasValue) { Vector4F clipPlane = new Vector4F(_nearClipPlane.Value.Normal, -_nearClipPlane.Value.DistanceFromOrigin); // Calculate the clip-space corner point opposite the clipping plane as // (-sign(clipPlane.x), -sign(clipPlane.y), 1, 1) and transform it into // camera space by multiplying it by the inverse of the projection matrix. Vector4F q; q.X = (-Math.Sign(clipPlane.X) + projection.M02) / projection.M00; q.Y = (-Math.Sign(clipPlane.Y) + projection.M12) / projection.M11; q.Z = -1.0f; q.W = (1.0f + projection.M22) / projection.M23; // Calculate the scaled plane vector Vector4F c = clipPlane * (1.0f / Vector4F.Dot(clipPlane, q)); // Replace the third row of the projection matrix projection.M20 = c.X; projection.M21 = c.Y; projection.M22 = c.Z; projection.M23 = c.W; } return(projection); }
public void DotProduct() { // 0° Assert.AreEqual(1.0f, Vector4F.Dot(Vector4F.UnitX, Vector4F.UnitX)); Assert.AreEqual(1.0f, Vector4F.Dot(Vector4F.UnitY, Vector4F.UnitY)); Assert.AreEqual(1.0f, Vector4F.Dot(Vector4F.UnitZ, Vector4F.UnitZ)); Assert.AreEqual(1.0f, Vector4F.Dot(Vector4F.UnitW, Vector4F.UnitW)); // 180° Assert.AreEqual(-1.0f, Vector4F.Dot(Vector4F.UnitX, -Vector4F.UnitX)); Assert.AreEqual(-1.0f, Vector4F.Dot(Vector4F.UnitY, -Vector4F.UnitY)); Assert.AreEqual(-1.0f, Vector4F.Dot(Vector4F.UnitZ, -Vector4F.UnitZ)); Assert.AreEqual(-1.0f, Vector4F.Dot(Vector4F.UnitW, -Vector4F.UnitW)); // 90° Assert.AreEqual(0.0f, Vector4F.Dot(Vector4F.UnitX, Vector4F.UnitY)); Assert.AreEqual(0.0f, Vector4F.Dot(Vector4F.UnitY, Vector4F.UnitZ)); Assert.AreEqual(0.0f, Vector4F.Dot(Vector4F.UnitZ, Vector4F.UnitW)); Assert.AreEqual(0.0f, Vector4F.Dot(Vector4F.UnitW, Vector4F.UnitX)); // 45° float angle = (float)Math.Acos(Vector4F.Dot(new Vector4F(1, 1, 0, 0).Normalized, Vector4F.UnitX)); Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(45), angle)); angle = (float)Math.Acos(Vector4F.Dot(new Vector4F(0, 1, 1, 0).Normalized, Vector4F.UnitY)); Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(45), angle)); angle = (float)Math.Acos(Vector4F.Dot(new Vector4F(1, 0, 1, 0).Normalized, Vector4F.UnitZ)); Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(45), angle)); angle = (float)Math.Acos(Vector4F.Dot(new Vector4F(1, 0, 0, 1).Normalized, Vector4F.UnitW)); Assert.IsTrue(Numeric.AreEqual(MathHelper.ToRadians(45), angle)); }
/// <summary> /// Determines whether the specified matrix is a valid pose matrix. /// </summary> /// <param name="matrix">The matrix.</param> /// <returns> /// <see langword="true"/> if the specified matrix is a valid pose matrix; otherwise, /// <see langword="false"/>. /// </returns> /// <remarks> /// This method makes a simple, low-performance test. /// </remarks> public static bool IsValid(Matrix44F matrix) { Vector4F v1 = matrix * Vector4F.UnitX; Vector4F v2 = matrix * Vector4F.UnitY; Vector4F v3 = matrix * Vector4F.UnitZ; return(Numeric.AreEqual(v1.LengthSquared, 1) && Numeric.AreEqual(v2.LengthSquared, 1) && Numeric.AreEqual(v3.LengthSquared, 1) && Numeric.IsZero(Vector4F.Dot(v1, v2)) && Numeric.IsZero(Vector4F.Dot(v2, v3)) && Numeric.IsZero(Vector4F.Dot(v1, v3)) && Numeric.AreEqual(1.0f, matrix.Determinant) && Numeric.IsZero(matrix.M30) && Numeric.IsZero(matrix.M31) && Numeric.IsZero(matrix.M32) && Numeric.AreEqual(matrix.M33, 1)); }
public void Dot() { Vector4F a = new Vector4F(1.0f, 2.0f, 3.0f, 4.0f); Vector4F b = new Vector4F(4.0f, 5.0f, 6.0f, 7.0f); double dot = a.Dot(b); Assert.AreEqual(1.0f * 4.0f + 2.0f * 5.0f + 3.0f * 6.0f + 4.0f * 7.0f, dot, 1e-14); }