Example #1
0
 public static T Dot <T>(Plane <T> plane, Vector4D <T> value)
     where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T>
 => Scalar.Add(
     Scalar.Add(
         Scalar.Add(Scalar.Multiply(plane.Normal.X, value.X),
                    Scalar.Multiply(plane.Normal.Y, value.Y)), Scalar.Multiply(plane.Normal.Z, value.Z)),
     Scalar.Multiply(plane.Distance, value.W));
Example #2
0
        /// <summary>
        /// Calculates the distance to the nearest edge from the point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <returns>The distance.</returns>
        public T GetDistanceToNearestEdge(Vector2D <T> point)
        {
            var dx = Scalar.Max(Scalar.Max(Scalar.Subtract(Min.X, point.X), Scalar <T> .Zero), Scalar.Subtract(point.X, Max.X));
            var dy = Scalar.Max(Scalar.Max(Scalar.Subtract(Min.Y, point.Y), Scalar <T> .Zero), Scalar.Subtract(point.Y, Max.Y));

            return(Scalar.Sqrt(Scalar.Add(Scalar.Multiply(dx, dx), Scalar.Multiply(dy, dy))));
        }
Example #3
0
        /// <summary>Creates a rotation matrix from the given Quaternion rotation value.</summary>
        /// <param name="quaternion">The source Quaternion.</param>
        /// <returns>The rotation matrix.</returns>
        public static Matrix2X3 <T> CreateFromQuaternion <T>(Quaternion <T> quaternion)
            where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T>
        {
            Matrix2X3 <T> result = Matrix2X3 <T> .Identity;

            T xx = Scalar.Multiply(quaternion.X, quaternion.X);
            T yy = Scalar.Multiply(quaternion.Y, quaternion.Y);
            T zz = Scalar.Multiply(quaternion.Z, quaternion.Z);

            T xy = Scalar.Multiply(quaternion.X, quaternion.Y);
            T wz = Scalar.Multiply(quaternion.Z, quaternion.W);
            T xz = Scalar.Multiply(quaternion.Z, quaternion.X);
            T wy = Scalar.Multiply(quaternion.Y, quaternion.W);
            T yz = Scalar.Multiply(quaternion.Y, quaternion.Z);
            T wx = Scalar.Multiply(quaternion.X, quaternion.W);

            result.M11 = Scalar.Subtract(Scalar <T> .One, Scalar.Multiply(Scalar <T> .Two, Scalar.Add(yy, zz)));
            result.M12 = Scalar.Multiply(Scalar <T> .Two, Scalar.Add(xy, wz));
            result.M13 = Scalar.Multiply(Scalar <T> .Two, Scalar.Subtract(xz, wy));

            result.M21 = Scalar.Multiply(Scalar <T> .Two, Scalar.Subtract(xy, wz));
            result.M22 = Scalar.Subtract(Scalar <T> .One, Scalar.Multiply(Scalar <T> .Two, Scalar.Add(zz, xx)));
            result.M23 = Scalar.Multiply(Scalar <T> .Two, Scalar.Add(yz, wx));

            return(result);
        }
Example #4
0
        /// <summary>
        /// Calculates the distance to the nearest edge from the point.
        /// </summary>
        /// <param name="point">The point.</param>
        /// <returns>The distance.</returns>
        public T GetDistanceToNearestEdge(Vector3D <T> point)
        {
            var max = Max;
            var dx  = Scalar.Max(Scalar.Max(Scalar.Subtract(Origin.X, point.X), Scalar <T> .Zero), Scalar.Subtract(point.X, max.X));
            var dy  = Scalar.Max(Scalar.Max(Scalar.Subtract(Origin.Y, point.Y), Scalar <T> .Zero), Scalar.Subtract(point.Y, max.Y));
            var dz  = Scalar.Max(Scalar.Max(Scalar.Subtract(Origin.Z, point.Z), Scalar <T> .Zero), Scalar.Subtract(point.Z, max.Z));

            return(Scalar.Sqrt(Scalar.Add(Scalar.Add(Scalar.Multiply(dx, dx), Scalar.Multiply(dy, dy)), Scalar.Multiply(dz, dz))));
        }
