/// <summary>
        /// Return the addition: v1 + v2
        /// </summary>
        /// <param name="v1">3d vector</param>
        /// <param name="v2">3d vector</param>
        public static I3dCartesianCoordinates <double> Add(I3dCartesianCoordinates <double> v1, I3dCartesianCoordinates <double> v2)
        {
            var p = new Point3d();

            p.SetCartesian(v1.X + v2.X, v1.Y + v2.Y, v1.Z + v2.Z);
            return(p);
        }
        /// <summary>
        /// Return a vector orthogonal to V
        /// </summary>
        /// <param name="vector">Vector 3d</param>
        /// <param name="normalize">Normalize the orthogonal vector?</param>
        public static I3dCartesianCoordinates <double> Orthogonal(I3dCartesianCoordinates <double> vector, bool normalize = true)
        {
            var O = new Point3d();
            var i = 0;

            if (Math.Abs(vector[1]) < Math.Abs(vector[0]))
            {
                i = 1;
            }
            if (Math.Abs(vector[2]) < Math.Abs(vector[i]))
            {
                i = 2;
            }
            switch (i)
            {
            case 0: O.SetCartesian(0.0, -vector.Z, vector.Y); break;

            case 1: O.SetCartesian(-vector.Z, 0.0, vector.X); break;

            case 2: O.SetCartesian(-vector.Y, vector.X, 0.0); break;

            default: break;
            }
            //Debug.Assert(Core.Algorithm.Mathematics.Near(Vector3d.Angle(V, O).Get(Angle.Unit.deg), 90.0, 1e-6));
            if (normalize)
            {
                return(Normalize(O));
            }
            return(O);
        }
        /// <summary>
        /// Return the cross product: v1 x v2
        /// </summary>
        /// <param name="v1">3d vector</param>
        /// <param name="v2">3d vector</param>
        public static I3dCartesianCoordinates <double> CrossProduct(I3dCartesianCoordinates <double> v1, I3dCartesianCoordinates <double> v2)
        {
            var X = (v1.Y * v2.Z) - (v1.Z * v2.Y);
            var Y = (v1.Z * v2.X) - (v1.X * v2.Z);
            var Z = (v1.X * v2.Y) - (v1.Y * v2.X);

            return(new Point3d(X, Y, Z));
        }
        /// <summary>
        /// Return normalized vector of v multiplied by a scalar
        /// </summary>
        /// <param name="point">Vector</param>
        /// <returns></returns>
        public static I3dCartesianCoordinates <double> Normalize(I3dCartesianCoordinates <double> point, double scalar = 1.0)
        {
            var norm = Norm(point);

            if (norm > 0)
            {
                return(new Point3d(scalar * point.X / norm, scalar * point.Y / norm, scalar * point.Z / norm));
            }
            else
            {
                return(new Point3d());
            }
        }
 public static I3dCartesianCoordinates <double> Multiply(I3dCartesianCoordinates <double> vector, double scalar) => Multiply(scalar, vector);
 /// <summary>
 /// Mutiply scalar to Vector
 /// </summary>
 /// <param name="scalar">scalar</param>
 /// <param name="vector">Vector</param>
 /// <returns></returns>
 public static I3dCartesianCoordinates <double> Multiply(double scalar, I3dCartesianCoordinates <double> vector)
 {
     return(new Point3d(scalar * vector.X, scalar * vector.Y, scalar * vector.Z));
 }
 public void SetCartesian(I3dCartesianCoordinates <double> p)
 {
     X = p.X; Y = p.Y; Z = p.Z;
 }
 public Point3d(I3dCartesianCoordinates <double> coordinates)
 {
     SetCartesian(coordinates);
 }