WPF Canvas.Left / Canvas.Top旋转时坐标不正确,为什么?

时间:2010-02-12 08:04:47

标签: wpf canvas rotation

我有一个奇怪但很大的问题。  我试图让用户在画布上移动/旋转一些矩形。我基于机制操作Canvas.Left / Canvas.Top属性为move,RenderTransform.Rotate用于旋转。我只需要在0/90/180/270角度旋转。

问题是在0角度旋转处放置在坐标0.0处的矩形显示正常,但是在90°角度旋转的0.0处的相同矩形显示其他坐标处的元素而不是0.0。正如我所看到的,在旋转为0或180的情况下坐标总是正确的,但在90/270的情况下则是错误的。  设置的坐标与用户看到的坐标之间的差异与高度和宽度之间的差异有关。

之前有没有人遇到过这类问题?

谢谢你,  丹尼尔

编辑:

当然,这是一些xaml:

  

    <Canvas 
        Height="500" 
        Width="500"
        Background="Green"

        <Rectangle 
            Canvas.Left="0" 
            Canvas.Top="0"
            Height="50"
            Width="100"
            RenderTransformOrigin="0.5,0.5"
            Fill="Red"

            <Rectangle.RenderTransform>
                <RotateTransform 
                Angle="90"
                />
            </Rectangle.RenderTransform>
        </Rectangle>
        <Rectangle 
            Canvas.Left="0" 
            Canvas.Top="0"
            Height="50"
            Width="100"
            RenderTransformOrigin="0.5,0.5"
            Fill="RoyalBlue"

            <Rectangle.RenderTransform>
                <RotateTransform 
                Angle="0"
                />
            </Rectangle.RenderTransform>
        </Rectangle>
    </Canvas> 
</Grid>

如您所见,蓝色矩形似乎正确放置(0,0)但红色矩形显示在不同坐标处,即使它返回stil 0,0。

我发现了公式:

displayPointX = Canvas.Left + height / 2 - width / 2

diaplayPointY = Canvas.Top + height / 2 - width / 2

3 个答案:

答案 0 :(得分:3)

Daniell,大家告诉你的是正确的。如果你有一个矩形,并且你将原点设置为0.5,0.5,这意味着“围绕这个物体的质心旋转”,所以如果你旋转90或270度,当然它看起来就像你看到的那样。 / p>

如果您希望矩形旋转90度并仍然在左上角结束,您必须旋转90,然后在X和Y中平移以使角落与0,0匹配,或者您需要围绕不同的中心(如0,0)旋转,仅在X中进行平移。

以下是一个例子:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Canvas Height="500" Width="500" Background="Green">
        <Rectangle Canvas.Left="0" Canvas.Top="0" Height="50" Width="100" RenderTransformOrigin="0.5,0.5" Fill="Red">
            <Rectangle.RenderTransform>
              <TransformGroup>
                <RotateTransform Angle="90" />
                <TranslateTransform X="-25" Y="25" />
              </TransformGroup>
            </Rectangle.RenderTransform>
        </Rectangle>
        <Rectangle Canvas.Left="0" Canvas.Top="0" Height="50" Width="100" RenderTransformOrigin="0.5,0.5" Fill="RoyalBlue">
            <Rectangle.RenderTransform>
                <RotateTransform Angle="0" />
            </Rectangle.RenderTransform>
        </Rectangle>
    </Canvas> 
</Page>

如果您解释了您真正想要做的事情,也许最好。同样奇怪的是,你说0和180很好,因为角落与0,0匹配,但是你的形状是旋转的,我们不知道保留方向对你是否重要。

答案 1 :(得分:2)

您描述的行为发生在以下条件下:

  1. 您的画布是非矩形的,
  2. 您的RenderTransformOrigin为“0.5,0.5”和
  3. 您为RenderTransform使用RotateTransform
  4. 你看到它的原因是因为一个围绕其中心旋转180度的矩形具有完全相同的边界,但旋转90度或270度的矩形则没有。想象一个宽而又瘦的矩形旋转而你很容易看出这是如此。

    旋转90度或270度时,角落不再与容器匹配。

    有许多解决方案可供选择:

    • 使容器完全正方形
    • 将画布的大小(翻转宽度和高度)更改为90和270转
    • 将ScaleTransform与您的RotateTransform结合使用,可以在一个方向上按w / h缩放画布,并在旋转为90或270度时按下h / w,以便画布拉伸以适应新的矩形
    • 将TranslateTransform添加到RotateTransform,每当旋转为90度或270度时,将坐标系移动w-h和h-w
    • 计算一个新的RenderTransformOrigin以使角落出现在你想要的地方

答案 2 :(得分:1)

坐标变化的原因是画布的坐标系与画布一起旋转。

http://msdn.microsoft.com/en-us/library/system.windows.media.rotatetransform.aspx州:

  

使用RotateTransform时,   意识到转型   旋转坐标系   关于点的特定对象(0,   0)。

假设您正在围绕正方形的质心旋转,当您旋转90度(顺时针方向,RotateTransform方向认为是正方向)时,(0,0)指的是屏幕的右上角,180指的是在右下角,270表示左下角,0表示正如预期的那样左上角。