我试图在A处拖动圆圈,使其相对于隐藏的中心元素B生成一个角度。
我正在使用MouseEventArgs.GetPosition(IInputElement relativeTo)
,所以:
Point p = args.GetPosition(B)
尽管在B上设置了RenderTransformOrigin 0.5,0.5,但我得到的是相对于B左上角的点,而不是它的中心。
我知道我可以手动计算正确的偏移量:Easiest way to get the angle of mouse position in WPF relative to the center of a circle
答案 0 :(得分:3)
RenderTransformOrigin
指定在B上应用的任何RenderTransform
的相对来源。设置它本身不会改变B的位置,因此它也不会影响e.GetPosition(B)
。
e.GetPosition(B)
是“给我在B的坐标空间中的鼠标位置。无论你如何改变这个坐标空间(通过应用渲染变换),相对来说,B的中心将远离在它的中间,它将取决于它的大小,所以你需要计算它的中心。
同样,在计算角度时,您需要确保使用同一个坐标空间。此代码会在A
上轮换Centre
,无论它们的位置如何:
Point? dragStart;
Point centrePoint;
private void A_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var handle = sender as FrameworkElement;
var parent = handle.Parent as FrameworkElement;
dragStart = e.GetPosition(parent);
var rotateCentre = Centre.TransformToVisual(A).Transform(new Point(Centre.ActualWidth / 2, Centre.ActualHeight / 2));
A.RenderTransform = new RotateTransform { CenterX = rotateCentre.X, CenterY = rotateCentre.Y };
centrePoint = Centre.TransformToVisual(handle.Parent as FrameworkElement).Transform(new Point(Centre.ActualWidth / 2, Centre.ActualHeight / 2));
handle.CaptureMouse();
}
private void A_MouseMove(object sender, MouseEventArgs e)
{
if (dragStart != null)
{
var current = e.GetPosition((sender as FrameworkElement).Parent as FrameworkElement);
var angle = RadiansToDegrees(AngleAtoB(dragStart.Value, current, centrePoint));
(A.RenderTransform as RotateTransform).Angle = angle;
}
}
private void A_LostMouseCapture(object sender, MouseEventArgs e)
{
dragStart = null;
}
private void A_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
(sender as FrameworkElement).ReleaseMouseCapture();
}
internal static double AngleWithHorizontal(Point point, Point origin)
{
return Math.Atan2(point.Y - origin.Y, point.X - origin.X);
}
internal static double AngleAtoB(Point a, Point b, Point origin)
{
return AngleWithHorizontal(b, origin) - AngleWithHorizontal(a, origin);
}
private const double Const180OverPi = 180 / Math.PI;
internal static double RadiansToDegrees(double angleInDegrees)
{
return angleInDegrees * Const180OverPi;
}