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);
我正在尝试创建一个示例项目以在 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);