public void DivideShape(Random rand, int shapeToDivide, int shapeToSacrifice)
{
Shape original = Shapes[shapeToDivide];
int points = original.Points.Length;
// Figure out which dividing vertex produces the shortest dividing edge.
PointF divisionVertex1 = default(PointF);
PointF divisionVertex2 = default(PointF);
double shortestDividingEdgeLength = Double.MaxValue;
Shape shifted = original;
for (int shiftAmount = 0; shiftAmount < points; shiftAmount++) {
Shape shiftedGuess = ShiftPoints(original, shiftAmount);
// Find the two dividing vertices
PointF vertexGuess1;
if (points%2 == 1) {
// odd number of points
vertexGuess1 = shiftedGuess.Points[points/2];
} else {
// even number of points
vertexGuess1 = Lerp(shiftedGuess.Points[points/2 - 1], shiftedGuess.Points[points/2], 0.5f);
}
PointF vertexGuess2 = Lerp(shiftedGuess.Points[0], shiftedGuess.Points[points - 1], 0.5f);
double dividingEdgeLength =
Math.Sqrt((vertexGuess1.X - vertexGuess2.X)*(vertexGuess1.X - vertexGuess2.X) +
(vertexGuess1.Y - vertexGuess2.Y)*(vertexGuess1.Y - vertexGuess2.Y));
if (dividingEdgeLength < shortestDividingEdgeLength) {
shortestDividingEdgeLength = dividingEdgeLength;
shifted = shiftedGuess;
divisionVertex1 = vertexGuess1;
divisionVertex2 = vertexGuess2;
}
}
var half1 = new Shape(shifted);
var half2 = new Shape(shifted);
// Construct half-shape #1
half1.Points[0] = divisionVertex1;
half1.Points[1] = divisionVertex2;
for (int i = 0; i < points/2; i++) {
half1.Points[i + 2] = shifted.Points[i];
}
// Construct half-shape #2
half2.Points[0] = divisionVertex2;
half2.Points[1] = divisionVertex1;
for (int i = 0; i < points/2; i++) {
half2.Points[i + 2] = shifted.Points[points/2 + i + 1];
}
// Randomly redistribute extra vertices for each half (if there are any)
int extraVertices = (points - 3)/2;
Subdivide(rand, half1, extraVertices);
Subdivide(rand, half2, extraVertices);
// Write back the changes
Shapes[shapeToDivide] = half1;
Shapes[shapeToSacrifice] = half2;
half1.OutlineColor = Color.Green;
half2.OutlineColor = Color.Red;
ShiftShapeIndex(shapeToSacrifice, shapeToDivide);
}