如何在WPF中围绕特定点旋转、平移和缩放控制对象

6
我有一个自定义控件,它是一个矩形,里面有一些细节,但它本质上是一个矩形。
我有一个中心点(X,Y),我称之为“重心”,它“代表”该点。这意味着当我将新位置设置给对象时,我希望该点位于设置的位置。当我旋转对象时,我需要它围绕此点旋转。当我缩放对象时,该点必须保持在设置前的位置。只有对象的大小必须更改。
例如,为了简单起见,假设我有一个10x10的正方形。我将重心设置在正方形的正中心:(5,5)。然后我将对象的位置设置为(100,100)。那么,正方形将位于:
(95,95),(105,95),(105,105),(95,105),这意味着其中心将位于所需位置。
如果我使用值2缩放正方形,则新的4个点的位置将是:
(90,90),(110,90),(110,110),(90,110),这意味着其中心仍将位于所需位置。
如果我将其旋转45度,则它将围绕其中心旋转,位置如下:
(92.93,92.93),(107.07,92.93),(107.07,107.07),(92.93,107.07)
如何在WPF中进行所有这些变换,使其中心完全可配置且对程序透明?我只想设置比例、位置、旋转角度和中心以正确绘制它。
谢谢!

首先,您需要对 -X、-Y 进行平移,使重心位于 0,0。然后进行旋转和缩放。最后再进行一次 X、Y 的平移,使点回到起始位置。很抱歉我只能列出步骤,而无法发布任何代码。现在已经很晚了。 - Steve
我觉得我明白你的意思,但如果你能发布一些代码,确保我正确理解了它,那将非常有帮助。 - jpnavarini
我认为在RenderTransformOrigin中定义中心时,WPF翻译会自动完成此操作。 - jpnavarini
2个回答

11

您可以相对于对象的大小设置变换的中心点。如果您想围绕对象的左上角旋转,则值为0, 0。如果要在底部右侧位置的10%之后旋转,则应使用1.1, 1.1

对于RotationTranforms,该属性称为RenderTransformOrigin。在Blend中,属性中有一个“Transform”组。如果展开它,RenderTransform具有一组选项卡。第5个选项卡是中心点。

以下是一些示例XAML:

<TextBlock Text="TextBlock" RenderTransformOrigin="-0.5,-0.5" Background="#FFA1BBF9" Margin="50" Width="100" Height="100">
    <TextBlock.RenderTransform>
        <TransformGroup>
            <ScaleTransform ScaleX="2"/>
            <SkewTransform/>
            <RotateTransform Angle="30"/>
            <TranslateTransform/>
         </TransformGroup>
     </TextBlock.RenderTransform>
</TextBlock>

translateTransform 不使用 origin 属性,对吧?我的意思是,即使将 RenderTransformOrigin 设置为 TextBlock 的中心,我们要转换到的点仍将是左上角。 - jpnavarini
@jpnavarini 在上面的代码中,翻译发生在其他转换之后。将翻译放在第一位会使其与原文无关。您还可以使用对齐和边距或将其放在画布中(使用Canvas.Left和Canvas.Top)。 - sharoz

3

旋转任何控件到原点

// rotated object
      Rectangle r = new Rectangle();
                r.Fill = Brushes.Blue;
                r.Stroke = Brushes.Yellow;
                r.Width = 200;
                r.Height = 100;      



//rotate transform
 RotateTransform rt = new RotateTransform();

            r.RenderTransform = rt;

            //origin for object
            r.RenderTransformOrigin = new Point(.5,.5);

            DoubleAnimation anim3 = new DoubleAnimation(0, 360, TimeSpan.FromSeconds(.5));
            anim3.RepeatBehavior = RepeatBehavior.Forever;
           rt.BeginAnimation(RotateTransform.AngleProperty, anim3);
  grid1.Children.Add(r);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接