WPF:旋转后获取新坐标

标签 wpf math transform

引用this programming game我目前正在 build 。

alt text http://img12.imageshack.us/img12/2089/shapetransformationf.jpg

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

当 Canvas 未旋转(或旋转 90 度,因为它是相同的)时,我可以轻松获得 Canvas 的左上角 x,y 坐标,但我面临的问题是获得左上角(和其他 3 个点)坐标。

这是因为当 RotateTransform应用,TranslateTransformXY属性没有改变(因此仍然表明正方形的左上角类似于虚线正方形(来自图像)

Canvas 从它的中心旋转,所以这是它的原点。

所以如何在旋转后获得 4 个点的"new"x 和 y 坐标 ?

[更新]

alt text http://img25.imageshack.us/img25/8676/shaperotationaltransfor.jpg

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

但是我现在无法弄清楚其余的坐标(其他 3 个)。

使用此旋转形状,我怎样才能找出其余 3 个角的 x 和 y 坐标?

[编辑]

第二张图片中的点 不是准确和准确的点 .我用脑子里的估计算出了这些点。

[更新] 解决方案:

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

但我现在找到了一个代码片段(感谢 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 将是顺时针旋转而不是逆时针旋转的角度。)

如果您知道矩形的坐标与 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 这没有意义(对于纯旋转,K2 = Kc2 + Ks2 应该等于 1;在这种情况下,它是 K = 1.089)所以它不是关于矩形中心,这就是您的绘图所指示的。它似乎也不是关于原点的纯粹旋转。要检查,请使用勾股定理比较旋转前后与旋转中心的距离,d2 = deltax2 + deltay2。 (绕xc=75,yc=85旋转,前距离43.01,后距离46.84,比例K=1.089;绕原点旋转,前距离70.71,后距离73.78,比例1.043。I可以相信 1.01 或更小的比率会因坐标舍入到整数而产生,但这显然大于舍入误差)

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

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

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

关于WPF:旋转后获取新坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/581837/

相关文章:

math - 如何找到给定行中的最小数字?

javascript - 重置多个元素的拖动

python - Duplicated() 函数作为 bool 索引生成与 drop_duplicates 不同的结果

c# - 通用智能感知的全新完整实现

java - 给定整数集的子集,其和为常量 N : Java

c# - Task.Factory.StartNew 抛出异常

c++ - 根据两个角度之间的差异更改值

xml - 尝试创建通用 XSL 以允许略有不同的 XML 格式

c# - 从 CollectionView 中获取过滤后的项目

c# - 更新 WPF MVVM 中的 UI 元素