2013-10-23 23 views
4

我想創建一個在Matlab中的多個座標系之間轉換的程序。應用函數在Matlab中獲取多個狀態

我有不同的系統,並希望在它們之間傳輸。有以地心爲中心的不同地心繫統。我寫了轉換矩陣在這些座標系之間轉換。

爲了簡化這個問題,我將使用一個例子。

如果我有3個座標系:

笛卡爾,圓柱&球面座標

從圓柱座標轉換爲笛卡爾座標。我可以申請:

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

將從球座標轉換爲笛卡爾座標。我可以申請:

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

假設我們不直接轉換球座標至柱座標下,我們轉換:

  • 球 - >笛卡爾
  • 笛卡爾 - >圓柱

在我真正的問題中,我有8個不同的座標系,每個座標系在它們之間來回轉換。系統只有兩條鏈接到不同座標系的路徑。

它看起來像這樣:

甲< - >乙< - 「ç< - > d < - >電子< - >˚F< - 」G < - >ħ

我想創建用戶可以選擇座標系,輸入座標並選擇目標座標系的方法。

,而無需手動編寫功能:A - > C,A - > d,A - > ...對於54個不同步驟

有沒有一種方法我可以創建一個系統連接的路徑? 有沒有一種方法可以使用圖形或節點並應用連接節點的功能(A-> C) 這個概念是什麼,所以我可以閱讀更多內容?

回答

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 

可以肯定,有實現這個更聰明的方法,這基本上是在說,一個調度表根據當前類型和目標類型確定哪個方向。

編輯

繼喬納斯操作的方式從一箇中央類型的所有轉換的建議(比方說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 
+0

您可能想在您的第一個開關/箱體塊中使用input_coord – Jonas

+0

我首先執行'output_coord = intput_coord',但是這肯定會被清理一下。代碼未經測試... –

+0

這正是我想要的! 我喜歡你給出的原始解決方案,並認爲這是我正在尋找的。 但是用@喬納斯的建議,這允許更少的函數明確定義,並使其更好。 謝謝你們! 我更喜歡用Java和Python進行編碼,所以我很想了解更多關於這個問題。我看着調度表,這可能是我在找的東西。想知道這是否是正確的術語,所以我可以自己閱讀它? – Kaj

2

在您當前的邏輯A <-> B <-> C <-> D <-> E <-> F <-> G <-> H中,您將不得不編寫14個轉換函數(如果A->BB->A計爲兩個)。

我建議,而不是,你選擇一個參考座標系,比方說,A和寫入功能A<->BA<->C

這種解決方案需要您編寫相同數量的功能,作爲您的解決方案,但邏輯變得微不足道。此外,每次轉換最多需要兩個轉換步驟,這將避免在執行轉換鏈時累積四捨五入錯誤。

+0

‘最多一個的’ - > '最多兩個'? –

+0

通過一種引用類型進行所有轉換的建議是一個很好的建議。實際的實施仍然看起來類似於我的答案。 –

+0

@BasSwinckels:是的,當然,最多兩個。 – Jonas