ViewOval.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. using PaintDotNet.Annotation.Enum;
  2. using PaintDotNet.Base.CommTool;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Diagnostics;
  6. using System.Drawing;
  7. using System.Drawing.Drawing2D;
  8. using System.Globalization;
  9. using System.Runtime.Serialization;
  10. using System.Windows.Forms;
  11. namespace PaintDotNet.Annotation.FieldView
  12. {
  13. /// <summary>
  14. /// 椭圆形视场绘制
  15. /// </summary>
  16. public class ViewOval : ViewBase
  17. {
  18. #region Calculate
  19. List<Func<PointF>> m_ovalTemple;
  20. float _a;
  21. float _b;
  22. float _centerx;
  23. float _centery;
  24. float _angle = 0;
  25. readonly float _sqrt2 = (float)Math.Sqrt(2);
  26. public override double Width
  27. {
  28. get => _a * 2;
  29. set
  30. {
  31. _a = (float)value / 2;
  32. _centerx = Center.X;
  33. _centery = Center.Y;
  34. Points = CalculateCirclePoints();
  35. }
  36. }
  37. public override double Height
  38. {
  39. get => _b * 2;
  40. set
  41. {
  42. _b = (float)value / 2;
  43. _centerx = Center.X;
  44. _centery = Center.Y;
  45. Points = CalculateCirclePoints();
  46. }
  47. }
  48. void InitOvalTemplate()
  49. {
  50. m_ovalTemple = new List<Func<PointF>>();
  51. m_ovalTemple.Add(
  52. new Func<PointF>(() =>
  53. { return new PointF(-(_a / _sqrt2), -(_b / _sqrt2)); }));
  54. m_ovalTemple.Add(
  55. new Func<PointF>(() =>
  56. { return new PointF(0, -_b); }));
  57. m_ovalTemple.Add(
  58. new Func<PointF>(() =>
  59. { return new PointF((_a / _sqrt2), -(_b / _sqrt2)); }));
  60. m_ovalTemple.Add(
  61. new Func<PointF>(() =>
  62. { return new PointF(_a, 0); }));
  63. m_ovalTemple.Add(
  64. new Func<PointF>(() =>
  65. { return new PointF((_a / _sqrt2), (_b / _sqrt2)); }));
  66. m_ovalTemple.Add(
  67. new Func<PointF>(() =>
  68. { return new PointF(0, _b); }));
  69. m_ovalTemple.Add(
  70. new Func<PointF>(() =>
  71. { return new PointF(-(_a / _sqrt2), (_b / _sqrt2)); }));
  72. m_ovalTemple.Add(
  73. new Func<PointF>(() =>
  74. { return new PointF(-_a, 0); }));
  75. }
  76. List<PointF> CalculateCirclePoints()
  77. {
  78. List<PointF> points = new List<PointF>();
  79. foreach (var func in m_ovalTemple)
  80. {
  81. var p = func.Invoke();
  82. p = BasicCalculationHelper.GetAnglePoint(p, _lastCenter, _angle);
  83. points.Add(new PointF(p.X + _centerx, p.Y + _centery));
  84. }
  85. return points;
  86. }
  87. /// <summary>
  88. /// 当PointList被修改时,更新参数
  89. /// </summary>
  90. /// <param name="points"></param>
  91. void ReverseBuild(List<PointF> points)
  92. {
  93. _b = (float)(BasicCalculationHelper.GetDistance(points[1], points[5]) / 2);
  94. _a = (float)(BasicCalculationHelper.GetDistance(points[3], points[7]) / 2);
  95. _centerx = (points[1].X + points[5].X) / 2;
  96. _centery = (points[1].Y + points[5].Y) / 2;
  97. _angle = (float)BasicCalculationHelper.CalculateAngle(new PointF(_centerx, _centery), new PointF(_centerx + 100, _centery), points[3]);
  98. }
  99. public override double Getacreage()
  100. {
  101. var b = BasicCalculationHelper.GetDistance(Points[1], Points[5]) / 2;
  102. var a = BasicCalculationHelper.GetDistance(Points[3], Points[7]) / 2;
  103. return Math.PI * a * b;
  104. }
  105. #endregion
  106. #region Constructor
  107. public ViewOval()
  108. {
  109. this.objectType = DrawClass.View;
  110. this.drawToolType = DrawToolType.ViewOval;
  111. Rotatable = true;
  112. Initialize();
  113. InitOvalTemplate();
  114. }
  115. public ViewOval(int x, int y) : this()
  116. {
  117. for (int i = 0; i < 8; i++) AddPoint(x, y);
  118. }
  119. public ViewOval(List<PointF> points) : this()
  120. {
  121. ReverseBuild(points);
  122. Points = points;
  123. }
  124. #endregion
  125. public override PointF Center
  126. {
  127. get
  128. {
  129. var x = (Points[1].X + Points[5].X) / 2;
  130. var y = (Points[1].Y + Points[5].Y) / 2;
  131. return new PointF(x, y);
  132. }
  133. set { }
  134. }
  135. #region Handle
  136. public override int HandleCount => 9;
  137. public override PointF GetHandle(int handleNumber)
  138. {
  139. if (handleNumber > Points.Count)
  140. {
  141. var x = (Center.X + Points[3].X) / 2;
  142. var y = (Center.Y + Points[3].Y) / 2;
  143. return new PointF(x, y);
  144. }
  145. else
  146. return Points[handleNumber - 1];
  147. }
  148. public override Cursor GetHandleCursor(int handleNumber)
  149. {
  150. switch (handleNumber)
  151. {
  152. case 9:
  153. return m_rotateCursor;
  154. default:
  155. return m_resizeCursor;
  156. }
  157. }
  158. public override void MoveHandleTo(Point point, int handleNumber)
  159. {
  160. if (handleNumber == 9) MoveRotate(point);
  161. else if (handleNumber % 2 != 0)
  162. MoveCorner(point);
  163. else
  164. MoveEdage(point, handleNumber);
  165. OnPropertyChanged();
  166. }
  167. private void MoveCorner(Point point)
  168. {
  169. _centerx = Center.X;
  170. _centery = Center.Y;
  171. var p = BasicCalculationHelper.GetAnglePoint(point, new PointF(_centerx, _centery), -_angle);
  172. _a = Math.Abs(p.X - Center.X) * _sqrt2;
  173. _b = Math.Abs(p.Y - Center.Y) * _sqrt2;
  174. Points = CalculateCirclePoints();
  175. }
  176. protected override void MoveRotate(PointF point)
  177. {
  178. _centerx = Center.X;
  179. _centery = Center.Y;
  180. _angle = (float)BasicCalculationHelper.CalculateAngle(new PointF(_centerx, _centery), new PointF(_centerx + 100, _centery), point);
  181. Points = CalculateCirclePoints();
  182. }
  183. private void MoveEdage(Point point, int i)
  184. {
  185. var o = Points[(i + 3) % 8];
  186. var p = BasicCalculationHelper.GetAnglePoint(point, o, -_angle);
  187. var c = BasicCalculationHelper.GetAnglePoint(Center, o, -_angle);
  188. if (i % 4 == 0)
  189. {
  190. c.X = (p.X + o.X) / 2;
  191. _a = Math.Abs(p.X - o.X) / 2;
  192. }
  193. else
  194. {
  195. c.Y = (p.Y + o.Y) / 2;
  196. _b = Math.Abs(p.Y - o.Y) / 2;
  197. }
  198. c = BasicCalculationHelper.GetAnglePoint(c, o, _angle);
  199. _centerx = c.X;
  200. _centery = c.Y;
  201. Points = CalculateCirclePoints();
  202. }
  203. #endregion
  204. #region Clone
  205. public override DrawObject Clone()
  206. {
  207. return Clone(ISurfaceBox);
  208. }
  209. public override DrawObject Clone(ISurfaceBox surfaceBox)
  210. {
  211. ViewOval drawRectangle = new ViewOval(Points);
  212. drawRectangle.ISurfaceBox = surfaceBox;
  213. drawRectangle.combineMode = this.combineMode;
  214. drawRectangle.Color = Color;
  215. drawRectangle.ID = ID;
  216. FillDrawObjectFields(drawRectangle);
  217. return drawRectangle;
  218. }
  219. #endregion
  220. }
  221. }