Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 矩阵/坐标变换阶_C#_Matrix_Coordinates_Transformation - Fatal编程技术网

C# 矩阵/坐标变换阶

C# 矩阵/坐标变换阶,c#,matrix,coordinates,transformation,C#,Matrix,Coordinates,Transformation,我有两组点: 点[]原件和点[]转换 这些转换后的数组只是应用了转换的原始数组的副本。例如: matrix.Rotate(5f); matrix.Scale(.8f, 1.1f); matrix.Translate(30f, 18f); matrix.TransformPoints(transformed); 原始点是已知的 变换值是已知的 应用转换的顺序未知 如何计算/推断变换的顺序 编辑 只有一轮转型 一轮最多可以包含三个转换,如下所示 应用的唯一变换是旋转、缩放和平移的

我有两组点:

点[]原件
点[]转换

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

matrix.Rotate(5f);  
matrix.Scale(.8f, 1.1f);  
matrix.Translate(30f, 18f);  
matrix.TransformPoints(transformed);
  • 原始点是已知的
  • 变换值是已知的
  • 应用转换的顺序未知
如何计算/推断变换的顺序

编辑

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

给它一些真实世界的上下文,考虑有一个具有已知兴趣点的图像。您可以打印图像,扫描图像,然后再次尝试读取。该图像包含方向标记,允许我计算扫描过程中应用的变换

现在,暴力手段将是:

  • 读取扫描图像
  • 计算扫描图像上的旋转
  • 对扫描的图像应用旋转
  • 计算旋转图像上的比例
  • 在旋转的图像上应用缩放
  • 计算缩放图像上的平移
  • 在缩放图像上应用平移
  • 现在,您可以使用原始点从处理后的图像中读取感兴趣的点,就像没有变换一样。当然,这种方法是昂贵的。500MB的图像一次需要在内存中至少有两个副本,并且必须使用图形对象进行转换


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

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

    对于您正在查看的转换数量,蛮力可能是最简单的方法,而不是尝试对事物进行任何数学分析(我不100%确定这是否可能,但这将非常困难)

    对于三种不同的变换(A、B、C),有六种不同的方法可以应用它们。它们是:

    • ABC
    • ACB
    • 美国银行
    • BCA
    • 驾驶室
    • CBA
    因此,对于每一个应用程序,都要按照这个顺序将它们应用到您的输入中,并检查最终产品是否与您的输出匹配

    如果没有一个特定的变换,那么只剩下两个顺序选项。这可以通过使用上述六个选项并在缺少变换的位置应用单位矩阵(或无运算)来最好地解决。当然,还需要进行检查以防止重复相同的变换顺序

    为了获得最佳性能,您不必检查阵列中的所有点-如果第一个点不匹配,则无需再检查。当然,您需要检查数组中的所有点是否存在匹配,以确保第一个点的转换并非偶然。此外,您还可以检查琐碎的转换(例如按因子1进行缩放),并将其视为不存在,因为它们可能出现在任何位置,因此您不妨假设它们位于开始(或结束或中间-个人偏好)

    最后,仍有可能出现歧义。这不太可能,即使只有一小部分输入点,也不太可能。这是你需要注意的一点。另请参见下文中关于更可能出现歧义的特殊情况的讨论

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

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


    如果X轴和Y轴上的标度相同,那么夜曲关于交换性的观点(在评论中)确实适用。这意味着,如果您有这样一个比例,并且它位于旋转旁边,那么您将获得两个可能的有效变换顺序。无法区分这两者。

    您有多少个变换?我突然想到,除非这是一个很大的问题,否则暴力手段将是最简单和最好的。如果你有很多,我想你可能仍然需要一个蛮力的方法,而不需要一些非常复杂的事情分析。。。此外,你也不能保证找到一个唯一的解决方案(如两个连续的翻译可以颠倒)。我不认为你能解决这个问题。例如,Translate函数可以在任何步骤执行,最终结果为same@Musefan:对于翻译来说,事实并非如此。假设你的第一个点是
    0,1
    ,你的两个变换是
    0,-1
    的平移和围绕原点旋转180度。显然,在旋转之前是否进行平移很重要。同样的论点也适用于缩放。@Chris:你是对的,我假设原点是r