4

Matlab で複数の座標系を変換するプログラムを作成しようとしています。

異なるシステムがあり、それらの間で転送したいと考えています。さまざまなトポセントリック、ジオセントリック、ヘリオセントリックのシステムがあります。これらの座標系間で転送する変換行列を作成しました。

この問題を単純化するために、例を使用します。

3 つの座標系がある場合:

直交座標、円筒座標、球座標

円筒座標から直交座標に変換します。私は適用することができます:

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

球座標からデカルト座標に変換します。私は適用することができます:

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

球座標を直接円柱座標に変換しないと仮定すると、次のように変換します。

  • 球面 -> デカルト
  • デカルト -> 円柱

私の実際の問題では、8 つの異なる座標系があり、それぞれの間で変換が行われます。システムには、異なる座標系にリンクする 2 つのパスしかありません。

次のようになります。

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

ユーザーが座標系を選択し、座標を入力し、目的の座標系を選択する方法を作成したいと考えています。

次の関数を手動で記述する代わりに: A -> C 、 A -> D 、 A -> E ... 54 の異なるステップ

パスを接続するシステムを作成する方法はありますか? グラフまたはノードを使用して、ノードを接続する関数を適用する方法はありますか (A->C) この概念は何ですか?

4

2 に答える 2

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これらの関数は、次のように 1 つのユニバーサル関数から呼び出すことができます。

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正しい型になるまで、一度に 1 つの変換ステップを実行します。唯一欠けているステップは、現在の型とターゲットの型に基づいて、次に行う変換を決定する関数です。「線形」変換チェーンの場合、これはそれほど難しくありません。タイプが複雑なグラフで接続されている、より複雑なケースでは、最短パス アルゴリズムが必要になる場合があります。残念ながら、これを Matlab で実装するのは少し面倒ですが、ハードコードされたソリューションの 1 つとして次のようなものがあります。

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

確かに、これを実装するよりスマートな方法があります。これは基本的に、現在の型とターゲット型に基づいてどの方向に進むべきかを示すディスパッチ テーブルです。

編集

すべての変換を 1 つの中心的な型 (たとえば ) を介して行うという 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 に答える