Example #5
0
        public static Plane <T> Transform <T>(Plane <T> plane, Matrix4X4 <T> matrix)
            where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T>
        {
            Matrix4X4.Invert(matrix, out Matrix4X4 <T> m);

            T x = plane.Normal.X, y = plane.Normal.Y, z = plane.Normal.Z, w = plane.Distance;

            return(new(
                       Scalar.Add(Scalar.Add(Scalar.Add(Scalar.Multiply(x, m.M11), Scalar.Multiply(y, m.M12)), Scalar.Multiply(z, m.M13)), Scalar.Multiply(w, m.M14)),
                       Scalar.Add(Scalar.Add(Scalar.Add(Scalar.Multiply(x, m.M21), Scalar.Multiply(y, m.M22)), Scalar.Multiply(z, m.M23)), Scalar.Multiply(w, m.M24)),
                       Scalar.Add(Scalar.Add(Scalar.Add(Scalar.Multiply(x, m.M31), Scalar.Multiply(y, m.M32)), Scalar.Multiply(z, m.M33)), Scalar.Multiply(w, m.M34)),
                       Scalar.Add(Scalar.Add(Scalar.Add(Scalar.Multiply(x, m.M41), Scalar.Multiply(y, m.M42)), Scalar.Multiply(z, m.M43)), Scalar.Multiply(w, m.M44))));
        }
Example #6
0
        /// <summary>Linearly interpolates between the corresponding values of two matrices.</summary>
        /// <param name="matrix1">The first source matrix.</param>
        /// <param name="matrix2">The second source matrix.</param>
        /// <param name="amount">The relative weight of the second source matrix.</param>
        /// <returns>The interpolated matrix.</returns>
        public static unsafe Matrix2X2<T> Lerp<T>(Matrix2X2<T> matrix1, Matrix2X2<T> matrix2, T amount) where T : unmanaged, IFormattable, IEquatable<T>, IComparable<T>
        {
            Matrix2X2<T> result = default;

            // First row
            result.M11 = Scalar.Add(matrix1.M11, Scalar.Multiply(Scalar.Subtract(matrix2.M11, matrix1.M11), amount));
            result.M12 = Scalar.Add(matrix1.M12, Scalar.Multiply(Scalar.Subtract(matrix2.M12, matrix1.M12), amount));

            // Second row
            result.M21 = Scalar.Add(matrix1.M21, Scalar.Multiply(Scalar.Subtract(matrix2.M21, matrix1.M21), amount));
            result.M22 = Scalar.Add(matrix1.M22, Scalar.Multiply(Scalar.Subtract(matrix2.M22, matrix1.M22), amount));

            return result;
        }
        /// <summary>Creates a matrix that rotates around an arbitrary vector.</summary>
        /// <param name="axis">The axis to rotate around.</param>
        /// <param name="angle">The angle to rotate around the given axis, in radians.</param>
        /// <returns>The rotation matrix.</returns>
        public static Matrix3X3 <T> CreateFromAxisAngle <T>(Vector3D <T> axis, T angle)
            where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T>
        {
            // a: angle
            // x, y, z: unit vector for axis.
            //
            // Rotation matrix M can compute by using below equation.
            //
            //        T               T
            //  M = uu + (cos a)( I-uu ) + (sin a)S
            //
            // Where:
            //
            //  u = ( x, y, z )
            //
            //      [  0 -z  y ]
            //  S = [  z  0 -x ]
            //      [ -y  x  0 ]
            //
            //      [ 1 0 0 ]
            //  I = [ 0 1 0 ]
            //      [ 0 0 1 ]
            //
            //
            //     [  xx+cosa*(1-xx)   yx-cosa*yx-sina*z zx-cosa*xz+sina*y ]
            // M = [ xy-cosa*yx+sina*z    yy+cosa(1-yy)  yz-cosa*yz-sina*x ]
            //     [ zx-cosa*zx-sina*y zy-cosa*zy+sina*x   zz+cosa*(1-zz)  ]
            //
            T x = axis.X, y = axis.Y, z = axis.Z;
            T sa = Scalar.Sin(angle), ca = Scalar.Cos(angle);
            T xx = Scalar.Multiply(x, x), yy = Scalar.Multiply(y, y), zz = Scalar.Multiply(z, z);
            T xy = Scalar.Multiply(x, y), xz = Scalar.Multiply(x, z), yz = Scalar.Multiply(y, z);

            Matrix3X3 <T> result = Matrix3X3 <T> .Identity;

            result.M11 = Scalar.Add(xx, Scalar.Multiply(ca, Scalar.Subtract(Scalar <T> .One, xx)));
            result.M12 = Scalar.Add(Scalar.Subtract(xy, Scalar.Multiply(ca, xy)), Scalar.Multiply(sa, z));
            result.M13 = Scalar.Subtract(Scalar.Subtract(xz, Scalar.Multiply(ca, xz)), Scalar.Multiply(sa, y));

            result.M21 = Scalar.Subtract(Scalar.Subtract(xy, Scalar.Multiply(ca, xy)), Scalar.Multiply(sa, z));
            result.M22 = Scalar.Add(yy, Scalar.Multiply(ca, Scalar.Subtract(Scalar <T> .One, yy)));
            result.M23 = Scalar.Add(Scalar.Subtract(yz, Scalar.Multiply(ca, yz)), Scalar.Multiply(sa, x));

            result.M31 = Scalar.Add(Scalar.Subtract(xz, Scalar.Multiply(ca, xz)), Scalar.Multiply(sa, y));
            result.M32 = Scalar.Subtract(Scalar.Subtract(yz, Scalar.Multiply(ca, yz)), Scalar.Multiply(sa, x));
            result.M33 = Scalar.Add(zz, Scalar.Multiply(ca, Scalar.Subtract(Scalar <T> .One, zz)));

            return(result);
        }
