| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- 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<Vector2> Pixels;
- HashSet<(int, int)> grids;
- public PixelCircleArea(Vector2 location)
- {
- Center = location;
- Pixels = new HashSet<Vector2> { location };
- MaxRadius = 0;
- grids = new HashSet<(int, int)>();
- Add(location);
- }
- public PixelCircleArea(IList<PixelCircleArea> areas)
- {
- Center = Vector2.zero;
- Pixels = new HashSet<Vector2>();
- 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<int[], (int, int), int, float> 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;
- }
- }
- }
|