internal static new double ApproxFit(ImageSection ImgSec) { //double Fit = 0d; //return Fit; //Just return circle from top to bottom, left to right return ImgSec.PixelsUsed().Length / (ImgSec.Width / 2 * ImgSec.Height / 2 * Math.PI); }
/// <summary> /// /// </summary> /// <param name="ImgSec"></param> /// <returns></returns> internal static new double ApproxFit(ImageSection ImgSec) { return ImgSec.PixelsUsed().Length / Area(GenerateCorners(ImgSec).ToArray()); }
/// <summary> /// /// </summary> /// <param name="ImgSec"></param> /// <returns></returns> private static List<Point> GenerateCorners(ImageSection ImgSec) { //Find all points that are clear on at least two sides of any other selected pixels List<Point> Outsides; { Point[] Pts = ImgSec.PixelsUsed(); Outsides = new List<Point>(); foreach (Point p in Pts) { int Bordering = 0; foreach (Point q in Pts) { //It only counts as bordering if they are adjacent, not diagonal if (Math.Abs(p.X - q.X) == 1 ^ Math.Abs(p.Y - q.Y) == 1) Bordering++; if (Bordering > 3) break; } if (Bordering <= 3) Outsides.Add(p); } } List<Point> Corners = new List<Point>(); //Order points around the shape in a roughly circular shape //This solution also ensure that the resulting shape is convex //I'll take a scan approach //Pick a point that you know is on the outside, so any one with min or max x or y //I'm going to find min y, then min x for that //Then do a scan using that and (-1,-1) to find the point with the SMALLEST angle //Guaranteed, those two points are part of the convex containing polygon //Using those two points, scan around //Scan every other point and its angle with the current two //The point with the greatest angle is the next convex vertex //Continue until you reach the original point { Point a, b = new Point(-1, -1), c = new Point(-1, -1); double angle = Math.PI, temp; //int MinY = Outsides.Min(p => p.Y); //MinY = 0; a = new Point(Outsides.Min(p => (p.Y == 0 ? p.X : ImgSec.Width)), 0); foreach (Point p in Outsides) { if (!p.Equals(a)) if ((temp = GetAngle(new Point(-1, -1), a, p)) < angle) { b = p; angle = temp; } } Corners.Add(a); Corners.Add(b); do { angle = 0d; foreach (Point q in Outsides) if (!Corners.Contains(q)) if ((temp = GetAngle(Corners[Corners.Count - 2], Corners[Corners.Count - 1], q)) > angle) { c = q; angle = temp; } if (Corners.Contains(c)) break; else Corners.Add(c); } while (Corners.Count < Outsides.Count); } return Corners; }