Exemple #1
0
        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));
        }
Exemple #2
0
        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));
        }
Exemple #3
0
        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());
        }
Exemple #4
0
        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());
        }