using ChunkyImageLib.DataHolders; using ChunkyImageLib.Operations; using System; using System.Collections.Generic; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Shapes; namespace ChunkyImageLibVis; /// /// Interaction logic for MainWindow.xaml /// public partial class MainWindow : Window, INotifyPropertyChanged { private double x1; private double y1; private double x2; private double y2; public double X1 { get => x1; set { x1 = value; PropertyChanged?.Invoke(this, new(nameof(X1))); PropertyChanged?.Invoke(this, new(nameof(RectWidth))); PropertyChanged?.Invoke(this, new(nameof(HalfRectWidth))); } } public double X2 { get => x2; set { x2 = value; PropertyChanged?.Invoke(this, new(nameof(X2))); PropertyChanged?.Invoke(this, new(nameof(RectWidth))); PropertyChanged?.Invoke(this, new(nameof(HalfRectWidth))); } } public double Y1 { get => y1; set { y1 = value; PropertyChanged?.Invoke(this, new(nameof(Y1))); PropertyChanged?.Invoke(this, new(nameof(RectHeight))); PropertyChanged?.Invoke(this, new(nameof(HalfRectHeight))); } } public double Y2 { get => y2; set { y2 = value; PropertyChanged?.Invoke(this, new(nameof(Y2))); PropertyChanged?.Invoke(this, new(nameof(RectHeight))); PropertyChanged?.Invoke(this, new(nameof(HalfRectHeight))); } } public double RectWidth { get => Math.Abs(X2 - X1); } public double RectHeight { get => Math.Abs(Y2 - Y1); } public double HalfRectWidth { get => Math.Abs(X2 - X1) / 2; } public double HalfRectHeight { get => Math.Abs(Y2 - Y1) / 2; } private double angle; public double Angle { get => angle; set { angle = value; PropertyChanged?.Invoke(this, new(nameof(Angle))); } } public MainWindow() { InitializeComponent(); DataContext = this; CreateGrid(); } public void CreateGrid() { for (int i = 0; i < 20; i++) { Line ver = new() { X1 = i * 32, X2 = i * 32, Y1 = 0, Y2 = 1000, Stroke = Brushes.Gray, StrokeThickness = 1, }; Line hor = new() { X1 = 0, X2 = 1000, Y1 = i * 32, Y2 = i * 32, Stroke = Brushes.Gray, StrokeThickness = 1, }; canvas.Children.Add(ver); canvas.Children.Add(hor); } } public List rectangles = new(); private void UpdateChunks() { foreach (var rect in rectangles) { canvas.Children.Remove(rect); } rectangles.Clear(); var chunks = OperationHelper.FindChunksTouchingRectangle(new VecD(X1 + HalfRectWidth, Y1 + HalfRectHeight), new(X2 - X1, Y2 - Y1), Angle * Math.PI / 180, 32); var innerChunks = OperationHelper.FindChunksFullyInsideRectangle(new VecD(X1 + HalfRectWidth, Y1 + HalfRectHeight), new(X2 - X1, Y2 - Y1), Angle * Math.PI / 180, 32); chunks.ExceptWith(innerChunks); foreach (var chunk in chunks) { Rectangle rectangle = new() { Fill = Brushes.Green, Width = 32, Height = 32, }; Canvas.SetLeft(rectangle, chunk.X * 32); Canvas.SetTop(rectangle, chunk.Y * 32); canvas.Children.Add(rectangle); rectangles.Add(rectangle); } } public event PropertyChangedEventHandler? PropertyChanged; private bool drawing = false; private bool rotating = false; private void Canvas_MouseDown(object sender, MouseButtonEventArgs e) { if (rotating) { rotating = false; return; } drawing = true; Angle = 0; var pos = e.GetPosition(canvas); if (e.LeftButton == MouseButtonState.Pressed) { X1 = pos.X; Y1 = pos.Y; } else { X1 = Math.Floor(pos.X / 32) * 32; Y1 = Math.Floor(pos.Y / 32) * 32; } } private void Canvas_MouseMove(object sender, MouseEventArgs e) { var pos = e.GetPosition(canvas); if (drawing) { if (e.LeftButton == MouseButtonState.Pressed) { X2 = pos.X; Y2 = pos.Y; } else { X2 = Math.Floor(pos.X / 32) * 32; Y2 = Math.Floor(pos.Y / 32) * 32; } } else if (rotating) { VecD center = new VecD(X1 + HalfRectWidth, Y1 + HalfRectHeight); Angle = new VecD(pos.X - center.X, pos.Y - center.Y).CCWAngleTo(new VecD(X2 - center.X, Y2 - center.Y)) * -180 / Math.PI; } UpdateChunks(); } private void Canvas_MouseUp(object sender, MouseButtonEventArgs e) { if (drawing) { drawing = false; rotating = true; } } }