1

好的,所以我有一个要围绕其左上角旋转的 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;
        }
    }
}
4

2 回答 2

2

你想要一个 TransformGroup 中的 TranslateTransform

<Grid>
    <Grid.RenderTransform>
        <TransformGroup>
            <RotateTransform Angle="45" CenterX="0" CenterY="0" />
            <TranslateTransform X="400" Y="400" />
        </TransformGroup>
    </Grid.RenderTransform>
</Grid>
于 2012-05-21T18:40:10.817 回答
1
  1. 不要Margin用于这种定位,使用附加Canvas属性,即Canvas.Left等。
  2. 您也可以使用 aTransformGroup并应用 aTranslateTransform和 a RotateTransform,大概旋转应该在翻译之前完成。
于 2012-05-21T17:01:25.790 回答