Предотвратить выход круга из холста / окна, если круг больше холста? - PullRequest
0 голосов
/ 21 июня 2020

Как я могу предотвратить круг, чтобы он никогда не выходил за пределы холста / окна, если круг больше холста?

Мне нужно, чтобы он автоматически настраивался на максимально доступный размер. Как лучше всего это исправить? Я знаю, что использование функции перетаскивания может решить эту проблему, но мне нужно сделать это в два щелчка. Первый щелчок определит центральную точку, а второй - радиус.

Код WPF xaml

<Window x:Class="ShapeAnimator.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ShapeAnimator"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Button Content="Step" HorizontalAlignment="Left" Margin="10,390,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>
        <Button Content="Button" HorizontalAlignment="Left" Margin="90,390,0,0" VerticalAlignment="Top" Width="75"/>
        <Canvas Name="Canvas1" 
                Background="#000000"
                HorizontalAlignment="Left" Height="376" VerticalAlignment="Top" Width="792"
                MouseDown="Canvas1_MouseDown"
                
                />
        <Label 
            Name="CoordLabel"
            Content="Label" HorizontalAlignment="Left" Margin="708,383,0,0" VerticalAlignment="Top" RenderTransformOrigin="0.362,0.083"/>

    </Grid>
</Window>

и .cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ShapeAnimator
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        int ClickStep = 1;
        double x1, y1;

        List<Circle> circles = new List<Circle>();
        private Animator animator;

        public MainWindow()
        {
            InitializeComponent();
            animator = new Animator((int)Canvas1.Width, (int)Canvas1.Height);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            foreach(Circle c in circles)
            {
                animator.Animate(c);
            }

            RefreshScreen();
        }


        private void Canvas1_MouseDown(object sender, MouseButtonEventArgs e)
        {
            double x = Mouse.GetPosition(Canvas1).X;
            double y = Mouse.GetPosition(Canvas1).Y;
            CoordLabel.Content = x.ToString() + ":" + y.ToString();
            
            if (ClickStep > 0)
            {
                x1 = x;
                y1 = y;
                DrawCircle(x1, y1, 3);
            }
            else
            {
                double radius = Math.Sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));

                Circle c = new Circle(x1, y1, radius);
                circles.Add(c);

                RefreshScreen();
            }

            ClickStep = -ClickStep;
        }


        private void RefreshScreen()
        {
            ClearScreen();
            foreach(Circle c in circles)
            {
                DrawCircle(c.x, c.y, c.radius);
            }
        }

        private void ClearScreen()
        {
            Canvas1.Children.Clear();
        }

        private void DrawCircle(double x, double y, double radius)
        {
            Ellipse c = new Ellipse()
            {
                Width = radius * 2,
                Height = radius * 2,
                Stroke = Brushes.Red,
                StrokeThickness = 1
            };

            Canvas1.Children.Add(c);
            c.SetValue(Canvas.LeftProperty, x - radius);
            c.SetValue(Canvas.TopProperty, y - radius);
        }


    }
}

1 Ответ

0 голосов
/ 21 июня 2020

Не уверен, почему перетаскивание исправило бы это, но наверняка в момент, когда будет сделан первый щелчок, вы сможете узнать его местоположение и, следовательно, кратчайшее расстояние до всех 4 краев холста, и, следовательно, вы можете определить максимально возможный радиус. Либо во время первого щелчка, либо во время второго, сделайте это cal c, сделайте радиус cal c, если радиус больше максимального, уменьшите радиус. Например:

        else
        {
            double radius = Math.Sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));

            if(radius > x1)
              radius = x1;
            if(radius > y1)
              radius = y1;
            if(radius > Canvas1.Width - x1)
              radius = Canvas1.Width - x1;
            if(radius > Canvas1.Height - y1)
              radius = Canvas1.Height - y1;
            

Радиус окажется на наименьшем расстоянии от края после этих 4 операторов if

ps; пожалуйста, назовите свои элементы управления чем-то более подходящим, чем Canvas1, Textbox1 и т. д. c - программам становится очень трудно следовать, когда у них есть огромное количество элементов управления, все называемые TypenameN

...