WPF圆形运动物体

WPF circular moving object

我正在尝试创建一个示例项目以在 WPF 中沿圆形路径移动椭圆对象。 为此,我使用了以下等式: x = x0 + R * sin(a), y = y0 + R * cos (a), 这里(x0, y0)是圆形路径的圆心,R是路径的半径, 但是我的椭圆不是在圆周上移动,而是在一条直线上移动。 我哪里弄错了?

我的XAML来源:

<Window x:Class="MyWpfAppSample1.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:MyWpfAppSample1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" WindowStartupLocation="CenterOwner">
    <Grid>
        <Button Content="Start" x:Name="btnStart" Width="100" Height="50" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="100,10,0,0" Click="btnStart_Click"/>
        <Button Content="Stop" x:Name="btnStop" Width="100" Height="50" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="210,10,0,0" Click="btnStop_Click"/>
        <Ellipse x:Name="myEllipse" Height="10" Width="10" Fill="Aqua" Margin="400,210,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
    </Grid>
</Window>

我的 XAML 的 c# 代码:

public partial class MainWindow : Window
    {
        private double x;
        private double y;
        private double angle;
        private CancellationTokenSource tokenSource;
        public MainWindow()
        {
            InitializeComponent();            
        }

        
        
        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            tokenSource = new CancellationTokenSource();
            var task = Task.Run(() => MoveMyEllipse(tokenSource.Token));            
        }

        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            tokenSource.Cancel();
        }

        private void MoveMyEllipse(CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                angle = angle + 0.1;
                Invoke(() =>
                {
                    x = myEllipse.Margin.Top + myEllipse.Height * Math.Sin(angle);
                    y = myEllipse.Margin.Left + myEllipse.Width * Math.Cos(angle);
                    myEllipse.Margin = new Thickness(x, y, 0, 0);
                });
                Thread.Sleep(100);
            }
        }
        private void Invoke(Action action)
        {
            Dispatcher?.Invoke(action);
        }
    }

不是你描述的功能,你实现的是什么不清楚。

    public partial class MainWindow : Window
    {
        private double x;
        private double y;
        private double x0 = 250;
        private double y0 = 350;
        private double r = 100;
        private double angle;
        private CancellationTokenSource tokenSource;
        public MainWindow()
        {
            InitializeComponent();
        }



        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            tokenSource = new CancellationTokenSource();
            var task = Task.Run(() => MoveMyEllipse(tokenSource.Token));
        }

        private void btnStop_Click(object sender, RoutedEventArgs e)
        {
            tokenSource.Cancel();
        }

        private void MoveMyEllipse(CancellationToken token)
        {
            while (!token.IsCancellationRequested)
            {
                angle = angle + 0.1;
                Invoke(() =>
                {
                    x = x0 + r * Math.Sin(angle);
                    y = y0 + r * Math.Cos(angle);
                    myEllipse.Margin = new Thickness(x, y, 0, 0);
                });
                Thread.Sleep(100);
            }
        }
        private void Invoke(Action action)
        {
            Dispatcher?.Invoke(action);
        }
    }

我建议看一下变换和动画。

用下面的RenderTransform

<Canvas>
    <Ellipse Height="10" Width="10" Fill="Aqua"
             Canvas.Left="200" Canvas.Top="200"
             RenderTransformOrigin="0.5,0.5">
        <Ellipse.RenderTransform>
            <TransformGroup>
                <TranslateTransform Y="-100"/>
                <RotateTransform x:Name="rotateTransform"/>
            </TransformGroup>
        </Ellipse.RenderTransform>
    </Ellipse>
</Canvas>

您可以像这样设置旋转动画:

var rotateAnimation = new DoubleAnimation(0, 360, TimeSpan.FromSeconds(10));

rotateTransform.BeginAnimation(RotateTransform.AngleProperty, rotateAnimation);