Example #8
0
        public static Plane <T> Transform <T>(Plane <T> plane, Quaternion <T> rotation)
            where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T>
        {
            // Compute rotation matrix.
            T x2 = Scalar.Add(rotation.X, rotation.X);
            T y2 = Scalar.Add(rotation.Y, rotation.Y);
            T z2 = Scalar.Add(rotation.Z, rotation.Z);

            T wx2 = Scalar.Multiply(rotation.W, x2);
            T wy2 = Scalar.Multiply(rotation.W, y2);
            T wz2 = Scalar.Multiply(rotation.W, z2);
            T xx2 = Scalar.Multiply(rotation.X, x2);
            T xy2 = Scalar.Multiply(rotation.X, y2);
            T xz2 = Scalar.Multiply(rotation.X, z2);
            T yy2 = Scalar.Multiply(rotation.Y, y2);
            T yz2 = Scalar.Multiply(rotation.Y, z2);
            T zz2 = Scalar.Multiply(rotation.Z, z2);

            T m11 = Scalar.Subtract(Scalar.Subtract(Scalar <T> .One, yy2), zz2);
            T m21 = Scalar.Subtract(xy2, wz2);
            T m31 = Scalar.Add(xz2, wy2);

            T m12 = Scalar.Add(xy2, wz2);
            T m22 = Scalar.Subtract(Scalar.Subtract(Scalar <T> .One, xx2), zz2);
            T m32 = Scalar.Subtract(yz2, wx2);

            T m13 = Scalar.Subtract(xz2, wy2);
            T m23 = Scalar.Add(yz2, wx2);
            T m33 = Scalar.Subtract(Scalar.Subtract(Scalar <T> .One, xx2), yy2);

            T x = plane.Normal.X, y = plane.Normal.Y, z = plane.Normal.Z;

            return(new(
                       Scalar.Add(Scalar.Add(Scalar.Multiply(x, m11), Scalar.Multiply(y, m21)), Scalar.Multiply(z, m31)),
                       Scalar.Add(Scalar.Add(Scalar.Multiply(x, m12), Scalar.Multiply(y, m22)), Scalar.Multiply(z, m32)),
                       Scalar.Add(Scalar.Add(Scalar.Multiply(x, m13), Scalar.Multiply(y, m23)), Scalar.Multiply(z, m33)),
                       plane.Distance));
        }
Example #9
0
        public static Plane <T> Normalize <T>(Plane <T> value)
            where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T>
        {
            /*if (Vector.IsHardwareAccelerated)
             * {
             *  T normalLengthSquared = value.Normal.LengthSquared();
             *  if (MathF.Abs(normalLengthSquared - 1.0f) < NormalizeEpsilon)
             *  {
             *      // It already normalized, so we don't need to farther process.
             *      return value;
             *  }
             *  T normalLength = MathF.Sqrt(normalLengthSquared);
             *  return new Plane(
             *      value.Normal / normalLength,
             *      value.D / normalLength);
             * }
             * else*/
            {
                T f = Scalar.Add(
                    Scalar.Add(Scalar.Multiply(value.Normal.X, value.Normal.X),
                               Scalar.Multiply(value.Normal.Y, value.Normal.Y)),
                    Scalar.Multiply(value.Normal.Z, value.Normal.Z));

                if (!Scalar.GreaterThanOrEqual(Scalar.Abs(Scalar.Subtract(f, Scalar <T> .One)), Scalar.As <float, T>(NormalizeEpsilon)))
                {
                    return(value); // It already normalized, so we don't need to further process.
                }

                T fInv = Scalar.Reciprocal(Scalar.Sqrt(f));

                return(new(
                           Scalar.Multiply(value.Normal.X, fInv),
                           Scalar.Multiply(value.Normal.Y, fInv),
                           Scalar.Multiply(value.Normal.Z, fInv),
                           Scalar.Multiply(value.Distance, fInv)));
            }
        }
