private static Tuple <double, Point[]> GetPercentCovered(Point[] polygon, Rect rect) { // Figure out the intersected polygon Point[] intersection = Math2D.GetIntersection_Polygon_Polygon( polygon, new Point[] { rect.TopLeft, rect.TopRight, rect.BottomRight, rect.BottomLeft }); if (intersection == null || intersection.Length == 0) { return(null); } // Calculate the area of the polygon double areaPolygon = Math2D.GetAreaPolygon(intersection); double areaRect = rect.Width * rect.Height; if (areaPolygon > areaRect) { if (areaPolygon > areaRect * 1.01) { throw new ApplicationException(string.Format("Area of intersected polygon is larger than the rectangle that clipped it: polygon={0}, rectangle={1}", areaPolygon.ToString(), areaRect.ToString())); } areaPolygon = areaRect; } return(Tuple.Create(areaPolygon / areaRect, intersection)); }
private static Point[] ResizeConvexPolygon(Point[] polygon, double newArea) { Point center = Math2D.GetCenter(polygon); // Create a delagate that returns the area of the polygon based on the percent size Func <double, double> getOutput = new Func <double, double>(o => { Point[] polyPoints = GetPolygon(center, polygon, o); return(Math2D.GetAreaPolygon(polyPoints)); }); // Find a percent that returns the desired area double percent = Math1D.GetInputForDesiredOutput_PosInput_PosCorrelation(newArea, newArea * .01, getOutput); // Return the sized polygon return(GetPolygon(center, polygon, percent)); }
private static double[] AnalyzeVoronoiCellSizes(VoronoiResult2D voronoi, ISOMInput[][] imagesByNode) { // Calculate area, density of each node var sizes = Enumerable.Range(0, voronoi.ControlPoints.Length). Select(o => { double area = Math2D.GetAreaPolygon(voronoi.GetPolygon(o, 1)); // there are no rays double imageCount = imagesByNode[o].Length.ToDouble(); return(new { ImagesCount = imageCount, Area = area, Density = imageCount / area, }); }). ToArray(); // Don't let any node have an area smaller than this double minArea = sizes.Min(o => o.Area) * .2; // Find the node with the largest density. This is the density to use when drawing all cells var largestDensity = sizes. OrderByDescending(o => o.Density). First(); return(sizes.Select(o => { // Figure out how much area it would take using the highest density double area = o.ImagesCount / largestDensity.Density; if (area < minArea) { area = minArea; } return area; }). ToArray()); }
private static OverlayResult[] IntersectTiles(Point[] polygon, Tuple <Rect, int, int>[] tiles) { List <OverlayResult> retVal = new List <OverlayResult>(); #region Get polygon AABB double minX = double.MaxValue; double minY = double.MaxValue; double maxX = double.MinValue; double maxY = double.MinValue; for (int cntr = 0; cntr < polygon.Length; cntr++) { if (polygon[cntr].X < minX) { minX = polygon[cntr].X; } if (polygon[cntr].X > maxX) { maxX = polygon[cntr].X; } if (polygon[cntr].Y < minY) { minY = polygon[cntr].Y; } if (polygon[cntr].Y > maxY) { maxY = polygon[cntr].Y; } } #endregion foreach (var tile in tiles) { // AABB check if (tile.Item1.Left > maxX) { continue; // polygon is left of the rectangle } else if (tile.Item1.Right < minX) { continue; // polygon is right of the rectangle } else if (tile.Item1.Top > maxY) { continue; // polygon is above rectangle } else if (tile.Item1.Bottom < minY) { continue; // polygon is below rectangle } // See if the polygon is completely inside the rectangle if (minX >= tile.Item1.Left && maxX <= tile.Item1.Right && minY >= tile.Item1.Top && maxY <= tile.Item1.Bottom) { double areaPoly = Math2D.GetAreaPolygon(polygon); double areaRect = tile.Item1.Width * tile.Item1.Height; if (areaPoly > areaRect) { throw new ApplicationException(string.Format("Area of contained polygon is larger than the rectangle that contains it: polygon={0}, rectangle={1}", areaPoly.ToString(), areaRect.ToString())); } retVal.Add(new OverlayResult(tile.Item2, tile.Item3, areaPoly / areaRect)); continue; } // Intersect polygon with rect var percent = GetPercentCovered(polygon, tile.Item1); if (percent != null) { retVal.Add(new OverlayResult(tile.Item2, tile.Item3, percent.Item1)); } } return(retVal.ToArray()); }