PixelArea.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. using o0;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Threading.Tasks;
  5. using Unity.VisualScripting;
  6. using UnityEngine;
  7. using ZIM.Unity;
  8. using Color = UnityEngine.Color;
  9. namespace ZIM
  10. {
  11. internal class PixelArea
  12. {
  13. public static int gridLength = 16;
  14. //public static (int x, int y) gridSize;
  15. public static (int x, int y) GetGrid(Vector2 v)
  16. {
  17. var m = (int)(v.x / gridLength);
  18. var n = (int)(v.y / gridLength);
  19. return (m, n);
  20. }
  21. public static List<(double cos, double sin)> AngleMathList {
  22. get
  23. {
  24. if (angleMathList != null)
  25. return angleMathList;
  26. // 三角函数值记录在list中
  27. double step = angleStep * 0.017453292519943295;
  28. angleMathList = new List<(double cos, double sin)>();
  29. for (double i = 0; i < 6.2831853; i += step)
  30. {
  31. var cos = Math.Cos(i);
  32. var sin = Math.Sin(i);
  33. angleMathList.Add((cos, sin));
  34. }
  35. return angleMathList;
  36. }
  37. }
  38. static float angleStep = 11.25f;
  39. static List<(double cos, double sin)> angleMathList;
  40. public Vector2 Center;
  41. public float MaxRadius;
  42. public HashSet<Vector2> Pixels;
  43. HashSet<(int, int)> grids;
  44. public PixelArea(Vector2 location)
  45. {
  46. Center = location;
  47. Pixels = new HashSet<Vector2> { location };
  48. MaxRadius = 0;
  49. grids = new HashSet<(int, int)>();
  50. Add(location);
  51. }
  52. public PixelArea(IList<PixelArea> areas)
  53. {
  54. Center = Vector2.zero;
  55. Pixels = new HashSet<Vector2>();
  56. MaxRadius = 0;
  57. grids = new HashSet<(int, int)>();
  58. foreach (var a in areas)
  59. {
  60. Pixels.AddRange(a.Pixels);
  61. grids.AddRange(a.grids);
  62. }
  63. foreach (var p in Pixels)
  64. {
  65. Center += p;
  66. }
  67. Center /= Pixels.Count;
  68. foreach (var p in Pixels)
  69. {
  70. var radius = (p - Center).magnitude;
  71. if (radius > MaxRadius)
  72. MaxRadius = radius;
  73. }
  74. }
  75. public bool Include((int, int) grid) => grids.Contains(grid);
  76. public void Add(Vector2 point) => Add(point, GetGrid(point));
  77. public void Add(Vector2 point, (int x, int y) grid)
  78. {
  79. Center += (point - Center) / Pixels.Count;
  80. var radius = (point - Center).magnitude;
  81. if (radius > MaxRadius)
  82. MaxRadius = radius;
  83. Pixels.Add(point);
  84. grids.AddRange(new (int, int)[]
  85. {
  86. (grid.x + -1, grid.y + 0) , (grid.x + 1 , grid.y + 0),
  87. (grid.x + 1, grid.y + -1) , (grid.x + -1, grid.y + 1),
  88. (grid.x + 0, grid.y + -1) , (grid.x + 0 , grid.y + 1),
  89. (grid.x + -1, grid.y + -1) , (grid.x + 1 , grid.y + 1),
  90. grid
  91. });
  92. }
  93. public float TotalBrightness(Color[] pixels,Func<int,int,int> Vector2ToIndex, int outer_size = 3)
  94. {
  95. (int x, int y) rectMin = ((int)(Center.x - MaxRadius - outer_size), (int)(Center.y - MaxRadius - outer_size));
  96. (int x, int y) rectMax = ((int)(Center.x + MaxRadius + outer_size), (int)(Center.y + MaxRadius + outer_size));
  97. var total = 0f;
  98. Parallel.For(rectMin.x, rectMax.x, (i) =>
  99. {
  100. var t = 0;
  101. for (int j = rectMin.y; j < rectMax.y; j++)
  102. {
  103. var index = Vector2ToIndex(i, j);
  104. var b = pixels[index].Brightness(64);
  105. t += b;
  106. }
  107. lock (InfraredLocate.locker)
  108. {
  109. total += t;
  110. }
  111. });
  112. //total /= (rectMax.y - rectMin.y) * (rectMax.x - rectMin.x);
  113. return total;
  114. }
  115. }
  116. }