Example #10
0
        /// <summary>Transforms the given matrix by applying the given Quaternion rotation.</summary>
        /// <param name="value">The source matrix to transform.</param>
        /// <param name="rotation">The rotation to apply.</param>
        /// <returns>The transformed matrix.</returns>
        public static Matrix2X3 <T> Transform <T>(Matrix2X3 <T> value, Quaternion <T> rotation)
            where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T>
        {
            // Compute rotation matrix.
            T x2 = Scalar.Add(rotation.X, rotation.X);
            T y2 = Scalar.Add(rotation.Y, rotation.Y);
            T z2 = Scalar.Add(rotation.Z, rotation.Z);

            T wx2 = Scalar.Multiply(rotation.W, x2);
            T wy2 = Scalar.Multiply(rotation.W, y2);
            T wz2 = Scalar.Multiply(rotation.W, z2);
            T xx2 = Scalar.Multiply(rotation.X, x2);
            T xy2 = Scalar.Multiply(rotation.X, y2);
            T xz2 = Scalar.Multiply(rotation.X, z2);
            T yy2 = Scalar.Multiply(rotation.Y, y2);
            T yz2 = Scalar.Multiply(rotation.Y, z2);
            T zz2 = Scalar.Multiply(rotation.Z, z2);

            T q11 = Scalar.Subtract(Scalar.Subtract(Scalar <T> .One, yy2), zz2);
            T q21 = Scalar.Subtract(xy2, wz2);
            T q31 = Scalar.Add(xz2, wy2);

            T q12 = Scalar.Add(xy2, wz2);
            T q22 = Scalar.Subtract(Scalar.Subtract(Scalar <T> .One, xx2), zz2);
            T q32 = Scalar.Subtract(yz2, wx2);

            T q13 = Scalar.Subtract(xz2, wy2);
            T q23 = Scalar.Add(yz2, wx2);
            T q33 = Scalar.Subtract(Scalar.Subtract(Scalar <T> .One, xx2), yy2);

            var q1 = new Vector3D <T>(q11, q12, q13);
            var q2 = new Vector3D <T>(q21, q22, q23);
            var q3 = new Vector3D <T>(q31, q32, q33);

            return(new(value.M11 * q1 + value.M12 * q2 + value.M13 * q3, value.M21 *q1 + value.M22 * q2 + value.M23 * q3));
        }
Example #11
0
        public static Plane <T> CreateFromVertices <T>(Vector3D <T> point1, Vector3D <T> point2, Vector3D <T> point3)
            where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T>
        {
            var a  = point1;
            var b  = point2;
            var c  = point3;
            var ab = b - a;
            var ac = c - a;

            var       cross = Vector3D.Cross(ab, ac);
            Plane <T> p;

            p.Normal   = cross;
            p.Distance = Scalar.Negate(Scalar.Add(
                                           Scalar.Add(Scalar.Multiply(p.Normal.X, a.X), Scalar.Multiply(p.Normal.Y, a.Y)),
                                           Scalar.Multiply(p.Normal.Z, a.Z)));

            return(p);

            /*if (Vector.IsHardwareAccelerated)
             * {
             *  Vector3D<T> a = point2 - point1;
             *  Vector3D<T> b = point3 - point1;
             *
             *  // N = Cross(a, b)
             *  Vector3D<T> n = Vector3D.Cross(a, b);
             *  Vector3D<T> normal = Vector3D.Normalize(n);
             *
             *  // D = - Dot(N, point1)
             *  T d = Scalar.Negate(Vector3D.Dot(normal, point1));
             *
             *  return new Plane<T>(normal, d);
             * }
             * else
             * {
             *  T ax = Scalar.Subtract(point2.X, point1.X);
             *  T ay = Scalar.Subtract(point2.Y, point1.Y);
             *  T az = Scalar.Subtract(point2.Z, point1.Z);
             *
             *  T bx = Scalar.Subtract(point3.X, point1.X);
             *  T by = Scalar.Subtract(point3.Y, point1.Y);
             *  T bz = Scalar.Subtract(point3.Z, point1.Z);
             *
             *  // N=Cross(a,b)
             *  T nx = Scalar.Subtract(Scalar.Multiply(ay, bz), Scalar.Multiply(az, by));
             *  T ny = Scalar.Subtract(Scalar.Multiply(az, bx), Scalar.Multiply(ax, bz));
             *  T nz = Scalar.Subtract(Scalar.Multiply(ax, by), Scalar.Multiply(ay, bx));
             *
             *  // Normalize(N)
             *  T ls = Scalar.Add(Scalar.Add(Scalar.Multiply(nx, nx), Scalar.Multiply(ny, ny)), Scalar.Multiply(nz, nz));
             *  T invNorm = Scalar.Inverse(Scalar.Sqrt(ls));
             *
             *  Vector3D<T> normal = new Vector3D<T>(
             *      Scalar.Multiply(nx, invNorm),
             *      Scalar.Multiply(ny, invNorm),
             *      Scalar.Multiply(nz, invNorm));
             *
             *  return new(normal,
             *      Scalar.Negate(Scalar.Add(
             *          Scalar.Add(Scalar.Multiply(normal.X, point1.X),
             *              Scalar.Multiply(normal.Y, point1.Y)), Scalar.Multiply(normal.Z, point1.Z))));
             * }*/
        }
