13

参考我目前正在构建的这个编程游戏。

替代文字 http://img12.imageshack.us/img12/2089/shapetransformationf.jpg

为了在 WPF 中翻译画布,我使用了两种形式:(TranslateTransform移动它)和RotateTransform(旋转它)[相同的孩子 TransformationGroup]

当画布不旋转(或旋转 90 度,因为它是相同的)时,我可以很容易地获得画布的左上角 x,y 坐标,但我面临的问题是左上角(和其他 3 个点)坐标。

这是因为当应用 aRotateTransform时,TranslateTransform'sXY属性没有改变(因此仍然表明正方形的左上角就像虚线正方形(来自图像)

画布从其中心旋转,这就是它的原点。

那么如何在旋转后获得 4 个点的“新”x 和 y 坐标

[更新]

替代文字 http://img25.imageshack.us/img25/8676/shaperotationaltransfor.jpg

我找到了一种在旋转后找到左上角坐标的方法(正如您从新图像中看到的那样),方法是将 OffsetX 和 OffsetY 从旋转添加到起始 X 和 Y 坐标。

但是我现在无法确定其余的坐标(其他 3 个)。

有了这个旋转的形状,我怎样才能算出剩余 3 个角的 x 和 y 坐标?

[编辑]

第二张图像中的点不是准确和精确的点。我在脑海中做出了估计。

[更新]解决方案:

首先,我要感谢Jason S的那篇冗长且内容丰富的帖子,他在其中描述了整个过程背后的数学;通过阅读您的帖子并尝试这些价值观,我当然学到了很多东西。

但我现在找到了一个代码片段(感谢EugeneZ提到的TransformBounds),它完全符合我的要求:

public Rect GetBounds(FrameworkElement of, FrameworkElement from)
{
    // Might throw an exception if of and from are not in the same visual tree
    GeneralTransform transform = of.TransformToVisual(from);

    return transform.TransformBounds(new Rect(0, 0, of.ActualWidth, of.ActualHeight));
} 

参考:http ://social.msdn.microsoft.com/Forums/en-US/wpf/thread/86350f19-6457-470e-bde9-66e8970f7059/

4

5 回答 5

16

如果我理解你的问题是正确的:

given:
shape has corner (x1,y1), center (xc,yc)
rotated shape has corner (x1',y1') after being rotated about center

desired:
how to map any point of the shape (x,y) -> (x',y') by that same rotation

以下是相关方程式:

(x'-xc) = Kc*(x-xc) - Ks*(y-yc)
(y'-yc) = Ks*(x-xc) + Kc*(y-yc)

其中Kc=cos(theta)和是逆时针旋转的角度Ks=sin(theta)theta(验证:如果 theta=0 则保持坐标不变,否则如果 xc=yc=0,则将 (1,0) 映射到 (cos(theta),sin(theta)) 并将 (0,1) 映射到 (- sin(theta), cos(theta)) . 警告:这是用于坐标系,其中 (x,y)=(1,1) 位于右上象限。对于您位于右下象限的坐标系,theta 将是顺时针旋转的角度,而不是逆时针旋转的角度。)

如果您知道矩形的坐标与 xy 轴对齐,则 xc 将只是两个 x 坐标的平均值,而 yc 将只是两个 y 坐标的平均值。(在您的情况下,它是 xc=75,yc=85。)

如果您知道 theta,您现在就有足够的信息来计算新坐标。如果你不知道theta,你可以解出Kc,Ks。这是您的示例的相关计算:

(62-75) = Kc*(50-75) - Ks*(50-85)
(40-85) = Ks*(50-75) + Kc*(50-85)

-13 = -25*Kc + 35*Ks = -25*Kc + 35*Ks
-45 = -25*Ks - 35*Kc = -35*Kc - 25*Ks

这是一个可以求解的线性方程组(读者练习:在 MATLAB 中它是:

[-25 35;-35 -25]\[-13;-45]

产生,在这种情况下,Kc=1.027, Ks=0.3622 这没有意义(K 2 = Kc 2 + Ks 2对于纯旋转应该等于 1;在这种情况下它是 K = 1.089)所以它不是围绕矩形中心的纯旋转,这就是您的绘图所指示的。它似乎也不是关于原点的纯粹旋转。要检查,请使用勾股定理比较旋转前后到旋转中心的距离,d 2 = deltax 2 + deltay 2. (绕xc=75,yc=85,前距离为43.01,后距离为46.84,比值为K=1.089;绕原点旋转时,前距离为70.71,后距离为73.78,比值为1.043。我可以相信 1.01 或更低的比率会因坐标舍入为整数而产生,但这显然大于舍入误差)

所以这里有一些缺失的信息。你是怎么得到数字(62,40)的?

然而,这是旋转背后数学的基本要点。

编辑:啊哈,我没有意识到它们是估计值。(虽然非常接近现实!)

于 2009-02-26T15:38:40.687 回答
8

我使用这种方法:

Point newPoint = rotateTransform.Transform(new Point(oldX, oldY));

其中 rotateTransform 是我工作并设置 Angle...等的实例。

于 2009-04-23T11:27:43.720 回答
3

查看 GeneralTransform.TransformBounds() 方法。

于 2009-02-27T04:46:11.230 回答
1

我不确定,但这是你要找的 - 笛卡尔坐标系中点的旋转: 链接

于 2009-02-24T14:05:46.917 回答
1

您可以在 Point 上使用具有相同转换的 Transform.Transform() 方法来获取应用这些转换的新点。

于 2009-02-24T15:34:06.533 回答