4

我正在尝试创建一个在 Matlab 中的多个坐标系之间转换的程序。

我有不同的系统,想在它们之间转移。有不同的地心、地心和日心系统。我已经编写了转换矩阵以在这些坐标系之间进行转换。

为了简化这个问题,我将使用一个示例。

如果我有 3 个坐标系:

笛卡尔坐标、圆柱坐标和球坐标

将圆柱坐标转换为笛卡尔坐标。我可以申请:

x = r ∙ cos(ø)
y = r ∙ sin(ø)
z = z

将球坐标转换为笛卡尔坐标。我可以申请:

x = R ∙ sin(θ) ∙ cos(ø)
y = R ∙ sin(θ) ∙ sin(ø)
z = R ∙ cos(θ)

假设我们不将球坐标直接转换为圆柱坐标,我们转换:

  • 球形 -> 笛卡尔
  • 笛卡尔 -> 圆柱

在我真正的问题中,我有 8 个不同的坐标系,每个坐标系之间来回转换。这些系统只有两条路径链接到不同的坐标系。

它看起来像这样:

A <-> B <-> C <-> D <-> E <-> F <-> G <-> H

我想为用户创建一种方法来选择坐标系、输入坐标并选择目标坐标系。

而不是手动编写函数: A -> C , A -> D , A -> E ... 54 个不同的步骤

有没有办法可以创建一个系统来连接路径?有没有办法可以使用图形或节点并应用连接节点的函数(A->C)这个概念是什么,所以我可以阅读更多内容?

4

2 回答 2

2

In your current logic, A <-> B <-> C <-> D <-> E <-> F <-> G <-> H, you will have to write 14 functions for converting (if A->B and B->A count as two).

I suggest that instead, you choose one reference coordinate system, say, A and write the functions A<->B, A<->C, etc.

This solution requires you to write the same number of functions as your solution, but the logic becomes trivial. Furthermore, each conversion takes a maximum of two conversion steps, which will avoid accumulating round-off errors when you perform a chain of conversions.

于 2013-10-23T10:37:48.167 回答
2

您可以使用面向对象的编程来实现一些复杂的东西,但为了简单起见,我建议将所有不同类型的坐标存储为结构,这些结构都有一个成员type以及该特定类型坐标所需的任何其他成员。

然后,您可以定义所有转换函数,这些函数只需一步即可具有相同的函数签名function out_coord = A2B(in_coord),例如:

function cart = sphere2cart(sphere)
assert(strcmp(sphere.type, 'sphere')) % make sure input is correct type
cart.type = 'cart';
cart.x = sphere.R * sin(sphere.theta) * cos(sphere.omega);
cart.y = sphere.R * sin(sphere.theta) * sin(sphere.omega);
cart.z = sphere.R * cos(sphere.theta);

这些函数可以从一个通用convert函数中调用,如下所示:

function output_coord = convert(input_coord, target_type)
output_coord = input_coord;
while ~strcmp(output_coord.type, target_type)
    func = get_next_conversion_func(input_coord.type, target_type);
    output_coord = func(output_coord);
end

它一次执行一个转换步骤,直到output_coord具有正确的类型。唯一缺少的步骤是一个函数,该函数根据当前类型和目标类型确定下一步要进行的转换。在您使用“线性”转换链的情况下,这并不难。在更复杂的情况下,类型在复杂图中连接,这可能需要一些最短路径算法。不幸的是,这在 Matlab 中实现起来有点麻烦,但是一个硬编码的解决方案可能是这样的:

function func = get_next_conversion_func(current_type. target_type);
switch current_type
    case 'A'
        func = @A2B;
    case 'B'
        switch target_type
            case 'A'
                func = @B2A;
            case {'C','D','E'}
                func = @B2C;
        end
    case 'C'
        switch target_type
            case {'A','B'}
                func = @C2B;
            case {'D','E'}
                func = @C2D;
        end
    ...
end

当然,有更聪明的方法来实现这一点,这基本上是一个调度表,它根据当前类型和目标类型说明前进的方向。

编辑

按照 Jonas 的建议,通过一种中心类型(比如说C)进行所有转换,所有这些都可以简化为

function output_coord = convert(input_coord, target_type)
output_coord = input_coord;
if strcmp(output_coord.type, target_type)
    return % nothing to convert
end

if ~strcmp(output_coord.type, 'C')
    switch output_coord.type
        case 'A'
            output_coord = A2C(output_coord)
        case 'B'
            output_coord = B2C(output_coord)
        case 'D'
            output_coord = D2C(output_coord)
        case 'E'
            output_coord = E2C(output_coord)
    end
end

assert(strcmp(output_coord.type, 'C'))

if ~strcmp(output_coord.type, target_type)
    switch target_type
        case 'A'
            output_coord = C2A(output_coord)
        case 'B'
            output_coord = C2B(output_coord)
        case 'D'
            output_coord = C2D(output_coord)
        case 'E'
            output_coord = C2E(output_coord)
    end
end
于 2013-10-23T12:00:58.447 回答