/// <summary> /// Attempts to scale up a Polygon until coming within the tolerance percentage of the target area. /// </summary> /// <param name="polygon">Polygon to scale.</param> /// <param name="area">Target area of the Polygon.</param> /// <param name="tolerance">Area total tolerance.</param> /// <param name="origin">Alignment location for final Polygon.</param> /// <param name="within">Polygon acting as a constraining outer boundary.</param> /// <param name="among">List of Polygons to avoid intersecting.</param> /// <returns> /// A new Polygon. /// </returns> public static Polygon ExpandToArea(this Polygon polygon, double area, double ratio, double tolerance = 0.1, Orient origin = Orient.C, Polygon within = null, List <Polygon> among = null) { if (polygon.IsClockWise()) { polygon = polygon.Reversed(); } if (Math.Abs(polygon.Area() - area) <= Math.Abs(tolerance * area)) { return(polygon); } var position = polygon.Compass().PointBy(origin); Polygon tryPoly = Shaper.RectangleByArea(area, ratio); tryPoly = tryPoly.MoveFromTo(tryPoly.Compass().PointBy(origin), position); double tryArea = tryPoly.Area(); do { var t = new Transform(); t.Scale(tryArea / area, tryPoly.Compass().PointBy(origin)); tryPoly = tryPoly.TransformedPolygon(t); if (within != null && tryPoly.Intersects(within)) { var tryPolys = within.Intersection(tryPoly); if (tryPolys != null && tryPolys.Count > 0) { tryPoly = tryPolys.First(); } } if (among != null && tryPoly.Intersects(among)) { var tryPolys = Shaper.Differences(tryPoly.ToList(), among); if (tryPolys != null && tryPolys.Count > 0) { tryPoly = tryPolys.First(); } } tryArea = tryPoly.Area(); }while (!Shaper.NearEqual(tryPoly.Area(), area, tolerance * area) && !Shaper.NearEqual(tryPoly.Area(), tryArea, tolerance)); return(tryPoly); }
/// <summary> /// Creates the largest Polygon fitted to supplied intersecting Polygons. /// </summary> /// <param name="among">List of Polygons against which this Polygon must conform.</param> /// <returns> /// A new Polygon. /// </returns> public static Polygon FitAmong(this Polygon polygon, List <Polygon> among) { if (among == null || among.Count == 0) { return(polygon); } var polygons = Shaper.Differences(polygon.ToList(), among); if (polygons.Count == 0) { return(null); } polygon = polygons.OrderByDescending(p => Math.Abs(p.Area())).First(); if (polygon.IsClockWise()) { return(polygon.Reversed()); } return(polygon); }