/// <summary>
        /// Transforms a point list between coordinate systems.
        /// </summary>
        /// <param name="points">Points to transform.</param>
        /// <param name="zAxis">Object normal vector.</param>
        /// <param name="from">Points coordinate system.</param>
        /// <param name="to">Coordinate system of the transformed points.</param>
        /// <returns>Transormed point list.</returns>
        public static List <Vector3> Transform(List <Vector3> points, Vector3 zAxis, CoordinateSystem from, CoordinateSystem to)
        {
            if (zAxis.Equals(Vector3.UnitZ))
            {
                return(points);
            }

            Matrix3        trans = ArbitraryAxis(zAxis);
            List <Vector3> transPoints;

            if (from == CoordinateSystem.World && to == CoordinateSystem.Object)
            {
                transPoints = new List <Vector3>();
                trans       = trans.Traspose();
                foreach (Vector3 p in points)
                {
                    transPoints.Add(trans * p);
                }
                return(transPoints);
            }
            if (from == CoordinateSystem.Object && to == CoordinateSystem.World)
            {
                transPoints = new List <Vector3>();
                foreach (Vector3 p in points)
                {
                    transPoints.Add(trans * p);
                }
                return(transPoints);
            }
            return(points);
        }
        /// <summary>
        /// Transforms a point between coordinate systems.
        /// </summary>
        /// <param name="point">Point to transform.</param>
        /// <param name="zAxis">Object normal vector.</param>
        /// <param name="from">Point coordinate system.</param>
        /// <param name="to">Coordinate system of the transformed point.</param>
        /// <returns>Transormed point.</returns>
        public static Vector3 Transform(Vector3 point, Vector3 zAxis, CoordinateSystem from, CoordinateSystem to)
        {
            Matrix3 trans = ArbitraryAxis(zAxis);

            if (from == CoordinateSystem.World && to == CoordinateSystem.Object)
            {
                trans = trans.Traspose();
                return(trans * point);
            }
            if (from == CoordinateSystem.Object && to == CoordinateSystem.World)
            {
                return(trans * point);
            }
            return(point);
        }
        /// <summary>
        /// Transforms a point between coordinate systems.
        /// </summary>
        /// <param name="point">Point to transform.</param>
        /// <param name="zAxis">Object normal vector.</param>
        /// <param name="from">Point coordinate system.</param>
        /// <param name="to">Coordinate system of the transformed point.</param>
        /// <returns>Transormed point.</returns>
        public static Vector3 Transform(Vector3 point, Vector3 zAxis, CoordinateSystem from, CoordinateSystem to)
        {
            // if the normal is (0,0,1) no transformation is needed the transformation matrix is the identity
            if (zAxis.Equals(Vector3.UnitZ))
            {
                return(point);
            }

            Matrix3 trans = ArbitraryAxis(zAxis);

            if (from == CoordinateSystem.World && to == CoordinateSystem.Object)
            {
                trans = trans.Traspose();
                return(trans * point);
            }
            if (from == CoordinateSystem.Object && to == CoordinateSystem.World)
            {
                return(trans * point);
            }
            return(point);
        }
        /// <summary>
        /// Transforms a point list between coordinate systems.
        /// </summary>
        /// <param name="points">Points to transform.</param>
        /// <param name="zAxis">Object normal vector.</param>
        /// <param name="from">Points coordinate system.</param>
        /// <param name="to">Coordinate system of the transformed points.</param>
        /// <returns>Transformed point list.</returns>
        public static IList <Vector3> Transform(IEnumerable <Vector3> points, Vector3 zAxis, CoordinateSystem from, CoordinateSystem to)
        {
            if (points == null)
            {
                throw new ArgumentNullException(nameof(points));
            }

            if (zAxis.Equals(Vector3.UnitZ))
            {
                return(new List <Vector3>(points));
            }

            Matrix3        trans = ArbitraryAxis(zAxis);
            List <Vector3> transPoints;

            if (from == CoordinateSystem.World && to == CoordinateSystem.Object)
            {
                transPoints = new List <Vector3>();
                trans       = trans.Traspose();
                foreach (Vector3 p in points)
                {
                    transPoints.Add(trans * p);
                }
                return(transPoints);
            }
            if (from == CoordinateSystem.Object && to == CoordinateSystem.World)
            {
                transPoints = new List <Vector3>();
                foreach (Vector3 p in points)
                {
                    transPoints.Add(trans * p);
                }
                return(transPoints);
            }
            return(new List <Vector3>(points));
        }