矩阵/坐标转换顺序

时间:2012-01-12 11:07:41

标签: c# matrix coordinates transformation

我有两个要点:

Point [] original;Point [] transformed;

这些变换后的数组只是应用了变换的原始副本。例如:

matrix.Rotate(5f);  
matrix.Scale(.8f, 1.1f);  
matrix.Translate(30f, 18f);  
matrix.TransformPoints(transformed);
  • 原点 ARE 已知。
  • 转换值 ARE 已知。
  • 应用转换的顺序是 NOT 已知。

如何计算/推断变换的顺序?

修改

  • 只有一轮转型。
  • 一轮可以包含最多三个转换,如下所示。
  • 应用的唯一转换是旋转,缩放和平移的任意组合。

为了给它一些真实世界的背景,考虑让图像具有已知的兴趣点。您打印图像,扫描并尝试再次阅读。图像包含方向标记,可以让我计算扫描过程中应用的变换。

现在,蛮力方法将是:

  1. 阅读扫描图像。
  2. 计算扫描图像的旋转。
  3. 在扫描图像上应用旋转。
  4. 计算旋转图像的比例。
  5. 在旋转的图像上应用比例。
  6. 计算缩放图像的平移。
  7. 在缩放图像上应用翻译。
  8. 现在,您可以使用原始点从已处理的图像中读取感兴趣的点,就好像没有转换一样。当然这种方法很昂贵。一个500MB的图像一次需要在内存中至少有两个副本,并且必须使用图形对象进行转换。

    这个问题的前提是只读取一次图像,计算所有变换并将它们应用于坐标而不是图像本身。使用变换的坐标来读取兴趣点。这就是“转换顺序”问题的来源。下面有一些非常有用的答案,我希望这可以清除背景。

2 个答案:

答案 0 :(得分:1)

对于你正在寻找的变形数量,蛮力可能是最简单的方法,而不是试图对事物做任何数学分析(我不是100%确定,如果这是可能的,但这将是非常困难的)。

对于三种不同的变换(A,B,C),您可以通过六种不同的方式应用它们。他们是:

  • ABC
  • ACB
  • BAC
  • BCA
  • CAB
  • CBA

因此,对于每个人,按顺序将它们应用于您的输入并检查最终产品是否与您的输出相匹配。

如果您没有其中一个特定的变换,那么您只剩下两个订单选项。这可以通过仅使用上述六个选项并应用缺失变换所在的单位矩阵(或无运算)来处理。当然,您还需要检查以防止重复相同的转换顺序。

为获得最佳性能,您不一定需要检查阵列中的所有点 - 如果第一个点不匹配则无需再检查。您当然希望检查数组中所有匹配的所有点,以确保它不仅仅是第一个转换点的机会。你也可以检查一些简单的变换(例如比例为1),并将它们视为不存在,因为它们可以出现在任何位置,所以你可以假设它们在开头(或者结束或中间 - 个人)偏好)。

最后,仍然存在歧义的可能性。它不太可能,甚至一小部分输入点变得非常不可能。这是你需要注意的一点。另请参阅下面有关特殊情况的讨论,其中歧义变得更有可能。

我希望这足以让你朝着正确的方向前进。我无法编写完整的代码,因为我不知道您的转换数据是如何存储的等等。

在一些关于某些翻译是否可交换的简短讨论之后(例如,做A然后B做B和做A一样)我相信它们不是。在X和Y的缩放相等的特殊情况下,缩放和旋转是可交换的,但这里使用的语法表明缩放有两个因素,我认为是X和Y缩放因子。这意味着在这种情况下缩放和旋转不可交换。翻译永远不可交换(想象一下翻译会将点移动到原点并且你可以看到它很重要的琐碎案例。)

如果X和Y轴上的比例相同,那么关于交换性的Nocturn点(在评论中)确实适用。这意味着如果您有这样的比例并且它在旋转旁边,那么您将获得两个有效的转换订单。没有办法区分这两者。

答案 1 :(得分:0)

在CG中,持有矩阵Stack是很常见的,即每次对矩阵执行操作(变换,旋转或缩放)时,都会将新矩阵放入堆栈。通过这种方式,您可以追溯到原始状态。