好的,所以我有一个要围绕其左上角旋转的 Image 对象。我设置了一个 'X' 度的 RotateTransform。我的图像的边距设置为 (400,400,0,0)。这将它集中在画布上。
问题是当我应用不同的旋转角度时,图像会向右和向下移动。看帖子,我现在明白为什么会这样了。旋转变换计算出一个边界矩形,因此如果您旋转图像,它将有一个更大的边界矩形。边距应用于该边界矩形,这会导致实际图像随着角度的变化而向下和向右移动。
我想要的是图像的左上角在我的画布上始终精确地位于 (400,400) 处,并且图像围绕该点旋转。
我已经做了一些计算,可以通过移动左边距和上边距来让它表现出来,但只能使用以下等式在象限 1 和 4(0-90 度)和(270-360 度)中得到正确的计算:
对于 0-90 度:(只需更改边距的顶部部分。所需边距为 (400,400,0,0) Margin=(400-sin(angle)*Image.Height, 400, 0, 0);
对于 270-360 度:(只需更改页边距的 TOP 部分。所需页边距为 (400,400,0,0) Margin=(400, 400 + sin(angle)*Image.Width, 0, 0);
我已经尝试使用 RotateTransform.Transform(point) 和 Image.TranslatPoint(point) 但似乎无法让它们工作。
有人对我有什么建议吗?
我想如果我能在任何给定时间弄清楚图像的绑定矩形是什么,我就可以找出它的宽度/高度和我的图像宽度/高度之间的差异,并使用它来适当地移动边距。
我已经整理了一个小应用程序来显示我的问题。运行时,应用程序在我希望矩形左上角的位置显示一个红点。我将其简化为使用网格而不是图像。在屏幕的左上角,有一个文本框,您可以在其中指定旋转角度。文本框的右侧是两个重复按钮,如果您单击并按住它们,它们会增加和减少角度。请注意,当您更改角度时,网格的左上角如何远离红点。我希望它表现得就像你在左上角放了一个大头针,然后围绕大头针旋转它,而不从角落开始的点移动。
谢谢你的帮助。
这是示例应用程序的代码:
xml:
<Window x:Class="RenderTransformTester.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="900" Width="900">
<Canvas x:Name="_canvas">
<Grid x:Name="_gridImage" Width="400" Height="200" Canvas.Left="400" Canvas.Top="400" Background="Navy">
<Grid.LayoutTransform>
<RotateTransform Angle="45" CenterX="0" CenterY="0"/>
</Grid.LayoutTransform>
</Grid>
<Ellipse Fill="Red" Width="20" Height="20" Margin="390,390,0,0"/>
<TextBox x:Name="_textBoxAngle" Width="70" Height="30" TextChanged="_textBoxAngle_TextChanged" Text="0"/>
<RepeatButton x:Name="_buttonUp" Width="30" Height="15" Margin="70,0,0,0" Click="_buttonUp_Click"/>
<RepeatButton x:Name="_buttonDown" Width="30" Height="15" Margin="70,15,0,0" Click="_buttonDown_Click"/>
</Canvas>
</Window>
代码隐藏:
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace RenderTransformTester
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
static double _left = -1;
static double _top = -1;
public MainWindow()
{
InitializeComponent();
}
private void _textBoxAngle_TextChanged(object sender, TextChangedEventArgs e)
{
int angle;
int.TryParse(_textBoxAngle.Text, out angle);
angle += 720;
angle %= 360;
_gridImage.LayoutTransform = new RotateTransform(angle, 0, 0);
}
private void _buttonUp_Click(object sender, RoutedEventArgs e)
{
int angle;
int.TryParse(_textBoxAngle.Text, out angle);
angle++;
angle = angle % 360;
_textBoxAngle.Text = angle.ToString();
}
private void _buttonDown_Click(object sender, RoutedEventArgs e)
{
int angle;
int.TryParse(_textBoxAngle.Text, out angle);
angle--;
angle = angle % 360;
_textBoxAngle.Text = angle.ToString();
}
private static double RadiansToDegrees(double radians)
{
return radians * 180 / Math.PI;
}
private static double DegreesToRadians(double degrees)
{
return degrees * Math.PI / 180;
}
}
}