我有两个点数组:
Point [] original;
AND Point [] transformed;
这些转换后的数组只是应用了转换的原始数组的副本。示例:
matrix.Rotate(5f);
matrix.Scale(.8f, 1.1f);
matrix.Translate(30f, 18f);
matrix.TransformPoints(transformed);
- 原始点是已知的。
- 转换值是已知的。
- 应用转换的顺序未知。
如何计算/推断转换顺序?
编辑
- 只有一轮转换。
- 一轮最多可以包含以下三个转换。
- 唯一应用的变换是旋转、缩放和平移的任意组合。
要为其提供一些真实世界的上下文,请考虑使用具有已知兴趣点的图像。你打印图像,扫描它并尝试再次阅读它。该图像包含方向标记,可让我计算扫描过程中应用的变换。
现在,蛮力方法是:
- 阅读扫描的图像。
- 计算扫描图像的旋转。
- 对扫描图像应用旋转。
- 计算旋转图像的比例。
- 对旋转后的图像应用缩放。
- 计算缩放图像的平移。
- 对缩放后的图像应用平移。
您现在可以使用原始点从处理过的图像中读取兴趣点,就好像没有进行任何变换一样。当然,这种方法是昂贵的。一个 500MB 的图像需要在内存中同时至少有两个副本,并且必须使用图形对象进行转换。
这道题的前提是只读取图像一次,计算所有变换并将它们应用于坐标而不是图像本身。使用转换后的坐标读取兴趣点。这就是“转换顺序”问题出现的地方。下面有一些非常有用的答案,我希望这能理清上下文。
最佳答案
对于您正在查看的转换数量,蛮力可能是最简单的方法,而不是尝试对事物进行任何数学分析(我不是 100% 确定这是否可能,但会非常困难)。
对于三种不同的变换(A、B、C),您有六种不同的应用方式。它们是:
- 基本知识
- ACB
- 商业银行
- 商业银行
- 驾驶室
- CBA
因此,对于其中的每一个,请按此顺序将它们应用于您的输入,并检查最终产品是否与您的输出相匹配。
如果您没有特定的转换之一,那么您将只剩下两个顺序选项。这可能是最好的处理方法,只需使用上述六个选项并在缺少的变换所在的位置应用单位矩阵(或无操作)。当然,您还需要检查以防止重复相同的转换顺序。
为了获得最佳性能,您不一定需要检查数组中的所有点 - 如果第一个点不匹配,则无需再检查。您当然会想要检查数组中的所有点是否存在任何匹配项,以确保第一个点转换后的结果不是偶然的。您还可以检查琐碎的转换(例如缩放 1 倍)并将它们视为不存在,因为它们可能出现在任何位置,因此您不妨假设它们在开头(或结尾或中间 - 个人偏好)。
最后还是有歧义的可能。它不太可能,即使是一小组输入点,它也变得非常不可能。这是你需要注意的一点。另请参阅下文,了解更可能出现歧义的特殊情况。
我希望这足以让您朝着正确的方向前进。我无法编写完整的代码,因为我不知道您的转换数据是如何存储的等等。
经过一些关于某些翻译是否可交换的简短讨论(例如做 A 然后 B 与做 B 然后 A 相同)我相信它们不是。在 X 和 Y 的缩放比例相等的特殊情况下,缩放和旋转是可交换的,但此处使用的语法表明缩放有两个因子,我认为它们是 X 和 Y 比例因子。这意味着缩放和旋转在这种情况下不可交换。翻译永远不会交换(想象一下翻译会将点移到原点的微不足道的情况,你会发现它很重要)。
如果 X 轴和 Y 轴上的比例相同,则 Nocturn 关于交换性的观点(在评论中)确实适用。这意味着如果您有这样的比例并且它在旋转旁边,那么您将获得两个可能的有效转换顺序。将无法区分两者。
关于c# - 矩阵/坐标变换顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8834070/