public static Double VectorMagnitude(MemorySafe_CartVect vector)
        {
            double magnitude = 0.0;

            magnitude = Math.Sqrt(Math.Pow((vector.X), 2) + Math.Pow((vector.Y), 2) + Math.Pow((vector.Z), 2));
            return(magnitude);
        }
 public static MemorySafe_CartVect CreateMemorySafe_Vector(CartCoord cd1, CartCoord cd2)
 {
     double X = cd2.X - cd1.X;
     double Y = cd2.Y - cd1.Y;
     double Z = cd2.Z - cd1.Z;
     MemorySafe_CartVect vector = new MemorySafe_CartVect(X, Y, Z);
     return vector;
 }
        public static MemorySafe_CartVect CreateMemorySafe_Vector(CartCoord cd1, CartCoord cd2)
        {
            double X = cd2.X - cd1.X;
            double Y = cd2.Y - cd1.Y;
            double Z = cd2.Z - cd1.Z;
            MemorySafe_CartVect vector = new MemorySafe_CartVect(X, Y, Z);

            return(vector);
        }
        public static MemorySafe_CartVect CrossProduct(MemorySafe_CartVect vector1, MemorySafe_CartVect vector2)
        {
            double xProdX             = vector2.Z * vector1.Y - vector1.Z * vector2.Y;
            double xProdY             = -1 * (vector2.Z * vector1.X - vector1.Z * vector2.X);
            double xProdZ             = vector2.Y * vector1.X - vector1.Y * vector2.X;
            MemorySafe_CartVect xProd = new MemorySafe_CartVect(xProdX, xProdY, xProdZ);

            return(xProd);
        }
        public static MemorySafe_CartVect UnitVector(MemorySafe_CartVect vector)
        {
            double magnitude       = VectorMagnitude(vector);
            double X               = vector.X / magnitude;
            double Y               = vector.Y / magnitude;
            double Z               = vector.Z / magnitude;
            MemorySafe_CartVect UV = new MemorySafe_CartVect(X, Y, Z);

            return(UV);
        }
        public static CartVect CrossProductNVRetMSNV(MemorySafe_CartVect vector1, CartVect vector2)
        {
            double   xProdX = vector2.Z * vector1.Y - vector1.Z * vector2.Y;
            double   xProdY = -1 * (vector2.Z * vector1.X - vector1.Z * vector2.X);
            double   xProdZ = vector2.Y * vector1.X - vector1.Y * vector2.X;
            CartVect xProd  = new CartVect(xProdX, xProdY, xProdZ);

            xProd.X = xProdX;
            xProd.Y = xProdY;
            xProd.Z = xProdZ;
            return(xProd);
        }
        public static MemorySafe_CartVect GetRHR(List <MemorySafe_CartCoord> plCoords)
        {
            CartVect plRHRVect = new CartVect();
            //this list will store all of the rhr values returned by any arbitrary polyloop
            List <MemorySafe_CartVect> RHRs = new List <MemorySafe_CartVect>();

            int coordCount = plCoords.Count;

            for (int i = 0; i < coordCount - 2; i++)
            {
                MemorySafe_CartVect v1 = CreateMemorySafe_Vector(plCoords[i], plCoords[i + 1]);
                MemorySafe_CartVect v2 = CreateMemorySafe_Vector(plCoords[i + 1], plCoords[i + 2]);
                MemorySafe_CartVect uv = UnitVector(CrossProduct(v1, v2));
                RHRs.Add(uv);
            }
            int RHRVectorCount = RHRs.Count;
            List <MemorySafe_CartVect> distinctRHRs = new List <MemorySafe_CartVect>();
            int parallelCount     = 0;
            int antiParallelCount = 0;

            //the Distinct().ToList() routine did not work because, we believe, the item in the list is not recognized by Distinct()
            //distinctRHRs = RHRs.Distinct().ToList();
            //so we took the following approach to try and find unique vectors and store them
            distinctRHRs.Add(RHRs[0]);
            List <int> uniqueIndices = new List <int>();

            for (int j = 1; j < RHRVectorCount; j++)
            {
                if (RHRs[j].X == distinctRHRs[0].X * -1 && RHRs[j].Y == distinctRHRs[0].Y * -1 && RHRs[j].Z == distinctRHRs[0].Z * -1)
                {
                    //means that the vectors are not facing in the same direction
                    antiParallelCount++;
                }
                else
                {
                    parallelCount++;
                }
            }

            if (antiParallelCount > parallelCount)
            {
                double X = distinctRHRs[0].X * -1;
                double Y = distinctRHRs[0].Y * -1;
                double Z = distinctRHRs[0].Z * -1;
                MemorySafe_CartVect antiParallel = new MemorySafe_CartVect(X, Y, Z);
                return(antiParallel);
            }
            else
            {
                return(distinctRHRs[0]);
            }
        }
 public static MemorySafe_CartVect convertToMemorySafeVector(CartVect vector)
 {
     MemorySafe_CartVect memVect = new MemorySafe_CartVect(vector.X, vector.Y, vector.Z);
     return memVect;
 }
        public static Double VectorMagnitude(MemorySafe_CartVect vector)
        {
            double magnitude = 0.0;

            magnitude = Math.Sqrt(Math.Pow((vector.X), 2) + Math.Pow((vector.Y), 2) + Math.Pow((vector.Z), 2));
            return magnitude;
        }
 public static MemorySafe_CartVect UnitVector(MemorySafe_CartVect vector)
 {
     double magnitude = VectorMagnitude(vector);
     double X = vector.X / magnitude;
     double Y = vector.Y / magnitude;
     double Z = vector.Z / magnitude;
     MemorySafe_CartVect UV = new MemorySafe_CartVect(X, Y, Z);
     return UV;
 }
        public static MemorySafe_CartVect GetRHR(List<MemorySafe_CartCoord> plCoords)
        {
            CartVect plRHRVect = new CartVect();
            //this list will store all of the rhr values returned by any arbitrary polyloop
            List<MemorySafe_CartVect> RHRs = new List<MemorySafe_CartVect>();

            int coordCount = plCoords.Count;
            for (int i = 0; i < coordCount - 2; i++)
            {
                MemorySafe_CartVect v1 = CreateMemorySafe_Vector(plCoords[i], plCoords[i + 1]);
                MemorySafe_CartVect v2 = CreateMemorySafe_Vector(plCoords[i + 1], plCoords[i + 2]);
                MemorySafe_CartVect uv = UnitVector(CrossProduct(v1, v2));
                RHRs.Add(uv);
            }
            int RHRVectorCount = RHRs.Count;
            List<MemorySafe_CartVect> distinctRHRs = new List<MemorySafe_CartVect>();
            int parallelCount = 0;
            int antiParallelCount = 0;
            //the Distinct().ToList() routine did not work because, we believe, the item in the list is not recognized by Distinct()
            //distinctRHRs = RHRs.Distinct().ToList();
            //so we took the following approach to try and find unique vectors and store them
            distinctRHRs.Add(RHRs[0]);
            List<int> uniqueIndices = new List<int>();
            for (int j = 1; j < RHRVectorCount; j++)
            {

                if (RHRs[j].X == distinctRHRs[0].X * -1 && RHRs[j].Y == distinctRHRs[0].Y * -1 && RHRs[j].Z == distinctRHRs[0].Z * -1)
                {
                    //means that the vectors are not facing in the same direction
                    antiParallelCount++;
                }
                else
                {
                    parallelCount++;
                }

            }

            if (antiParallelCount > parallelCount)
            {
                double X = distinctRHRs[0].X * -1;
                double Y = distinctRHRs[0].Y * -1;
                double Z = distinctRHRs[0].Z * -1;
                MemorySafe_CartVect antiParallel = new MemorySafe_CartVect(X, Y, Z);
                return antiParallel;
            }
            else
            {
                return distinctRHRs[0];
            }
        }
        public static double GetAreaofSurface(MemorySafe_Surface surface)
        {
            //Used to figure out how best to calculate the area from a given surfacce.
            //Get the coordinates that define the surface
            //get the area based on the coordinates

            //Get the RHRVector (the actual direction is not important
            MemorySafe_CartVect RHRVector = GetRHR(surface.SurfaceCoords);

            //now that I have this, I can move on

            //there are two basic cases for calculating the area that we cover here,
            //one where we get the area using greens theorem when the surface is parallel to one of the axes of the project global reference frame
            //and the second where the surface is not parallel to one of the axes of the global reference frame

            //Surface normal Parallel to global reference frame X Axis
            if (Math.Abs(RHRVector.X) == 1 && RHRVector.Y == 0 && RHRVector.Z == 0)
            {
                List<MemorySafe_CartCoord> coordList = new List<MemorySafe_CartCoord>();
                for (int i = 0; i < surface.SurfaceCoords.Count; i++)
                {
                    //only take the Y and Z coordinates and throw out the X because we can assume that they are all the same
                    double X = 0;
                    double Y = surface.SurfaceCoords[i].Y;
                    double Z = surface.SurfaceCoords[i].Z;
                    MemorySafe_CartCoord coord = new MemorySafe_CartCoord(X, Y, Z);
                    coordList.Add(coord);

                }
                double area = GetAreaFrom2DPolyLoop(coordList);
                return area;

            }
            //Surface normal Parallel to global reference frame y Axis
            else if (RHRVector.X == 0 && Math.Abs(RHRVector.Y) == 1 && RHRVector.Z == 0)
            {
                List<MemorySafe_CartCoord> coordList = new List<MemorySafe_CartCoord>();
                for (int i = 0; i < surface.SurfaceCoords.Count; i++)
                {
                    //only take the X and Z coordinates and throw out the Y because we can assume that they are all the same
                    double X = surface.SurfaceCoords[i].X;
                    double Y = 0;
                    double Z = surface.SurfaceCoords[i].Z;
                    MemorySafe_CartCoord coord = new MemorySafe_CartCoord(X, Y, Z);
                    coordList.Add(coord);

                }
                double area = GetAreaFrom2DPolyLoop(coordList);
                return area;
            }
            else if (RHRVector.X == 0 && RHRVector.Y == 0 && Math.Abs(RHRVector.Z) == 1)
            {
                List<MemorySafe_CartCoord> coordList = new List<MemorySafe_CartCoord>();
                for (int i = 0; i < surface.SurfaceCoords.Count; i++)
                {
                    //only take the X and Y coordinates and throw out the Z because we can assume that they are all the same
                    double X = surface.SurfaceCoords[i].X;
                    double Y = surface.SurfaceCoords[i].Y;
                    double Z = 0;
                    MemorySafe_CartCoord coord = new MemorySafe_CartCoord(X, Y, Z);
                    coordList.Add(coord);
                }
                double area = GetAreaFrom2DPolyLoop(coordList);
                return area;
            }

            //the surface is not aligned with one of the reference frame axes, which requires a bit more work to determine the right answer.
            else
            {

                //New Z Axis for this plane is the normal vector already calculated, does not need to be created
                //Get New Y Axis which is the surface Normal Vector cross the original global reference X unit vector (all unit vectors please
                double X = 1;
                double Y = 0;
                double Z = 0;
                MemorySafe_CartVect globalReferenceX = new MemorySafe_CartVect(X, Y, Z);

                MemorySafe_CartVect localY = CrossProduct(RHRVector, globalReferenceX);
                localY = UnitVector(localY);

                //new X axis is the localY cross the surface normal vector
                MemorySafe_CartVect localX = CrossProduct(localY, RHRVector);
                localX = UnitVector(localX);

                //convert the polyloop coordinates to a local 2-D reference frame
                //using a trick employed by video game programmers found here http://stackoverflow.com/questions/1023948/rotate-normal-vector-onto-axis-plane
                List<MemorySafe_CartCoord> translatedCoordinates = new List<MemorySafe_CartCoord>();
                //put the origin in place in these translated coordinates since our loop skips over this first arbitrary point
                double originX = 0;
                double originY = 0;
                double originZ = 0;
                MemorySafe_CartCoord newOrigin = new MemorySafe_CartCoord(originX, originY, originZ);
                translatedCoordinates.Add(newOrigin);
                for (int j = 1; j < surface.SurfaceCoords.Count; j++)
                {
                    //randomly assigns the first polyLoop coordinate as the origin
                    MemorySafe_CartCoord origin = surface.SurfaceCoords[0];
                    //captures the components of a vector drawn from the new origin to the
                    double xDistance = surface.SurfaceCoords[j].X - origin.X;
                    double yDist = surface.SurfaceCoords[j].Y - origin.Y;
                    double zDist = surface.SurfaceCoords[j].Z - origin.Z;
                    MemorySafe_CartVect distance = new MemorySafe_CartVect(xDistance, yDist, zDist);
                    double translPtX = distance.X * localX.X + distance.Y * localX.Y + distance.Z * localX.Z;
                    double translPtY = distance.X * localY.X + distance.Y * localY.Y + distance.Z * localY.Z;
                    double translPtZ = 0;
                    MemorySafe_CartCoord translatedPt = new MemorySafe_CartCoord(translPtX, translPtY, translPtZ);
                    translatedCoordinates.Add(translatedPt);

                }
                double area = GetAreaFrom2DPolyLoop(translatedCoordinates);
                return area;
            }
        }
 public static CartVect CrossProductNVRetMSNV(MemorySafe_CartVect vector1, CartVect vector2)
 {
     double xProdX = vector2.Z * vector1.Y - vector1.Z * vector2.Y;
     double xProdY = -1 * (vector2.Z * vector1.X - vector1.Z * vector2.X);
     double xProdZ = vector2.Y * vector1.X - vector1.Y * vector2.X;
     CartVect xProd = new CartVect(xProdX, xProdY, xProdZ);
     xProd.X = xProdX;
     xProd.Y = xProdY;
     xProd.Z = xProdZ;
     return xProd;
 }
 public static MemorySafe_CartVect CrossProduct(MemorySafe_CartVect vector1, MemorySafe_CartVect vector2)
 {
     double xProdX = vector2.Z * vector1.Y - vector1.Z * vector2.Y;
     double xProdY = -1 * (vector2.Z * vector1.X - vector1.Z * vector2.X);
     double xProdZ = vector2.Y * vector1.X - vector1.Y * vector2.X;
     MemorySafe_CartVect xProd = new MemorySafe_CartVect(xProdX, xProdY, xProdZ);
     return xProd;
 }
        public static double GetAreaofSurface(MemorySafe_Surface surface)
        {
            //Used to figure out how best to calculate the area from a given surfacce.
            //Get the coordinates that define the surface
            //get the area based on the coordinates

            //Get the RHRVector (the actual direction is not important
            MemorySafe_CartVect RHRVector = GetRHR(surface.SurfaceCoords);

            //now that I have this, I can move on

            //there are two basic cases for calculating the area that we cover here,
            //one where we get the area using greens theorem when the surface is parallel to one of the axes of the project global reference frame
            //and the second where the surface is not parallel to one of the axes of the global reference frame

            //Surface normal Parallel to global reference frame X Axis
            if (Math.Abs(RHRVector.X) == 1 && RHRVector.Y == 0 && RHRVector.Z == 0)
            {
                List <MemorySafe_CartCoord> coordList = new List <MemorySafe_CartCoord>();
                for (int i = 0; i < surface.SurfaceCoords.Count; i++)
                {
                    //only take the Y and Z coordinates and throw out the X because we can assume that they are all the same
                    double X = 0;
                    double Y = surface.SurfaceCoords[i].Y;
                    double Z = surface.SurfaceCoords[i].Z;
                    MemorySafe_CartCoord coord = new MemorySafe_CartCoord(X, Y, Z);
                    coordList.Add(coord);
                }
                double area = GetAreaFrom2DPolyLoop(coordList);
                return(area);
            }
            //Surface normal Parallel to global reference frame y Axis
            else if (RHRVector.X == 0 && Math.Abs(RHRVector.Y) == 1 && RHRVector.Z == 0)
            {
                List <MemorySafe_CartCoord> coordList = new List <MemorySafe_CartCoord>();
                for (int i = 0; i < surface.SurfaceCoords.Count; i++)
                {
                    //only take the X and Z coordinates and throw out the Y because we can assume that they are all the same
                    double X = surface.SurfaceCoords[i].X;
                    double Y = 0;
                    double Z = surface.SurfaceCoords[i].Z;
                    MemorySafe_CartCoord coord = new MemorySafe_CartCoord(X, Y, Z);
                    coordList.Add(coord);
                }
                double area = GetAreaFrom2DPolyLoop(coordList);
                return(area);
            }
            else if (RHRVector.X == 0 && RHRVector.Y == 0 && Math.Abs(RHRVector.Z) == 1)
            {
                List <MemorySafe_CartCoord> coordList = new List <MemorySafe_CartCoord>();
                for (int i = 0; i < surface.SurfaceCoords.Count; i++)
                {
                    //only take the X and Y coordinates and throw out the Z because we can assume that they are all the same
                    double X = surface.SurfaceCoords[i].X;
                    double Y = surface.SurfaceCoords[i].Y;
                    double Z = 0;
                    MemorySafe_CartCoord coord = new MemorySafe_CartCoord(X, Y, Z);
                    coordList.Add(coord);
                }
                double area = GetAreaFrom2DPolyLoop(coordList);
                return(area);
            }

            //the surface is not aligned with one of the reference frame axes, which requires a bit more work to determine the right answer.
            else
            {
                //New Z Axis for this plane is the normal vector already calculated, does not need to be created
                //Get New Y Axis which is the surface Normal Vector cross the original global reference X unit vector (all unit vectors please
                double X = 1;
                double Y = 0;
                double Z = 0;
                MemorySafe_CartVect globalReferenceX = new MemorySafe_CartVect(X, Y, Z);

                MemorySafe_CartVect localY = CrossProduct(RHRVector, globalReferenceX);
                localY = UnitVector(localY);

                //new X axis is the localY cross the surface normal vector
                MemorySafe_CartVect localX = CrossProduct(localY, RHRVector);
                localX = UnitVector(localX);

                //convert the polyloop coordinates to a local 2-D reference frame
                //using a trick employed by video game programmers found here http://stackoverflow.com/questions/1023948/rotate-normal-vector-onto-axis-plane
                List <MemorySafe_CartCoord> translatedCoordinates = new List <MemorySafe_CartCoord>();
                //put the origin in place in these translated coordinates since our loop skips over this first arbitrary point
                double originX = 0;
                double originY = 0;
                double originZ = 0;
                MemorySafe_CartCoord newOrigin = new MemorySafe_CartCoord(originX, originY, originZ);
                translatedCoordinates.Add(newOrigin);
                for (int j = 1; j < surface.SurfaceCoords.Count; j++)
                {
                    //randomly assigns the first polyLoop coordinate as the origin
                    MemorySafe_CartCoord origin = surface.SurfaceCoords[0];
                    //captures the components of a vector drawn from the new origin to the
                    double xDistance                  = surface.SurfaceCoords[j].X - origin.X;
                    double yDist                      = surface.SurfaceCoords[j].Y - origin.Y;
                    double zDist                      = surface.SurfaceCoords[j].Z - origin.Z;
                    MemorySafe_CartVect distance      = new MemorySafe_CartVect(xDistance, yDist, zDist);
                    double translPtX                  = distance.X * localX.X + distance.Y * localX.Y + distance.Z * localX.Z;
                    double translPtY                  = distance.X * localY.X + distance.Y * localY.Y + distance.Z * localY.Z;
                    double translPtZ                  = 0;
                    MemorySafe_CartCoord translatedPt = new MemorySafe_CartCoord(translPtX, translPtY, translPtZ);
                    translatedCoordinates.Add(translatedPt);
                }
                double area = GetAreaFrom2DPolyLoop(translatedCoordinates);
                return(area);
            }
        }
        public static MemorySafe_CartVect convertToMemorySafeVector(CartVect vector)
        {
            MemorySafe_CartVect memVect = new MemorySafe_CartVect(vector.X, vector.Y, vector.Z);

            return(memVect);
        }