Example #12
0
 public static T DotCoordinate <T>(Plane <T> plane, Vector3D <T> value)
     where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T>
 => Scalar.Add(Vector3D.Dot(plane.Normal, value), plane.Distance);
Example #13
0
        /// <summary>Creates a rotation matrix using the given rotation in radians and a center point.</summary>
        /// <param name="radians">The amount of rotation, in radians.</param>
        /// <param name="centerPoint">The center point.</param>
        /// <returns>A rotation matrix.</returns>
        public static Matrix3X2 <T> CreateRotation <T>(T radians, Vector2D <T> centerPoint)
            where T : unmanaged, IFormattable, IEquatable <T>, IComparable <T>
        {
            radians = Scalar.IEEERemainder(radians, Scalar <T> .Tau);

            T c, s;

            if (Scalar.GreaterThan(radians, Scalar.As <float, T>(-RotationEpsilon)) && !Scalar.GreaterThanOrEqual(radians, Scalar.As <float, T>(RotationEpsilon)))
            {
                // Exact case for zero rotation.
                c = Scalar <T> .One;
                s = Scalar <T> .Zero;
            }
            else if (Scalar.GreaterThan(radians, Scalar.As <float, T>(
#if MATHF
                                            MathF.PI
#else
                                                ((float)Math.PI)
#endif
                                            / 2 - RotationEpsilon)) && !Scalar.GreaterThanOrEqual(radians, Scalar.As <float, T>(
#if MATHF
                                                                                                      MathF.PI
#else
                                                                                                          ((float)Math.PI)
#endif
                                                                                                      / 2 + RotationEpsilon)))
            {
                // Exact case for 90 degree rotation.
                c = Scalar <T> .Zero;
                s = Scalar <T> .One;
            }
            else if (!Scalar.GreaterThanOrEqual(radians, Scalar.As <float, T>(-
#if MATHF
                                                                              MathF.PI
#else
                                                                                  ((float)Math.PI)
#endif
                                                                              + RotationEpsilon)) || Scalar.GreaterThan(radians, Scalar.As <float, T>(
#if MATHF
                                                                                                                            MathF.PI
#else
                                                                                                                                ((float)Math.PI)
#endif
                                                                                                                            - RotationEpsilon)))
            {
                // Exact case for 180 degree rotation.
                c = Scalar <T> .MinusOne;
                s = Scalar <T> .Zero;
            }
            else if (Scalar.GreaterThan(radians, Scalar.As <float, T>(-
#if MATHF
                                                                      MathF.PI
#else
                                                                          ((float)Math.PI)
#endif
                                                                      / 2 - RotationEpsilon)) && !Scalar.GreaterThanOrEqual(radians, Scalar.As <float, T>(-
#if MATHF
                                                                                                                                                          MathF.PI
#else
                                                                                                                                                              ((float)Math.PI)
#endif
                                                                                                                                                          / 2 + RotationEpsilon)))
            {
                // Exact case for 270 degree rotation.
                c = Scalar <T> .Zero;
                s = Scalar <T> .MinusOne;
            }
            else
            {
                // Arbitrary rotation.
                c = Scalar.Cos(radians);
                s = Scalar.Sin(radians);
            }

            T x = Scalar.Add(Scalar.Multiply(centerPoint.X, Scalar.Subtract(Scalar <T> .One, c)), Scalar.Multiply(centerPoint.Y, s));
            T y = Scalar.Subtract(Scalar.Multiply(centerPoint.Y, Scalar.Subtract(Scalar <T> .One, c)), Scalar.Multiply(centerPoint.X, s));

            // [  c  s ]
            // [ -s  c ]
            // [  x  y ]
            return(new(
                       new(c, s),
                       new(Scalar.Negate(s), c),
                       new(x, y)));
        }