RenderTransformOrigin
указывает относительное происхождение любого RenderTransform
, примененного к B. Установка его сама по себе не меняет положение 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;
}