2016-11-16 125 views
1

我正在構建一個將軌道元素轉換爲笛卡爾座標的程序。將三個函數合併爲一個

我想創建一個這樣做的函數,將軌道元素轉換成cartisian座標,但是我無法讓它工作。這是我第一次使用fortran,所以我仍然習慣它。

program conversion 

implicit none 
real*8 :: EC, A, IC, OM, W, TA, X, Y, Z 
real*8, external :: XCARTISIAN, YCARTISIAN, ZCARTISIAN, r 

print *, "Insert Oribtal Elements (EC, A, IC, OM, W, TA): " 
read *, EC, A, IC, OM, W, TA, X, Y, Z 


X = XCARTISIAN(EC, A, IC, OM, W, TA) 
Y = YCARTISIAN(EC, A, IC, OM, W, TA) 
Z = ZCARTISIAN(EC, A, IC, OM, W, TA) 

print *, "X : ", X, "Y : ", Y, "Z : ", Z 

end program conversion 



real*8 function XCARTISIAN(EC, A, IC, OM, W, TA) 

implicit none 
real*8, intent(in) :: EC, A, IC, OM, W, TA 
real*8 :: XCARTISIAN, r 

r = A(1-EC**2)/(1+EC*COS(TA)) 
XCARTISIAN = r(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC)) 

return 

end function XCARTISIAN 

real*8 function YCARTISIAN(EC, A, IC, OM, W, TA) 

implicit none 
real*8, intent(in) :: EC, A, IC, OM, W, TA 
real*8 :: YCARTISIAN 

r = A(1-EC**2)/(1+EC*COS(TA)) 
YCARTISIAN = r(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC)) 

return 

end function YCARTISIAN 


real*8 function ZCARTISIAN(EC, A, IC, OM, W, TA) 

implicit none 
real*8, intent(in) :: EC, A, IC, OM, W, TA 
real*8 :: ZCARTISIAN 

