using o0; using System; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; namespace ZIM { internal class PixelCircleArea { public Vector2 Center; public float MaxRadius; public HashSet Pixels; HashSet<(int, int)> grids; public PixelCircleArea(Vector2 location) { Center = location; Pixels = new HashSet { location }; MaxRadius = 0; grids = new HashSet<(int, int)>(); Add(location); } public PixelCircleArea(IList areas) { Center = Vector2.zero; Pixels = new HashSet(); MaxRadius = 0; grids = new HashSet<(int, int)>(); foreach (var a in areas) { Pixels.AddRange(a.Pixels); grids.AddRange(a.grids); } foreach (var p in Pixels) { Center += p; } Center /= Pixels.Count; foreach (var p in Pixels) { var radius = (p - Center).magnitude; if (radius > MaxRadius) MaxRadius = radius; } } public bool Include((int, int) grid) => grids.Contains(grid); public void Add(Vector2 point) => Add(point, PixelArea.GetGrid(point)); public void Add(Vector2 point, (int x, int y) grid) { Center += (point - Center) / Pixels.Count; var radius = (point - Center).magnitude; if (radius > MaxRadius) MaxRadius = radius; Pixels.Add(point); grids.AddRange(new (int, int)[] { (grid.x + -1, grid.y + 0) , (grid.x + 1 , grid.y + 0), (grid.x + 1, grid.y + -1) , (grid.x + -1, grid.y + 1), (grid.x + 0, grid.y + -1) , (grid.x + 0 , grid.y + 1), (grid.x + -1, grid.y + -1) , (grid.x + 1 , grid.y + 1), grid }); } public float CircleBrightness(out float variance, int[] pixels, Func GetBrightness, int kernel_size = 3) { var hash = new HashSet<(int, int)>(); foreach (var (cos, sin) in PixelArea.AngleMathList) { var x = (int)Math.Round(Center.x + (MaxRadius + 1) * cos); // +1防止区域太小 var y = (int)Math.Round(Center.y + (MaxRadius + 1) * sin); hash.Add((x, y)); } var sum = 0f; var sum2 = 0f; foreach (var p in hash) { var value = GetBrightness(pixels, p, kernel_size); sum += value; sum2 += value * value; } var avg = sum / hash.Count; variance = sum2 / hash.Count - avg * avg; //Debug.Log(hash.Count + " -- bright: " + avg); return avg; } } }