static MyPoint[] CalculateConvexPolygon(MyPoint[] points) { Array.Sort(points); int numPoints = points.Length; MyPoint[] result = new MyPoint[numPoints * 2]; int currentIndex = 0; int minIndex = 2; for (int i = 0; i < numPoints; i++) { while (currentIndex >= minIndex) { MyPoint p1 = MyPoint.Sub(result[currentIndex - 1], result[currentIndex - 2]); MyPoint p2 = MyPoint.Sub(points[i], result[currentIndex - 2]); if (MyPoint.Cross(p1, p2) <= 0) { currentIndex--; } else { break; } } result[currentIndex++] = points[i]; } minIndex = currentIndex + 1; for (int i = numPoints - 2; i >= 0; i--) { while (currentIndex >= minIndex) { MyPoint p1 = MyPoint.Sub(result[currentIndex - 1], result[currentIndex - 2]); MyPoint p2 = MyPoint.Sub(points[i], result[currentIndex - 2]); if (MyPoint.Cross(p1, p2) <= 0) { currentIndex--; } else { break; } } result[currentIndex++] = points[i]; } Array.Resize <MyPoint>(ref result, currentIndex - 1); return(result); }
private void UpdateRectangles(bool createNewRectangles) { if (fRectangles == null || createNewRectangles) { fRectangles = MyFactory.GetRandomRectangles(); fAngle = 0; } else { foreach (var rectangle in fRectangles) { rectangle.Angle = fAngle; } } int numberOfPoints = 4 * fRectangles.Count; MyPoint[] points = new MyPoint[numberOfPoints]; int pointIndex = 0; foreach (var rectangle in fRectangles) { var corners = rectangle.CalculateCorners(); points[pointIndex++] = corners[0]; points[pointIndex++] = corners[1]; points[pointIndex++] = corners[2]; points[pointIndex++] = corners[3]; } var polygon = CalculateConvexPolygon(points); if (fLines == null) { fLines = new DynamicPrimitiveLine(fSpriteBatch.GraphicsDevice); fLines.UseVertexBuffer = false; } else { fLines.Clear(); } double boardArea = 0; foreach (var rectangle in fRectangles) { var corners = rectangle.CalculateCorners(); fLines.AddLine(ToVertexPositionColor(corners[0], Color.White), ToVertexPositionColor(corners[1], Color.White)); fLines.AddLine(ToVertexPositionColor(corners[1], Color.White), ToVertexPositionColor(corners[2], Color.White)); fLines.AddLine(ToVertexPositionColor(corners[2], Color.White), ToVertexPositionColor(corners[3], Color.White)); fLines.AddLine(ToVertexPositionColor(corners[3], Color.White), ToVertexPositionColor(corners[0], Color.White)); boardArea += rectangle.Width * rectangle.Height; } double polyArea = 0; int numberOfPolyLines = polygon.Length; for (int i = 0; i < numberOfPolyLines; i++) { int j = (i + 1) % numberOfPolyLines; MyPoint p1 = polygon[i]; MyPoint p2 = polygon[j]; polyArea += MyPoint.Cross(p1, p2); fLines.AddLine(ToVertexPositionColor(p1, Color.Red), ToVertexPositionColor(p2, Color.Red)); } polyArea = polyArea / 2; double ratio = 100.0 * boardArea / polyArea; //System.Console.WriteLine($"Area: {polyArea} PolyPoints: {numberOfPolyLines}, Ratio: {ratio:F1} %"); }