r = A(1-EC**2)/(1+EC*COS(TA)) 
ZCARTISIAN = r(SIN(W+F)*SIN(IC) 

return 

end function ZCARTISIAN 

我怎樣才能使這個工作,並做一個單獨的功能,而不是三個獨立的單獨的X,Y和Z單獨的?

的轉換公式如下:

X = r(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC)) 
Y = r(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC)) 
Z = r(SIN(W+F)*SIN(IC) 

其中,

r = A(1-EC**2)/(1+EC*COS(TA)) 
+0

歡迎。針對所有Fortran問題使用標籤[tag:fortran]。如果您需要區分特定版本,則可以添加版本。 –

+0

你不能改變你的問題!你不能使現有的答案無效。 –

+0

對不起,但在過去的問題中,人們告訴我當新問題出現時更新當前問題。我一直在大吼大叫,因爲沒有更新主要問題和更新問題... –

回答

1

最直接的做法是製作一個子程序。最好放在一個模塊中,但這是可選的(但恕我直言,所有的功能和子程序應該在某個模塊中)。

subroutine XYZCARTISIAN(XCARTISIAN, YCARTISIAN, ZCARTISIAN, EC, A, IC, OM, W, TA) 

    implicit none 
    real*8 :: XCARTISIAN, YCARTISIAN, ZCARTISIAN 
    real*8, intent(in) :: EC, A, IC, OM, W, TA 
, r 

    r = A(1-EC**2)/(1+EC*COS(TA)) 

    XCARTISIAN = r*(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC)) 
    YCARTISIAN = r*(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC)) 
    ZCARTISIAN = r*(SIN(W+F)*SIN(IC) 
end subroutine 

這也將更快,因爲你計算r只有一次,你做只有一個子程序調用。

請注意:

  1. real*8完全是非標準的,它不是Fortran語言。
  2. 使用縮進可使您的代碼更具可讀性。
  3. return是必要的,我們只有過早返回。
+0

好的!這很簡單! –

+0

如果我理解正確,要使用子例程,我需要使用CALL()函數。我如何在代碼的主要部分執行此操作,以便將XCARTISIAN分配給X等等? –

+0

你只是叫'XYZCARTISAN(X,Y,Z,EC,...)' –

1

也許把你的功能集成到一個模塊?

MODULE ORBITCANDY 
IMPLICIT NONE 
PRIVATE 

TYPE(Cart_typ) 
    REAL*8 X 
    REAL*8 Y 
    REAL*8 Z 
END TYPE Cart_typ 
PUBLIC :: Cart_Typ 

TYPE(OE_typ) 
    REAL*8 EC 
    REAL*8 A 
    REAL*8 IC 
    REAL*8 OM 
    REAL*8 W 
    REAL*8 TA 
END TYPE OE_typ 
PUBLIC :: OE_Typ 

PUBLIC :: OE2CART 

CONTAINS 

function OE2Cart(OE) 
implicit none 
TYPE(OE_Typ) , INTENT(IN ) :: OE 
TYPE(Cart_Typ)    :: OE2Cart 
real*8      :: EC, A, IC, OM, W, TA 
real*8      :: XCARTISIAN, r 

EC = OE%EC 
A = OE%A 
IC = OE%IC 
OM = OE%OM 
W = OE%W 
TA = OE%TA 
OE2Cart%X = XCARTISIAN(EC, A, IC, OM, W, TA) 
OE2Cart%Y = YCARTESIAN(EC, A, IC, OM, W, TA) 
OE2Cart%Z = ZCARTESIAN(EC, A, IC, OM, W, TA) 

RETURN 
END FUNCTION OE2CART 

!%%%%%%%%%%%%%% 
real*8 function YCARTISIAN(EC, A, IC, OM, W, TA) 
implicit none 
TYPE(OE_Typ) , INTENT(IN ) :: OE 
real*8, intent(in) :: EC, A, IC, OM, W, TA 
real*8 :: XCARTISIAN, r 

r = A(1-EC**2)/(1+EC*COS(TA)) 
XCARTISIAN = r(COS(OM)*COS(W+TA)-SIN(OM)*SIN(W+TA)*COS(IC)) 

return 
end function XCARTISIAN 

!%%%%%%%%%%%%%% 
real*8 function YCARTISIAN(EC, A, IC, OM, W, TA) 
implicit none 
real*8, intent(in) :: EC, A, IC, OM, W, TA 
real*8 :: YCARTISIAN 

r = A(1-EC**2)/(1+EC*COS(TA)) 
YCARTISIAN = r(SIN(OM)*COS(W+TA)+COS(OM)*SIN(W+TA)*COS(IC)) 

return 
end function YCARTISIAN 


    !%%%%%%%%%%%%%% 
real*8 function ZCARTISIAN(EC, A, IC, OM, W, TA) 

implicit none 
real*8, intent(in) :: EC, A, IC, OM, W, TA 
real*8 :: ZCARTISIAN 

r = A(1-EC**2)/(1+EC*COS(TA)) 
ZCARTISIAN = r(SIN(W+F)*SIN(IC) 

return 

end function ZCARTISIAN 

END MODULE ORBITCANDY 

而且一個R,然後CART2GEODETIC等..

program conversion 
USE ORBITCANDY 
implicit none 
TYPE(OE_Typ) :: OE 
TYPE(Cart_Typ) :: Cart 
real*8, external :: r ! Add this one above 

print *, "Insert Oribtal Elements (EC, A, IC, OM, W, TA): " 
read *, OE%EC, OE%A, OE%IC, OE%OM, OE%W, OE%TA 

print *, "Insert Oribtal Elements (EC, A, IC, OM, W, TA): " 
read *, OE%EC, OE%A, OE%IC, OE%OM, OE%W, OE%TA 

XYZ = OE2CART(OE) 
print *, "X : ", XYZ%X, "Y : ", XYZ%Y, "Z : ", XYZ%Z 

end program conversion 

有在iPad上沒有編譯器,所以我肯定有一個錯字...

+2

爲什麼貌似簡單的Fortran讓我的眼睛每次都流血? – rubenvb

+0

嬰兒的步驟@rubenvb但程序(主)看起來更簡單。我可以把ISO_C_BINDING放在裏面,這樣你可以在C(?)中使用它。 – Holmz