using o0; using o0InfraredLocate.ZIM; using System; using System.Collections.Generic; using System.Threading.Tasks; using Unity.VisualScripting; using UnityEngine; using ZIM.Unity; using Color = UnityEngine.Color; namespace ZIM { internal class PixelArea { public static int gridLength = 16; //public static (int x, int y) gridSize; public static (int x, int y) GetGrid(Vector2 v) { var m = (int)(v.x / gridLength); var n = (int)(v.y / gridLength); return (m, n); } public static List<(double cos, double sin)> AngleMathList { get { if (angleMathList != null) return angleMathList; // 三角函数值记录在list中 double step = angleStep * 0.017453292519943295; angleMathList = new List<(double cos, double sin)>(); for (double i = 0; i < 6.2831853; i += step) { var cos = Math.Cos(i); var sin = Math.Sin(i); angleMathList.Add((cos, sin)); } return angleMathList; } } static float angleStep = 11.25f; static List<(double cos, double sin)> angleMathList; public Vector2 Center; public float MaxRadius; public HashSet Pixels; HashSet<(int, int)> grids; public PixelArea(Vector2 location) { Center = location; Pixels = new HashSet { location }; MaxRadius = 0; grids = new HashSet<(int, int)>(); Add(location); } public PixelArea(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, 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 TotalBrightness(Color[] pixels,Func Vector2ToIndex, int outer_size = 3) { (int x, int y) rectMin = ((int)(Center.x - MaxRadius - outer_size), (int)(Center.y - MaxRadius - outer_size)); (int x, int y) rectMax = ((int)(Center.x + MaxRadius + outer_size), (int)(Center.y + MaxRadius + outer_size)); var total = 0f; Parallel.For(rectMin.x, rectMax.x, (i) => { var t = 0; for (int j = rectMin.y; j < rectMax.y; j++) { var index = Vector2ToIndex(i, j); var b = pixels[index].Brightness(64); t += b; } lock (InfraredLocate.Locker) { total += t; } }); //total /= (rectMax.y - rectMin.y) * (rectMax.x - rectMin.x); return total; } } }