【问题标题】:Apply Functions to get to Multiple States in Matlab在 Matlab 中应用函数以获取多个状态
【发布时间】:2013-10-23 08:07:41
【问题描述】:

我正在尝试在 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) 这是什么概念,所以我可以阅读更多内容?

【问题讨论】:

    标签: matlab coordinate-systems coordinate-transformation


    【解决方案1】:

    你可以用面向对象编程来实现一些复杂的东西,但为了简单起见,我建议将所有不同类型的坐标存储为结构,这些结构都有一个成员 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
    

    【讨论】:

    • 你可能想在你的第一个 switch/case 块中使用 input_coord
    • 我先做一个output_coord = intput_coord,但这肯定可以清理一下。代码未经测试...
    • 这正是我想要的!我喜欢您提供的原始解决方案,并认为这就是我正在寻找的。但是根据@Jonas 的建议,这允许显式定义更少的函数并使其变得更好。多谢你们!我更喜欢用 Java 和 Python 编写代码,所以我很想了解更多关于这个问题的信息。我查看了调度表,这可能就是我想要的。想知道这是否是正确的术语,以便我自己阅读?
    • 要搜索的词可能是“调度表”或“单个调度”。是的,这在 Python 中比在 Matlab 中要容易得多(如果你还没有的话,看看 numpy)。请注意,Jonas 的解决方案并没有减少函数的数量,它只是使逻辑更容易,并且最多需要 2 次转换。在线性链和 Jonas 星型方案的情况下,您都需要2 * (n-1) 转换函数。如果您满意,请采纳答案。
    【解决方案2】:

    在您当前的逻辑A <-> B <-> C <-> D <-> E <-> F <-> G <-> H 中,您将必须编写 14 个转换函数(如果 A->BB->A 算作两个)。

    我建议您改为选择一个参考坐标系,例如 A 并编写函数 A<->BA<->C 等。

    此解决方案要求您编写与您的解决方案相同数量的函数,但逻辑变得微不足道。此外,每次转换最多需要两个转换步骤,这样可以避免在执行一系列转换时累积舍入误差。

    【讨论】:

    • '最多一个' -> '最多两个' ?
    • 通过一种引用类型进行所有转换的建议是一个很好的建议。实际的实现看起来仍然与我的答案相似。
    • 我喜欢这个解决方案,我之前没有想到这个。以确保我理解。如果我想转换C->E,我在输入系统C中输入坐标,转换C->A,然后转换A->E。更深入地看,这需要 54 个函数,例如 B->DB->E... 我仍然需要编写函数:function [output_coord] = coordC_to_coordE(input_coord) output_coord = coordA_to_coordE(coordC_to_coordA(input_coord)) 我想使用图形或一些编程概念来避免定义 54在坐标系之间跳转的函数。感谢您的帮助,我很欣赏这个想法:)
    猜你喜欢
    • 2017-12-13
    • 2020-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多