PixelArea.cs 4.1 KB

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