MainWindow.xaml.cs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. using ChunkyImageLib.DataHolders;
  2. using ChunkyImageLib.Operations;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.ComponentModel;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Input;
  9. using System.Windows.Media;
  10. using System.Windows.Shapes;
  11. namespace ChunkyImageLibVis;
  12. /// <summary>
  13. /// Interaction logic for MainWindow.xaml
  14. /// </summary>
  15. public partial class MainWindow : Window, INotifyPropertyChanged
  16. {
  17. private double x1;
  18. private double y1;
  19. private double x2;
  20. private double y2;
  21. public double X1
  22. {
  23. get => x1;
  24. set
  25. {
  26. x1 = value;
  27. PropertyChanged?.Invoke(this, new(nameof(X1)));
  28. PropertyChanged?.Invoke(this, new(nameof(RectWidth)));
  29. PropertyChanged?.Invoke(this, new(nameof(HalfRectWidth)));
  30. }
  31. }
  32. public double X2
  33. {
  34. get => x2;
  35. set
  36. {
  37. x2 = value;
  38. PropertyChanged?.Invoke(this, new(nameof(X2)));
  39. PropertyChanged?.Invoke(this, new(nameof(RectWidth)));
  40. PropertyChanged?.Invoke(this, new(nameof(HalfRectWidth)));
  41. }
  42. }
  43. public double Y1
  44. {
  45. get => y1;
  46. set
  47. {
  48. y1 = value;
  49. PropertyChanged?.Invoke(this, new(nameof(Y1)));
  50. PropertyChanged?.Invoke(this, new(nameof(RectHeight)));
  51. PropertyChanged?.Invoke(this, new(nameof(HalfRectHeight)));
  52. }
  53. }
  54. public double Y2
  55. {
  56. get => y2;
  57. set
  58. {
  59. y2 = value;
  60. PropertyChanged?.Invoke(this, new(nameof(Y2)));
  61. PropertyChanged?.Invoke(this, new(nameof(RectHeight)));
  62. PropertyChanged?.Invoke(this, new(nameof(HalfRectHeight)));
  63. }
  64. }
  65. public double RectWidth { get => Math.Abs(X2 - X1); }
  66. public double RectHeight { get => Math.Abs(Y2 - Y1); }
  67. public double HalfRectWidth { get => Math.Abs(X2 - X1) / 2; }
  68. public double HalfRectHeight { get => Math.Abs(Y2 - Y1) / 2; }
  69. private double angle;
  70. public double Angle
  71. {
  72. get => angle;
  73. set
  74. {
  75. angle = value;
  76. PropertyChanged?.Invoke(this, new(nameof(Angle)));
  77. }
  78. }
  79. public MainWindow()
  80. {
  81. InitializeComponent();
  82. DataContext = this;
  83. CreateGrid();
  84. }
  85. public void CreateGrid()
  86. {
  87. for (int i = 0; i < 20; i++)
  88. {
  89. Line ver = new()
  90. {
  91. X1 = i * 32,
  92. X2 = i * 32,
  93. Y1 = 0,
  94. Y2 = 1000,
  95. Stroke = Brushes.Gray,
  96. StrokeThickness = 1,
  97. };
  98. Line hor = new()
  99. {
  100. X1 = 0,
  101. X2 = 1000,
  102. Y1 = i * 32,
  103. Y2 = i * 32,
  104. Stroke = Brushes.Gray,
  105. StrokeThickness = 1,
  106. };
  107. canvas.Children.Add(ver);
  108. canvas.Children.Add(hor);
  109. }
  110. }
  111. public List<Rectangle> rectangles = new();
  112. private void UpdateChunks()
  113. {
  114. foreach (var rect in rectangles)
  115. {
  116. canvas.Children.Remove(rect);
  117. }
  118. rectangles.Clear();
  119. var chunks = OperationHelper.FindChunksTouchingRectangle(new VecD(X1 + HalfRectWidth, Y1 + HalfRectHeight), new(X2 - X1, Y2 - Y1), Angle * Math.PI / 180, 32);
  120. var innerChunks = OperationHelper.FindChunksFullyInsideRectangle(new VecD(X1 + HalfRectWidth, Y1 + HalfRectHeight), new(X2 - X1, Y2 - Y1), Angle * Math.PI / 180, 32);
  121. chunks.ExceptWith(innerChunks);
  122. foreach (var chunk in chunks)
  123. {
  124. Rectangle rectangle = new()
  125. {
  126. Fill = Brushes.Green,
  127. Width = 32,
  128. Height = 32,
  129. };
  130. Canvas.SetLeft(rectangle, chunk.X * 32);
  131. Canvas.SetTop(rectangle, chunk.Y * 32);
  132. canvas.Children.Add(rectangle);
  133. rectangles.Add(rectangle);
  134. }
  135. }
  136. public event PropertyChangedEventHandler? PropertyChanged;
  137. private bool drawing = false;
  138. private bool rotating = false;
  139. private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
  140. {
  141. if (rotating)
  142. {
  143. rotating = false;
  144. return;
  145. }
  146. drawing = true;
  147. Angle = 0;
  148. var pos = e.GetPosition(canvas);
  149. if (e.LeftButton == MouseButtonState.Pressed)
  150. {
  151. X1 = pos.X;
  152. Y1 = pos.Y;
  153. }
  154. else
  155. {
  156. X1 = Math.Floor(pos.X / 32) * 32;
  157. Y1 = Math.Floor(pos.Y / 32) * 32;
  158. }
  159. }
  160. private void Canvas_MouseMove(object sender, MouseEventArgs e)
  161. {
  162. var pos = e.GetPosition(canvas);
  163. if (drawing)
  164. {
  165. if (e.LeftButton == MouseButtonState.Pressed)
  166. {
  167. X2 = pos.X;
  168. Y2 = pos.Y;
  169. }
  170. else
  171. {
  172. X2 = Math.Floor(pos.X / 32) * 32;
  173. Y2 = Math.Floor(pos.Y / 32) * 32;
  174. }
  175. }
  176. else if (rotating)
  177. {
  178. VecD center = new VecD(X1 + HalfRectWidth, Y1 + HalfRectHeight);
  179. Angle = new VecD(pos.X - center.X, pos.Y - center.Y).CCWAngleTo(new VecD(X2 - center.X, Y2 - center.Y)) * -180 / Math.PI;
  180. }
  181. UpdateChunks();
  182. }
  183. private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
  184. {
  185. if (drawing)
  186. {
  187. drawing = false;
  188. rotating = true;
  189. }
  190. }
  191. }