如果圆大于canvas,防止圆超出canvas/window?

Prevent circle of going out of the canvas/window if circle is bigger than canvas?

万一圆比 canvas 大,我怎样才能防止圆不超出 canvas/window?

我需要它自动调整到最大可用尺寸。解决此问题的最佳解决方案是什么?我知道使用拖动功能可以解决这个问题,但我需要点击 2 次才能完成。第一次单击将定义中心点,第二次单击定义半径。

WPFxaml代码

<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);
        }


    }
}

不确定为什么拖动会修复它,但可以肯定的是,当第一次点击完成时,您可以知道它的位置,因此可以知道到 canvas 的所有 4 个边缘的最短距离,因此您可以计算出最大可能的半径。在第一次点击或第二次点击时,进行计算,计算半径,如果半径大于最大值,则减小半径。例如:

        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 等更合适的名称 - 当程序拥有大量控件时,它们会变得非常难以理解,所有控件都称为 TypenameN