/// <summary>
 /// Returns the angle between two NetronVectors
 /// </summary>
 /// <param name="v1">a vector</param>
 /// <param name="v2">a vector</param>
 /// <returns></returns>
 public static double Angle(NetronVector v1, NetronVector v2)
 {
     if ((v1.Length() > 0) && (v2.Length() > 0))
     {
         return(Math.Acos(v1.DotProduct(v2) / (v1.Length() * v2.Length())));
     }
     else
     {
         return(0);
     }
 }
 /// <summary>
 /// Return whether another vector is equal to this one
 /// </summary>
 /// <param name="v">a NetronVector vector</param>
 /// <returns>true if the two are component-wise equal, otherwise false</returns>
 public bool IsEqual(NetronVector v)
 {
     if (this.mX != v.X)
     {
         return(false);
     }
     if (this.mY != v.Y)
     {
         return(false);
     }
     if (this.mZ != v.Z)
     {
         return(false);
     }
     return(true);
 }
        /// <summary>
        /// Rotates the vector
        /// </summary>
        /// <param name="phi">the angle around the x-axis</param>
        /// <param name="theta">the angle around the y-axis</param>
        /// <param name="psi">the angle around the z-axis</param>
        public void RotateEquals(double phi, double theta, double psi)
        {
            NetronVector t = new NetronVector();                 // Temporary variables for holding old values
            double       sX = Math.Sin(phi), cX = Math.Cos(phi), //to avoid reduntant calculations.
                         sY = Math.Sin(theta), cY = Math.Cos(theta),
                         sZ = Math.Sin(psi), cZ = Math.Cos(psi);

            t.mY = mY * cX - mZ * sX;         //rotate around the mX-axis
            t.mZ = mY * sX + mZ * cX;
            mY   = t.mY;                      //update vars needed in algorithm
            mZ   = t.mZ;

            t.mX = mX * cY - mZ * sY;         //rotate around the mY-axis
            t.mZ = mX * sY + mZ * cY;
            mX   = t.mX;                      //update vars needed in algorithm again
            mZ   = t.mZ;

            t.mX = mX * cZ - mY * sZ;         //rotate around the mZ-axis
            t.mY = mX * sZ + mY * cZ;
            mX   = t.mX;                      //update vars for final storage
            mY   = t.mY;
            mZ   = t.mZ;
        }
        /// <summary>
        /// Rotates a 3D point along the origin of its coordinate system
        /// </summary>
        /// <param name="phi">the angle around the x-axis</param>
        /// <param name="theta">the angle around the y-axis</param>
        /// <param name="psi">the angle around the z-axis</param>
        /// <returns></returns>
        public NetronVector Rotate(double phi, double theta, double psi)
        {                                                        //Euler angles
            NetronVector t = new NetronVector();                 // Temporary variables for holding old values
            double       sX = Math.Sin(phi), cX = Math.Cos(phi), //to avoid reduntant calculations.
                         sY = Math.Sin(theta), cY = Math.Cos(theta),
                         sZ = Math.Sin(psi), cZ = Math.Cos(psi);
            NetronVector tmp = new NetronVector(this);

            t.mY   = tmp.mY * cX - tmp.mZ * sX;   //rotate around the mX-axis
            t.mZ   = tmp.mY * sX + tmp.mZ * cX;
            tmp.mY = t.mY;                        //update vars needed in algorithm
            tmp.mZ = t.mZ;

            t.mX   = tmp.mX * cY - tmp.mZ * sY;   //rotate around the mY-axis
            t.mZ   = tmp.mX * sY + tmp.mZ * cY;
            tmp.mX = t.mX;                        //update vars needed in algorithm again
            tmp.mZ = t.mZ;

            t.mX   = tmp.mX * cZ - tmp.mY * sZ;   //rotate around the mZ-axis
            t.mY   = tmp.mX * sZ + tmp.mY * cZ;
            tmp.mX = t.mX;                        //update vars for final storage
            tmp.mY = t.mY;
            return(t);
        }
 /// <summary>
 /// Constructor; based on another NetronVector
 /// </summary>
 /// <param name="v">a vector</param>
 public NetronVector(NetronVector v)
 {
     mX = v.mX; mY = v.mY; mZ = v.mZ;
 }
 /// <summary>
 /// Returns the distance to the given vector
 /// </summary>
 /// <param name="v">a vector</param>
 /// <returns>the distance to the given vector</returns>
 public double Distance(NetronVector v)
 {
     return(Math.Sqrt((mX - v.X) * (mX - v.X) + (mY - v.Y) * (mY - v.Y) + (mZ - v.Z) * (mZ - v.Z)));
 }
 /// <summary>
 /// The vector product and sets the result equal to this vector
 /// </summary>
 /// <param name="v">a vector</param>
 public void CrossProductEquals(NetronVector v)
 {
     this.SetTo(new NetronVector(this.mY * v.mZ - v.mY * this.mZ, this.mZ * v.mX - v.mZ * this.mX, this.mX * v.mY - v.mX * this.mY));
 }
 /// <summary>
 /// Sets this vector to the project of the original onto the given vector
 /// </summary>
 /// <param name="v">the vector onto which this vector is projected</param>
 public void ProjectionEquals(NetronVector v)
 {
     this.SetTo(v.Multiply((this.DotProduct(v)) / (v.DotProduct(v))));
 }
 /// <summary>
 /// The vector product with another vector
 /// </summary>
 /// <param name="v">the second vector of the product</param>
 /// <returns>the resulting vector</returns>
 public NetronVector CrossProduct(NetronVector v)
 {
     return(new NetronVector(this.mY * v.mZ - v.mY * this.mZ, this.mZ * v.mX - v.mZ * this.mX, this.mX * v.mY - v.mX * this.mY));
 }
 /// <summary>
 /// Scalar product of this vector with another
 /// </summary>
 /// <param name="v">the second vector to make the scalar product with</param>
 /// <returns>the result of the scalar product</returns>
 public double DotProduct(NetronVector v)
 {
     return(mX * v.mX + mY * v.mY + mZ * v.mZ);
 }
 /// <summary>
 /// Returns the projection of this vector on the given one
 /// </summary>
 /// <param name="v">the vector onto which this vector is projected</param>
 /// <returns>the resulting vector</returns>
 public NetronVector Projection(NetronVector v)
 {
     return(v.Multiply((this.DotProduct(v)) / (v.DotProduct(v))));
 }
 /// <summary>
 /// Sets the coordinates of this vector to those of the given one
 /// </summary>
 /// <param name="v">a vector</param>
 public void SetTo(NetronVector v)
 {
     mX = v.mX; mY = v.mY; mZ = v.mZ;
 }
 /// <summary>
 /// Substract the vector with the given one
 /// </summary>
 /// <param name="v">a vector</param>
 public void SubstractEquals(NetronVector v)
 {
     mX -= v.mX; mY -= v.mY; mZ -= v.mZ;
 }
 /// <summary>
 /// Substract the vector with the given one
 /// </summary>
 /// <param name="v">a vector</param>
 /// <returns>the result of the vector operation</returns>
 public NetronVector Substract(NetronVector v)
 {
     return(new NetronVector(mX - v.mX, mY - v.mY, mZ - v.mZ));
 }
 /// <summary>
 /// Adds a vector to the current one
 /// </summary>
 /// <param name="v">a vector</param>
 public void AddEquals(NetronVector v)
 {
     mX += v.mX; mY += v.mY; mZ += v.mZ;
 }
 /// <summary>
 /// Returns the addition of the vector with the given one
 /// </summary>
 /// <param name="v">a vector</param>
 /// <returns></returns>
 public NetronVector Add(NetronVector v)
 {
     return(new NetronVector(mX + v.mX, mY + v.mY, mZ + v.mZ));
 }