我已经完成了大部分的工作,但问题出现在我的数学计算中。我希望箭头(用户控件)可以旋转并指向鼠标,当它在WPF画布上单击并拖动时。我已经弄清楚如何计算弧度的角度,但是当我应用该值时,看起来效果不尽如人意。
当前状态
目标状态
关注的主要代码片段如下...
![enter image description here](https://istack.dev59.com/WMJKe.webp)
![enter image description here](https://istack.dev59.com/pcsgr.webp)
![enter image description here](https://istack.dev59.com/xObUy.webp)
private double Angle(Point origin, Point target)
{
//Calculate the distance from the square to the mouse's X and Y position
var radians = Math.Atan2(origin.Y - target.Y, origin.X - target.X);
var degrees = radians * (180 / Math.PI) - 90;
Console.WriteLine(target + "--" + origin + "--" + degrees);
return degrees;
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
var canvas = (Canvas)sender;
if (e.LeftButton == MouseButtonState.Pressed)
{
if (_followMouse)
{
// Get Cursor Position
Point _targetPoint = e.GetPosition(this);
// Follow mouse
foreach (UIElement element in canvas.Children)
{
Arrow arrow = (Arrow)element;
// example 1
double x = Canvas.GetTop(arrow) + arrow.ActualWidth / 2.0;
double y = Canvas.GetLeft(arrow) + arrow.ActualHeight / 2.0;
Point _originPoint = new Point(x,y);
arrow.rotateTransform.Angle = Angle(_originPoint, _targetPoint);
}
}
}
}
以下是整个项目的代码...
MainWindow.xaml.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 WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
bool _followMouse;
private void Canvas_MouseDown(object sender, MouseButtonEventArgs e)
{
_followMouse = true;
}
private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
{
_followMouse = false;
}
private double Angle(Point origin, Point target)
{
//Calculate the distance from the square to the mouse's X and Y position
var radians = Math.Atan2(origin.Y - target.Y, origin.X - target.X);
var degrees = radians * (180 / Math.PI) - 90;
Console.WriteLine(target + "--" + origin + "--" + degrees);
return degrees;
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
var canvas = (Canvas)sender;
if (e.LeftButton == MouseButtonState.Pressed)
{
if (_followMouse)
{
// Get Cursor Position
Point _targetPoint = e.GetPosition(this);
// Follow mouse
foreach (UIElement element in canvas.Children)
{
Arrow arrow = (Arrow)element;
// example 1
double x = Canvas.GetTop(arrow) + arrow.ActualWidth / 2.0;
double y = Canvas.GetLeft(arrow) + arrow.ActualHeight / 2.0;
Point _originPoint = new Point(x,y);
arrow.rotateTransform.Angle = Angle(_originPoint, _targetPoint);
}
}
}
}
}
}
MainWindow.xaml
<Window x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300"
WindowStartupLocation="CenterScreen">
<Canvas
MouseDown="Canvas_MouseDown"
MouseUp="Canvas_MouseUp"
MouseMove="Canvas_MouseMove"
Background="LightBlue">
<local:Arrow Canvas.Left="158" Canvas.Top="43"/>
<local:Arrow Canvas.Left="38" Canvas.Top="108"/>
<local:Arrow Canvas.Left="158" Canvas.Top="170"/>
<local:Arrow Canvas.Left="78" Canvas.Top="158"/>
<local:Arrow Canvas.Left="196" Canvas.Top="108"/>
<local:Arrow Canvas.Left="78" Canvas.Top="53"/>
</Canvas>
</Window>
Arrow.xaml
<UserControl x:Class="WpfApplication1.Arrow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50">
<Grid>
<Path Data="M 0 4 L 4 0 L 8 4 Z" RenderTransformOrigin="0.5,0.5"
Width="50"
Height="50"
Stretch="Uniform"
Fill="Red">
<Path.RenderTransform>
<RotateTransform x:Name="rotateTransform"/>
</Path.RenderTransform>
</Path>
</Grid>
</UserControl>