基于用户指定方向从 XYZ 到前/上/右坐标变换的算法

问题描述 投票:0回答:1

希望这个问题不是太宽泛。我并不是在寻找任何人为我编写这个算法,但希望我在这里尝试做的事情已经完成,但我没有找到它,我希望有人可以建议通常如何解决此类问题。

我正在编写一个应用程序,它从 CAD 程序中获取 3D 模型,读取几何数据,并对其进行计算。在 3D 空间中,坐标表示为正/负 XYZ 值,我有一个用于存储它们的包装器:

public class XyzCoords
{
    public double X;
    public double Y;
    public double Z;
}

假设用户制作了一辆汽车的 3D 模型。根据他们的建模方式,它可能面向 X+、X-、Y+、Y-、Z+ 或 Z- 方向,而屋顶可能指向任何其他方向。用户需要在我的应用程序中指定向前/向上方向,以便它可以理解模型并对其执行计算。方向以枚举器表示:

public enum Directions
{
    Xpos,
    Xneg,
    Ypos,
    Yneg,
    Zpos,
    Zneg
}

用户选择保存在如下设置中:

public Directions directionFw;
public Directions directionUp;

(右不必指定,因为可以从前/上推断)

为了使计算和结果与方向无关,我有另一个坐标包装器,将坐标表示为前/上/右:

public class FurCoords
{
    public double F;
    public double U;
    public double R;
}

现在,我需要一个可以在 XyzCoords 和 FurCoords 之间相互转换的转换器:

public static class XyzFurConverter
{
    public FurCoordinates Convert(XyzCoords xyzCoords, Directions directionFw, Directions directionUp)
    {
        //...
    }

    public XyzCoords Convert(FurCoordinates coordinates, Directions directionFw, Directions directionUp)
    {
        //...
    }
}

在我的应用程序核心中,Z正被认为是前向,Y正被认为是向上,这使得X正为右。这意味着如果第一个函数像这样调用:

FurCoords furCoords = XyzFurConverter.Convert([1, 2, 3], Directions.Zpos, Directions.Ypos)

那么

FurCoords
字段值应该这样写:

F = 1
U = 2
R = 3

问题在于实施转换。当然可以通过对每种可能的组合使用大量 if/switch 语句来完成,但考虑到组合的数量庞大,这似乎是一种愚蠢的方法。有没有人遇到过类似的问题,并且可以建议这种事情通常是如何解决的?再说一遍,不是找人帮我做作业,只是一些指导。

c# coordinates coordinate-transformation
1个回答
0
投票

这个问题一般可以通过使用变换矩阵来解决。

它确实需要一些代数,但一旦掌握了它的窍门,那就很容易了。基本思想是矩阵向量乘法将对象从一个坐标系变换到另一个坐标系。从同质 4 维单位矩阵

开始
(1 0 0 0)
(0 1 0 0)
(0 0 1 0)
(0 0 0 1)

(应用于对象时不执行任何操作)您可以开始交换坐标。例如。要将对象上下翻转,请取消 z 轴:

(1 0 0 0)
(0 1 0 0)
(0 0 -1 0)
(0 0 0 1)

当然,最好绕 x 轴旋转(如上面的“翻转”左右反转)。 看起来像

     (1 0 0 0)
Rx = (0 cos(180) sin(180) 0)
     (0 -sin(180) cos(180) 0)
     (0 0 0 1)

设置好矩阵后(在您的情况下,使用用户提供的任何旋转值),然后将矩阵与每个点的向量相乘(您需要使用 4 维向量,第 4 个元素必须是 1开头,但之后可以忽略)。

对于每个点:

FurCoords[1x4-Vector] = XyzCoords[1x4-Vector] * Matrix[4x4-Matrix]

一本好的代数书(或现有的数学库)会告诉您如何进行向量乘以矩阵乘法。

© www.soinside.com 2019 - 2024. All rights reserved.