【问题标题】:WPF: Getting new coordinates after a RotationWPF:旋转后获取新坐标
【发布时间】:2010-10-09 13:42:57
【问题描述】:

参考this programming game我目前正在建设中。

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

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

当画布不旋转(或旋转 90 度,因为它是相同的)时,我可以轻松获取画布的左上角 x,y 坐标,但我面临的问题是左上角(以及另一个3 点)坐标。

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

Canvas 正在从它的中心旋转,这就是它的原点。

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

[更新]

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

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

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

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

[编辑]

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

[更新]解决方案:

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

但我现在找到了一个代码 sn-p(感谢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/

【问题讨论】:

标签: wpf math transform


【解决方案1】:

我用这个方法:

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

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

【讨论】:

    【解决方案2】:

    查看 GeneralTransform.TransformBounds() 方法。

    【讨论】:

      【解决方案3】:

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

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

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

      不过,这是旋转背后数学的基本要点。

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

      【讨论】:

      • 我通过将起始 X 和 Y 坐标添加到从旋转矩阵检索到的 OffsetX 和 OffsetY 得到这些数字。因此,如果 OffsetX 为 12,而“未旋转”形状的 X 为 50,则新的 X(旋转后)为 62。Y 坐标也是如此
      • 顺便说一句,只是为了澄清一下:我在图像中放置的点不是真实的点,甚至偏移量也不是真实的;我只是为图像弥补了它们
      • 我认为这些值是一个粗略的估计,他以插图为例。
      • 哦,好的。那么,这是一个很好的估计;您将围绕中心的半径保持在其预旋转值的 10% 以内。 :)
      【解决方案4】:

      您可以在 Point 上使用 Transform.Transform() 方法进行相同的转换,以获得应用这些转换的新点。

      【讨论】:

      • Transform() 接受 Point 变量。该点的 x 和 y 应该是什么?
      • 参考您更新的问题 Transform() 方法将完全满足您对任何点(包括正方形的其他角)的需要。
      • "你可以使用 Transform.Transform()"
      • 使用与对象相同的变换(即,在这种情况下,使用具有旋转和平移变换的 TransformGroup 实例)
      【解决方案5】:

      我不确定,但这就是你要找的 - 在笛卡尔坐标系中旋转一个点: link

      【讨论】:

      • 会看看。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-09
      • 2013-05-10
      • 1970-01-01
      • 2021-08-12
      • 2021-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多