public static double[,] AddIntersectionsY(double[,] structure, double[] yCut) { double m; double xNew; double[,] finalContours = structure; for (int y = 0; y < yCut.Length; y++) { double[,] contours = finalContours; int numConts = finalContours.Length / 3; int numAdded = 1; //start at one, increment after adding each point, to keep track of where to add next additional point (add to index) //index 0 outside of loop: if ((contours[0, 1] > yCut[y]) & (contours[contours.Length / 3 - 1, 1] < yCut[y])) { m = (contours[0, 1] - contours[contours.Length / 3 - 1, 1]) / (contours[0, 0] - contours[contours.Length / 3 - 1, 0]); xNew = ((yCut[y] - contours[contours.Length / 3 - 1, 1]) / m) + contours[contours.Length / 3 - 1, 0]; finalContours = ContourFixing.AddPoint(finalContours, 0, new double[] { xNew, yCut[y], contours[0, 2] }); numAdded++; } if ((contours[0, 1] < yCut[y]) & (contours[contours.Length / 3 - 1, 1] > yCut[y])) { m = (contours[contours.Length / 3 - 1, 1] - contours[0, 1]) / (contours[contours.Length / 3 - 1, 0] - contours[0, 0]); xNew = ((yCut[y] - contours[0, 1]) / m) + contours[0, 0]; finalContours = ContourFixing.AddPoint(finalContours, contours.Length / 3, new double[] { xNew, yCut[y], contours[0, 2] }); } for (int i = 1; i < numConts - 1; i++) //for all points, except last one will be out of loop { if ((contours[i, 1] < yCut[y]) & (contours[i + 1, 1] > yCut[y])) //if y is below the cut { m = (contours[i + 1, 1] - contours[i, 1]) / (contours[i + 1, 0] - contours[i, 0]); xNew = ((yCut[y] - contours[i, 1]) / m) + contours[i, 0]; finalContours = ContourFixing.AddPoint(finalContours, i + numAdded, new double[] { xNew, yCut[y], contours[0, 2] }); numAdded++; } else if ((contours[i, 1] > yCut[y]) & (contours[i + 1, 1] < yCut[y])) { m = (contours[i + 1, 1] - contours[i, 1]) / (contours[i + 1, 0] - contours[i, 0]); xNew = ((yCut[y] - contours[i, 1]) / m) + contours[i, 0]; finalContours = ContourFixing.AddPoint(finalContours, i + numAdded, new double[] { xNew, yCut[y], contours[0, 2] }); numAdded++; } } } return(finalContours); }
public static double[,] AddIntersectionsX(double[,] contours, double xCut) { double m; double yNew; double[,] finalContours = contours; int numAdded = 1; //start at one, increment after adding each point, to keep track of where to add next additional point (add to index) //index 0 outside of loop: if ((contours[0, 0] > xCut) & (contours[contours.Length / 3 - 1, 0] < xCut)) { m = (contours[0, 0] - contours[contours.Length / 3 - 1, 0]) / (contours[0, 1] - contours[contours.Length / 3 - 1, 1]); yNew = ((xCut - contours[contours.Length / 3 - 1, 0]) / m) + contours[contours.Length / 3 - 1, 1]; finalContours = ContourFixing.AddPoint(finalContours, 0, new double[] { xCut, yNew, contours[0, 2] }); numAdded++; } if ((contours[0, 0] < xCut) & (contours[contours.Length / 3 - 1, 0] > xCut)) { m = (contours[contours.Length / 3 - 1, 0] - contours[0, 0]) / (contours[contours.Length / 3 - 1, 1] - contours[0, 1]); yNew = ((xCut - contours[0, 0]) / m) + contours[0, 1]; finalContours = ContourFixing.AddPoint(finalContours, contours.Length / 3, new double[] { xCut, yNew, contours[0, 2] }); } for (int i = 0; i < contours.Length / 3 - 1; i++) //for all points, except last one will be out of loop { if ((contours[i, 0] < xCut) & (contours[i + 1, 0] > xCut)) //if x is below the cut { m = (contours[i + 1, 0] - contours[i, 0]) / (contours[i + 1, 1] - contours[i, 1]); yNew = ((xCut - contours[i, 0]) / m) + contours[i, 1]; finalContours = ContourFixing.AddPoint(finalContours, i + numAdded, new double[] { xCut, yNew, contours[0, 2] }); numAdded++; } else if ((contours[i, 0] > xCut) & (contours[i + 1, 0] < xCut)) { m = (contours[i + 1, 0] - contours[i, 0]) / (contours[i + 1, 1] - contours[i, 1]); yNew = ((xCut - contours[i, 0]) / m) + contours[i, 1]; finalContours = ContourFixing.AddPoint(finalContours, i + numAdded, new double[] { xCut, yNew, contours[0, 2] }); numAdded++; } } return(finalContours); }
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); }
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); }