参考我目前正在构建的这个编程游戏.
alt text http://img12.imageshack.us/img12/2089/shapetransformationf.jpg
要在WPF中翻译Canvas,我使用两个表单:( TranslateTransform
移动它)和RotateTransform
(旋转它)[ 相同的子节点 TransformationGroup
]
我可以很容易地获得画布的左上角x,y坐标,当它没有旋转(或旋转90度,因为它将是相同的),但我面临的问题是左上角(和其他3点)坐标.
这是因为当RotateTransform
应用a 时,TranslateTransform
's X
和Y
属性不会改变(因此仍然表明正方形的左上角就像点状正方形(来自图像)
Canvas正在从它的中心旋转,因此它就是它的起源.
那么如何在旋转后获得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的提及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/
如果我理解你的问题:
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)?
然而,这是轮换背后数学的基本要点.
编辑:啊哈,我没有意识到他们是估计.(虽然很接近现实!)
我用这个方法:
Point newPoint = rotateTransform.Transform(new Point(oldX, oldY));
其中rotateTransform是我工作的实例,并设置Angle ...等.