Esempio n. 1
0
        public static double[] BestCutY(List <double[, ]> contours, int numCuts, double errorTolerance)
        {
            double[] yCuts = new double[numCuts];
            double   area = 0;
            double   maxY = -1000;
            double   minY = 1000;
            double   error, yCut, newArea;

            //Get the total area of contours:
            for (int i = 0; i < contours.Count; i++)
            {
                if (contours[i].Length != 0)
                {
                    area += Geom.Geometry.Area(contours[i]);
                }
            }
            for (int cut = 0; cut < numCuts; cut++)
            {
                double areaGoal = (double)(cut + 1) / (numCuts + 1); // fractional area goal for each cut.
                //Now get the max and min Y for the structure
                for (int j = 0; j < contours.Count; j++)
                {
                    if (contours[j].Length != 0)
                    {
                        for (int row = 0; row < contours[j].Length / 3; row++)
                        //get the maximum, minimum y
                        {
                            if (contours[j][row, 1] > maxY)
                            {
                                maxY = contours[j][row, 1];
                            }
                            if (contours[j][row, 1] < minY)
                            {
                                minY = contours[j][row, 1];
                            }
                        }
                    }
                }
                //Now iteratively get equal volumes to the error allowance set
                List <double[, ]> tempContours = new List <double[, ]>();
                List <double[]>   cutContours  = new List <double[]>(); //store contour as a list to append easily.
                do
                {
                    tempContours.Clear();
                    yCut    = (minY + maxY) / 2;
                    newArea = 0;
                    //First add the intersection points:
                    for (int i = 0; i < contours.Count; i++)
                    {
                        cutContours.Clear();
                        if (contours[i].Length != 0)
                        {
                            tempContours.Add(AddIntersectionsY(contours[i], yCut));
                            tempContours[i] = ContourFixing.ClosedLooper(tempContours[i]);
                            //now make a new contour with points below yCut.
                            for (int j = 0; j < tempContours[i].Length / 3; j++)
                            {
                                if (tempContours[i][j, 1] <= yCut)
                                {
                                    cutContours.Add(new double[] { tempContours[i][j, 0], tempContours[i][j, 1], tempContours[i][j, 2] });
                                }
                            }
                            if (cutContours.Count != 0)
                            {
                                cutContours = ContourFixing.ClosedLooper(cutContours);
                                newArea    += Geom.Geometry.Area(cutContours);
                            }
                        }
                    }
                    //Now compare areas:
                    if (newArea / area < areaGoal)
                    {
                        minY = yCut;
                    }
                    else if (newArea / area > areaGoal)
                    {
                        maxY = yCut;
                    }
                    error = Math.Abs((newArea / area) - areaGoal);
                } while (error > errorTolerance);

                yCuts[cut] = yCut;
            }
            return(yCuts);
        }
Esempio n. 2
0
        public static List <List <double[, ]> > YChop(List <double[, ]> contours, int numCutsY)
        {
            double[] yCuts = BestCutY(contours, numCutsY, 0.0001);        //Contains y-values for cut locations

            // add intersection points
            for (int i = 0; i < contours.Count; i++)
            {
                contours[i] = AddIntersectionsY(contours[i], yCuts);
                contours[i] = ContourFixing.ClosedLooper(contours[i]);
            }

            //////////////////////////////////////
            //Now divide into separate parts.
            ///////////////////////////////////////
            List <List <double[, ]> > finalContours = new List <List <double[, ]> >();
            //make a list for each y division for the current contour.
            List <List <double[]> > divisions = new List <List <double[]> >();

            //Make the list the correct size so that there is an item for each y division.
            for (int div = 0; div <= yCuts.Length; div++)
            {
                finalContours.Add(new List <double[, ]>());
            }


            for (int i = 0; i < contours.Count; i++)        //for all of the contours
            {
                divisions.Clear();
                //Make the list the correct size so that there is an item for each y division.
                for (int div = 0; div <= yCuts.Length; div++)
                {
                    divisions.Add(new List <double[]>());
                }
                for (int y = 0; y <= yCuts.Length; y++)              //a section for every cut, + 1
                {
                    for (int j = 0; j < contours[i].Length / 3; j++) //loop through all points
                    {
                        if (y == 0)
                        {
                            if (contours[i][j, 1] <= yCuts[y])
                            {
                                divisions[y].Add(new double[] { contours[i][j, 0], contours[i][j, 1], contours[i][j, 2] });
                            }
                        }
                        else if (y == yCuts.Length)
                        {
                            if (contours[i][j, 1] >= yCuts[y - 1])
                            {
                                divisions[y].Add(new double[] { contours[i][j, 0], contours[i][j, 1], contours[i][j, 2] });
                            }
                        }
                        else
                        {
                            if ((contours[i][j, 1] >= yCuts[y - 1]) && (contours[i][j, 1] <= yCuts[y]))
                            {
                                divisions[y].Add(new double[] { contours[i][j, 0], contours[i][j, 1], contours[i][j, 2] });
                            }
                        }
                    }
                }
                //at this point divisions has a list item holding a list of array points for each cut.
                //Need to now make double arrays for each of these and add them to new final list.
                double[,] temp;
                for (int y = 0; y <= yCuts.Length; y++)     //a section for every cut, + 1
                {
                    temp = new double[divisions[y].Count, 3];
                    for (int row = 0; row < temp.Length / 3; row++)
                    {
                        temp[row, 0] = divisions[y][row][0];
                        temp[row, 1] = divisions[y][row][1];
                        temp[row, 2] = divisions[y][row][2];
                    }

                    if (temp.Length != 0)
                    {
                        temp = ContourFixing.ClosedLooper(temp);
                        finalContours[y].Add(temp);
                    }
                }
            }

            return(finalContours);
        }