参考我目前正在制作的this programming game。
alt text http://img12.imageshack.us/img12/2089/shapetransformationf.jpg
要在WPF中翻译Canvas,我使用两个表单:TranslateTransform
(移动它)和RotateTransform
(旋转它)[相同的孩子 TransformationGroup
]
当画布没有旋转时(或者旋转90度,因为它会是相同的),我可以很容易地获得画布的左上角x,y坐标,但我面临的问题是左上角(和另一个) 3分)坐标。
这是因为当应用RotateTransform
时,TranslateTransform
的{{1}}和X
属性不会更改(因此仍然表示左上角正方形就像虚线(从图像中)
“画布”正从其中心旋转,因此这是它的起源。
那么如何在旋转后获得4个点的“新”x和y坐标?
[UPDATE]
alt text http://img25.imageshack.us/img25/8676/shaperotationaltransfor.jpg
通过将旋转中的OffsetX和OffsetY添加到起始X和Y,我找到了一种在旋转后找到左上角坐标的方法(从新图像中可以看到)坐标。
但我现在无法弄清楚其余的坐标(其他3)。
使用此旋转形状,如何计算其余3个角的x和y坐标?
[编辑]
第二张图片中的点不准确且精确点。我在脑海中估计了这一点。
[更新]解决方案:
首先,我要感谢Jason S这篇冗长且内容丰富的文章,其中他描述了整个过程背后的数学;通过阅读你的帖子和尝试价值观,我当然学到了很多东西。
但我现在找到了一个代码片段(感谢EugeneZ提到Y
),它完全符合我的要求:
TransformBounds
参考:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/86350f19-6457-470e-bde9-66e8970f7059/
答案 0 :(得分:15)
如果我理解你的问题:
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将是顺时针旋转而不是逆时针旋转的角度。)
如果您知道矩形的坐标与x-y轴对齐,则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
这是一个可以解决的system of linear equations(为读者练习:在MATLAB中它是:
[-25 35;-35 -25]\[-13;-45]
在这种情况下产生Kc = 1.027,Ks = 0.3622这是没有意义的(K 2 = Kc 2 + Ks 2 对于纯旋转,sup>应该等于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)?
然而,这是轮换背后数学的基本要点。
编辑:啊哈,我没有意识到他们是估计。 (尽管很接近现实!)
答案 1 :(得分:7)
我使用这种方法:
Point newPoint = rotateTransform.Transform(new Point(oldX, oldY));
其中rotateTransform是我工作的实例,并设置Angle ... etc。
答案 2 :(得分:3)
查看GeneralTransform.TransformBounds()方法。
答案 3 :(得分:1)
我不确定,但这就是你要找的东西 - 在笛卡尔坐标系中旋转一个点: link
答案 4 :(得分:1)
您可以在Point上使用具有相同变换的Transform.Transform()方法来获取应用这些变换的新点。