矩阵/坐标转换顺序

我有两个要点:

Point [] original; AND Point [] transformed;

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

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

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

编辑

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

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

现在,蛮力方法将是:

  1. 读取扫描图像。
  2. 计算扫描图像的旋转。
  3. 在扫描图像上应用旋转。
  4. 计算旋转图像的比例。
  5. 在旋转的图像上应用比例。
  6. 计算缩放图像上的平移。
  7. 在缩放图像上应用翻译。

您现在可以使用原始点从已处理图像中读取感兴趣的点,就像没有变换一样。 当然这种方法很昂贵。 500MB图像一次需要在内存中至少有两个副本,并且必须使用图形对象进行转换。

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

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

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

  • ABC
  • ACB
  • BAC
  • BCA
  • 出租车
  • CBA

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

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

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

最后,仍然存在模棱两可的可能性。 它不太可能,即使只有一小组输入点,它也变得不太可能。 这是你需要注意的一点。 另请参阅下面有关特殊情况的讨论,其中歧义变得更有可能。

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

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

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

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