private double[] judge(int width, int height, Color[] pixels, double centerX, double centerY, double[] radii) { //establish state and constants int[] scores = new int[resolution]; Color[] samples = new Color[resolution * 2]; double alpha = System.Math.PI / resolution; double beta = alpha / 2.0; //take samples at each radius foreach (double radius in radii) { for (int i = -resolution; i < resolution; i++) { double theta = beta + alpha * i; double x = centerX + radius * System.Math.Cos(theta); double y = centerY - radius * System.Math.Sin(theta); int coordX = (int)System.Math.Round(x); int coordY = (int)System.Math.Round(y); if (coordX < 0 || coordX >= width || coordY < 0 || coordY >= height) { samples[i + resolution] = backgroundValue; } else { int offset = coordX + width * coordY; Color b = pixels[offset]; samples[i + resolution] = b; } } score(samples, scores); } //identify candidates int benchmark = (int)Mathf.Round(scoreThreshold * 2 * resolution * radii.Count()); List <int> candidates = new List <int>(); for (int i = 0; i < scores.Count(); i++) { int j = i == 0 ? scores.Count() - 1 : i - 1; int k = i == scores.Count() - 1 ? 0 : i + 1; int score = scores[i]; if (score >= benchmark && score >= scores[j] && score >= scores[k]) { candidates.Add(i); } } //merge adjacent angles //TODO address merging of 'wrap-around' adjacent angles OrderedSet <AngularIndex> indices = new OrderedSet <AngularIndex>(); //SortedSet<AngularIndex> indices = new TreeSet<AngularIndex>(); int space = (int)Math.Ceiling(angularAliasing / alpha); int first = -1; int weightedSum = -1; int directSum = -1; int count = -1; foreach (int index in candidates) //for (Iterator<Integer> i = candidates.iterator(); i.hasNext();) { //int index = i.next(); if (first != -1 && index - first < space) { int score = scores[index]; weightedSum += score * index; directSum += score; count += 1; } else { if (first != -1) { AngularIndex angularIndex = new AngularIndex(first, weightedSum / directSum, directSum / count); indices.Add(angularIndex); } first = index; int score = scores[index]; weightedSum = score * index; directSum = score; count = 1; } } if (first != -1) { AngularIndex angularIndex = new AngularIndex(first, weightedSum / directSum, directSum / count); indices.Add(angularIndex); } //convert to radians double[] angles = new double[indices.Count()]; List <AngularIndex> listIndices = indices.ToList(); for (int i = 0; i < angles.Count(); i++) { AngularIndex index = listIndices[i]; angles[i] = beta + alpha * (index.index - resolution); } return(angles); }