FocalPlanes3D.cs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. using StageController;
  2. using System;
  3. using System.Collections.Generic;
  4. namespace Metis.AutoAnalysis
  5. {
  6. public class FocalPlanes3D
  7. {
  8. private BasePointEnum basePoint;
  9. private double A, B, C, D;
  10. private Point3D center;
  11. private List<double> As = new List<double>();
  12. private List<double> Bs = new List<double>();
  13. private List<double> Cs = new List<double>();
  14. private List<double> Ds = new List<double>();
  15. private List<Vector> vectors = new List<Vector>();
  16. public FocalPlanes3D(Point3D p1, Point3D p2, Point3D p3)
  17. : this(p1.X, p1.Y, p1.Z, p2.X, p2.Y, p2.Z, p3.X, p3.Y, p3.Z) { }
  18. public FocalPlanes3D(double x1, double y1, double z1, double x2, double y2, double z2, double x3, double y3, double z3)
  19. {
  20. if (x1 == x2 && x2 == x3 || y1 == y2 && y2 == y3)
  21. {
  22. throw new ArgumentException("Three points were in a same straight line.");
  23. }
  24. basePoint = BasePointEnum.Threee;
  25. A = (y2 - y1) * (z3 - z1) - (y3 - y1) * (z2 - z1);
  26. B = (z2 - z1) * (x3 - x1) - (z3 - z1) * (x2 - x1);
  27. C = (x2 - x1) * (y3 - y1) - (x3 - x1) * (y2 - y1);
  28. D = -A * x1 - B * y1 - C * z1;
  29. }
  30. public FocalPlanes3D(Point3D center, List<Point3D> points)
  31. {
  32. if (center == null || points == null || points.Count < 3)
  33. {
  34. throw new ArgumentNullException("Argument is null, the number of argumentor is Lless than four.");
  35. }
  36. basePoint = BasePointEnum.Multi;
  37. this.center = center;
  38. for (int i = 0; i < points.Count; i++)
  39. {
  40. var next = i + 1 == points.Count ? 0 : i + 1;
  41. if (center.X == points[i].X && center.X == points[next].X || center.Y == points[i].Y && center.Y == points[next].Y)
  42. {
  43. throw new ArgumentException("Three points were in a same straight line.");
  44. }
  45. vectors.Add(new Vector(center.X - points[i].X, center.Y - points[i].Y, 0));
  46. As.Add((points[i].Y - center.Y) * (points[next].Z - center.Z) - (points[next].Y - center.Y) * (points[i].Z - center.Z));
  47. Bs.Add((points[i].Z - center.Z) * (points[next].X - center.X) - (points[next].Z - center.Z) * (points[i].X - center.X));
  48. Cs.Add((points[i].X - center.X) * (points[next].Y - center.Y) - (points[next].X - center.X) * (points[i].Y - center.Y));
  49. Ds.Add(-As[i] * center.X - Bs[i] * center.Y - Cs[i] * center.Z);
  50. }
  51. //Logs.WriteFocus($"\tCenter=({center.X}, {center.Y}, {center.Z})");
  52. //for (int i=0;i<points.Count; i++)
  53. //{
  54. // Logs.WriteFocus($"\ti={i+1},\t({points[i].X}, {points[i].Y}, {points[i].Z})");
  55. //}
  56. }
  57. public double GetFocusValue(double x, double y)
  58. {
  59. if (basePoint == BasePointEnum.Threee)
  60. {
  61. var z = (-D - A * x - B * y) / C;
  62. //Logs.WriteFocus($"\ti={0},\tx={x}, y={y}, \tz={z}");
  63. return z;
  64. }
  65. else
  66. {
  67. var vector = new Vector(center.X - x, center.Y - y, 0);
  68. for (int i = 0; i < vectors.Count; i++)
  69. {
  70. var next = i + 1 == vectors.Count ? 0 : i + 1;
  71. var angle = vectors[i] * vectors[next] / (vectors[i].Model * vectors[next].Model);
  72. var angleHalf1 = vectors[i] * vector / (vectors[i].Model * vector.Model);
  73. var angleHalf2 = vector * vectors[next] / (vector.Model * vectors[next].Model);
  74. if (Math.Abs(Math.Acos(angle) - Math.Acos(angleHalf1) - Math.Acos(angleHalf2)) <= 1e-6)
  75. {
  76. var z = (-Ds[i] - As[i] * x - Bs[i] * y) / Cs[i];
  77. //Logs.WriteFocus($"\tNo={i+1}, \tx={x}, \ty={y}, \tz={z}");
  78. return z;
  79. }
  80. }
  81. throw new Exception("Space sector not closed.");
  82. }
  83. }
  84. public int GetAreaNo(double x, double y)
  85. {
  86. if (basePoint == BasePointEnum.Threee)
  87. {
  88. return -1;
  89. }
  90. else
  91. {
  92. var vector = new Vector(center.X - x, center.Y - y, 0);
  93. for (int i = 0; i < vectors.Count; i++)
  94. {
  95. var next = i + 1 == vectors.Count ? 0 : i + 1;
  96. var angle = vectors[i] * vectors[next] / (vectors[i].Model * vectors[next].Model);
  97. var angleHalf1 = vectors[i] * vector / (vectors[i].Model * vector.Model);
  98. var angleHalf2 = vector * vectors[next] / (vector.Model * vectors[next].Model);
  99. if (Math.Abs(Math.Acos(angle) - Math.Acos(angleHalf1) - Math.Acos(angleHalf2)) <= 1e-6)
  100. {
  101. return i + 1;
  102. }
  103. }
  104. throw new Exception("Space sector not closed.");
  105. }
  106. }
  107. }
  108. public enum BasePointEnum
  109. {
  110. Threee,
  111. Multi,
  112. }
  113. public class Point3D
  114. {
  115. public double X { get; set; }
  116. public double Y { get; set; }
  117. public double Z { get; set; }
  118. public Point3D(double x, double y, double z)
  119. {
  120. X = x; Y = y; Z = z;
  121. }
  122. }
  123. public class Vector
  124. {
  125. private double x, y, z;
  126. public Vector(double x, double y, double z)
  127. {
  128. this.x = x;
  129. this.y = y;
  130. this.z = z;
  131. }
  132. public double Model => Math.Sqrt(x * x + y * y + z * z);
  133. public static Vector operator +(Vector AB, Vector AC)
  134. {
  135. return new Vector(AB.x + AC.x, AB.y + AC.y, AB.z + AC.z);
  136. }
  137. public static Vector operator -(Vector AB, Vector AC)
  138. {
  139. return new Vector(AB.x - AC.x, AB.y - AC.y, AB.z - AC.z);
  140. }
  141. public static Vector operator ^(Vector AB, Vector AC)
  142. {
  143. return new Vector(AB.y * AC.z - AC.y * AB.z, AC.x * AB.z - AB.x * AC.z, AB.x * AC.y - AC.x * AB.y);
  144. }
  145. public static double operator *(Vector AB, Vector AC)
  146. {
  147. return AB.x * AC.x + AB.y * AC.y + AB.z * AC.z;
  148. }
  149. }
  150. }