黄経 黄緯 から、赤経 赤緯 へ

 投稿者:SECOND  投稿日:2010年12月14日(火)22時38分48秒
  ! 黄経 黄緯 から、赤経 赤緯 へ
!-----------------------------

!赤道座標系= 地表の経緯度を天空に投影し、経緯度0を天空の春分点に固定。
!
!黄道座標系= 赤道座標系と同様であるが、中心から春分点を結ぶ線 を軸に、
!       全体を回転、その赤道面(黄道面)を地球の公転面に重ねる。
!地球を中心にする地心黄道座標系と、
!太陽を中心にする日心黄道座標系の、2通りがある。

!地心黄道座標系の黄道面(地球の公転面)は、赤道座標系の赤道面の
!春分点から中心側をみて、反時計方向に、ε=23.4°傾いている。
! (太陽は、黄道を1年かけて、西から東へ逆回りするように見える。)

!地心黄道座標系の黄道面、赤道座標系の赤道面、それぞれの中心から、
!春分点を結ぶ線を、X軸とする2つの直交座標系を仲介させると、・・

!     赤道座標                                         黄道座標
!
!  |緯度δ経度αの方向余弦x|  |1      0        0  | |緯度β経度λの方向余弦x|
!  |緯度δ経度αの方向余弦y|=|0  cos(ε)  sin(ε)| |緯度β経度λの方向余弦y|
!  |緯度δ経度αの方向余弦z|  |0 -sin(ε)  cos(ε)| |緯度β経度λの方向余弦z|
!
!           |cos(δ)*cos(α)|  |1      0        0  | |cos(β)*cos(λ)|
!           |cos(δ)*sin(α)|=|0  cos(ε)  sin(ε)| |cos(β)*sin(λ)|
!           |sin(δ)        |  |0 -sin(ε)  cos(ε)| |sin(β)        |
!-----------------------------

!※十進BASIC では、画素が 行ベクトル構造なので、行列は下の様に転置させ、
! さらに1次追加して、平行移動も可能(Afine)の形式で、実行する。
!
! 緯度β経度λの方向余弦(xyz1)       |1,       0,        0, 0|
! {cos(β)*cos(λ), cos(β)*sin(λ), sin(β), 1} |0, cos(ε), -sin(ε), 0|=
!                                                 |0, sin(ε),  cos(ε), 0|
!                                                 |0,       0,        0, 1|
!     緯度δ経度αの方向余弦(xyz1)
!     {cos(δ)*cos(α), cos(δ)*sin(α), sin(δ), 1}
!
!-----------------------------

!緯度δ経度αの方向余弦x cos(δ)*cos(α)=  cos(β)*cos(λ)
!緯度δ経度αの方向余弦y cos(δ)*sin(α)=  cos(β)*sin(λ)*cos(ε) +sin(β)*sin(ε)
!緯度δ経度αの方向余弦z     sin(δ)= -cos(β)*sin(λ)*sin(ε) +sin(β)*cos(ε) ※1
!
!経度α=mod( angle(x,y), 360)         ※2  (output 0~360°)
!経度α=mod( angle(x/cos(β),y/cos(β)), 360) ※2'
!-----------------------------

OPTION ARITHMETIC NATIVE
DEF δ_(λ,β)= ASIN( -COS(β)*SIN(λ)*SIN(ε) +SIN(β)*COS(ε) )             !緯度δ ※1
DEF α_(λ,β)= MOD( ANGLE( COS(λ), SIN(λ)*COS(ε)+TAN(β)*SIN(ε) ), 360)  !経度α ※2'

!このプログラムは、上の座標変換を、
!立体モデルのアニメーションにして、どの方向からも、見られる様にしたもの。
!-----------------------------

OPTION ANGLE DEGREES
DIM pV(4), P3D(4,4), LH(6), rec_(0 TO 2000, 3)  !rec_の使用量 約1200( 0~1184)
DIM rotx(4,4), shxyzM(4,4), shxyzP(4,4)
MAT rotx=IDN
MAT shxyzM=IDN
MAT shxyzP=IDN
!-----
!
LET ε=-23.4          !黄道から見る赤道の傾斜角ε
LET λ= 45            !黄経λ   0°~+360°
LET β= 45            !黄緯β  -90°~+90°
LET δ=δ_(λ,β)     !赤緯δ
LET α=α_(λ,β)     !赤経α
!-----
!
MAT READ LH
DATA -1.5,1.5, -1.5,1.5, -1.5,1.5  !座標軸の両端座標 xL,xH, yL,yH, zL,zH
!
LET zox=0!.5                       !回転 旋回中心点 center へのオフセットxyz(使用しない)
LET zoy=0!.5
LET zoz=0!.5
!
LET Sx=1                           !スケール倍率 Sx,Sy,Sz
LET Sy=1
LET Sz=1
LET xm=0                           !画面中心 xm,ym
LET ym=0
LET hw=2                           !画面幅/2 ±hw
!
LET Axs=-75                        !z軸をx軸まわりで倒す開始角度
LET Ays=0                          !z軸をy軸まわりで倒す開始角度
LET Azs=0                          !z軸 回転開始角度
LET ST= +1                         !z軸 回転ステップ +:左回転 -:右回転
!
SET WINDOW xm-hw,xm+hw,ym-hw,ym+hw
CALL graph3D
CALL mat_shxyz
CALL plotter

!3D原画を作る。     黒1 赤4 Cyan5 黄6=FFFF00,63=AAAA00,13=808000,44=555500

SUB graph3D
   LET ci=0
   !---天球(赤)
   CALL rec_xyz( 1e4, 4, 1)                     !(制御コードPEN-off, color, width)
   LET r=1
   LET Az=0
   LET Ax=ε*COS(Az)                            !ε(Az=0)
   LET Ay=ε*SIN(Az)                            ! 0(Az=0)
   CALL ball                                    !keep Ax,Ay,Az, set P3D
   !---試験ベクトル(経度α,緯度δ)
   LET pV(1)=COS(δ)*COS(α)
   LET pV(2)=COS(δ)*SIN(α)
   LET pV(3)=SIN(δ)
   LET pV(4)=1
   MAT pV=pV*P3D
   CALL rec_xyz( 2e4, 0, 4)                     !(制御コード, color,width)
   CALL rec_xyz(0.8*pV(1),0.8*pV(2),0.8*pV(3))  !(x,y,z)
   CALL rec_xyz(1.2*pV(1),1.2*pV(2),1.2*pV(3))  !(x,y,z)
   !---天球(黄)
   CALL rec_xyz( 1e4, 13, 1)                    !(制御コードPEN-off, color, width)
   LET r=1.3
   LET Ax=0
   LET Ay=0
   CALL ball                                    !keep Ax,Ay,Az, set P3D
   !---試験ベクトル(経度λ,緯度β)
   LET pV(1)=COS(β)*COS(λ)
   LET pV(2)=COS(β)*SIN(λ)
   LET pV(3)=SIN(β)
   LET pV(4)=1
   MAT pV=pV*P3D
   CALL rec_xyz( 2e4, 0, 4)                     !(制御コード, color, width)
   CALL rec_xyz(1.2*pV(1),1.2*pV(2),1.2*pV(3))  !(x,y,z)
   CALL rec_xyz(1.5*pV(1),1.5*pV(2),1.5*pV(3))  !(x,y,z)
   !---
   CALL rec_xyz( 1e4, 1, 1)                     !(制御コードPEN-off, color, width)
END SUB

SUB rec_xyz(x,y,z)
   LET rec_(ci,1)=x
   LET rec_(ci,2)=y
   LET rec_(ci,3)=z
   LET ci=ci+1
END SUB

SUB ball                                     !球殻モデル
!---経度のline
   LET Az0=Az
   FOR Az=Az0 TO Az0+180-1 STEP 360/24
      CALL mat_P3D
      FOR t=-90 TO 270+1 STEP 15
         LET pV(1)=r*COS(t)
         LET pV(2)=0
         LET pV(3)=r*SIN(t)
         LET pV(4)=1
         MAT pV=pV*P3D
         CALL rec_xyz(pV(1),pV(2),pV(3))     !(x,y,z)
      NEXT t
   NEXT Az
   LET Az=Az0
   CALL mat_P3D
   CALL rec_xyz( 1e4, 0, 0)                  !(制御コードPEN-off, color, width)
   !---緯度のline
   FOR h=15 TO 180-1 STEP 15
      IF h=90 THEN CALL rec_xyz( 2e4, 0, 2) !(制御コード, color, width)
      FOR a=0 TO 360+1 STEP 360/24
         LET pV(1)=r*SIN(h)*COS(a)
         LET pV(2)=r*SIN(h)*SIN(a)
         LET pV(3)=r*COS(h)
         LET pV(4)=1
         MAT pV=pV*P3D
         CALL rec_xyz(pV(1),pV(2),pV(3))     !(x,y,z)
      NEXT a
      CALL rec_xyz( 1e4, 0, 1)               !(制御コードPEN-off, color, width)
   NEXT h
END SUB

!-----------------------------------------
SUB plotter
   LET Ax=Axs                                !z軸をx軸まわりで倒す開始角度
   LET Ay=Ays                                !z軸をy軸まわりで倒す開始角度
   LET Az=Azs
   MOUSE POLL m_x,m_y,mlb,mrb
   LET mxbak=m_x
   LET mybak=m_y
   DO
      IF mlb=0 THEN LET Az=MOD(Az+ST,360)    !z軸で、1ステップ回す。
      CALL mat_P3D                           !Ax,Ay,Az 回転などの行列 P3D 作成
      SET DRAW mode hidden
      CLEAR
      CALL panel                             !座標軸、角度表示 を描く
      !----                                  !3D原画の再生。
      FOR ci=0 TO ci-1
         CALL line3D( rec_(ci,1),rec_(ci,2),rec_(ci,3) )
      NEXT ci
      SET DRAW mode explicit
      !----
      MOUSE POLL m_x,m_y,mlb,mrb
      IF mlb=1 THEN
         LET Ax=Ax -(m_y-mybak)*90/hw        !ドラッグ方向、90度/画面半幅
         LET Ay=Ay +(m_x-mxbak)*90/hw
      END IF
      LET mxbak=m_x
      LET mybak=m_y
      WAIT DELAY 0 !0.05
   LOOP UNTIL mrb=1
END SUB

!-----------------------------------------
SUB mat_P3D
   LET ar0=SQR(Ax^2+Ay^2)                    !旋回角度(∝マウス・ドラッグの長さ)
   IF ar0<>0 THEN LET DIRar0=ANGLE(Ax,Ay)    !旋回軸の方向
   IF 180< ar0 THEN
      LET Ax=(ar0-360)*COS(DIRar0)
      LET Ay=(ar0-360)*SIN(DIRar0)
   END IF
   ! xy平面上、0度方向(x軸)を、軸として旋回する行列 rotx
   !(x,y,z,1)| 1,        0,        0, 0 |
   !         | 0, cos(ar0), sin(ar0), 0 |
   !         | 0,-sin(ar0), cos(ar0), 0 |
   !         | 0,        0,        0, 1 |
   LET rotx(2,2)=COS(ar0)
   LET rotx(3,2)=-SIN(ar0)
   LET rotx(2,3)=SIN(ar0)
   LET rotx(3,3)=COS(ar0)
   !
   ! (center →原点) (旋回軸→x軸) (x軸でrot.) (旋回軸→元へ) (center →元へ)
   MAT P3D= shxyzM*ROTATE(Az-DIRar0)*rotx*ROTATE(DIRar0)*shxyzP !変形指示MAT
END SUB

!-----------------------------------------
SUB panel
   PLOT TEXT,AT xm-hw*.9,ym+hw*.9: "赤道座標系と、地心黄道座標系"
   PLOT TEXT,AT xm+hw*.23,ym+hw*.9,USING"Ax=####  Ay=####  Az=####":Ax,Ay,Az  !PEN-off
   PLOT TEXT,AT xm+hw*.5,ym+hw*.83: "右クリック: 終了"  !PEN-off
   !---
   IF ar0< 90 THEN SET AREA COLOR "cyan" ELSE SET AREA COLOR "black"
   DRAW disk WITH SCALE(hw/5)*P3D                         !   原点近傍、裏表 のマーカー1
   DRAW disk WITH SCALE(hw/15)*SHIFT(zox*Sx,zoy*Sy)*P3D   !center 近傍、裏表 のマーカー2
   CALL axes3D( zox,zoy,0, zox,zoy,zoz, "center" )        !center 座標を指す  マーカー3
   !---座標軸
   CALL axes3D( LH(1),0,0, LH(2),0,0, STR$(LH(2))& "( X)" )
   PLOT TEXT,AT pV(1),pV(2)-.15 :"春分点"
   CALL axes3D( 0,LH(3),0, 0,LH(4),0, STR$(LH(4))& "( Y)" )
   CALL axes3D( 0,0,LH(5), 0,0,LH(6), STR$(LH(6))& "( Z)" )
END SUB

!-----------------------------------------
SUB axes3D(x1,y1,z1, x2,y2,z2, a$ )
   CALL line3D(x1,y1,z1)
   CALL line3D(x2,y2,z2)
   PLOT TEXT,AT pV(1),pV(2) :a$      !PEN-off
END SUB

SUB line3D(x,y,z)
   IF x< 1e4 THEN
      LET pV(1)=x*Sx                 !目盛/pixel は 全方向等しくないと、回転で形が保てない。
      LET pV(2)=y*Sy                 !スケール Sx,Sy,Sz の違いは、入力の倍率として、行なう。
      LET pV(3)=z*Sz                 !入力 z 座標は 出力 x,y に反映。出力zは 描画不可。
      LET pV(4)=1                    !平行移動の shxyzM …shxyzP で必要。
      MAT pV=pV*P3D
      PLOT LINES: pV(1),pV(2);       !PEN-on
   ELSE
      IF x=1e4 THEN PLOT LINES       !PEN-off
      IF 0< y THEN SET LINE COLOR y
      IF 0< z THEN SET LINE width z
   END IF
END SUB

!-----------------------------------------
SUB mat_shxyz
!
!  ! 回転 旋回中心点 center を 原点へ移動し、又、元へ戻す行列。(初期値=単位行列。無効果)
!  !(x,y,z,1)|      1,      0,      0, 0 |
!  !         |      0,      1,      0, 0 |
!  !         |      0,      0,      1, 0 |
!  !         |-zox*Sx,-zoy*Sy,-zoz*Sz, 1 |
   LET shxyzM(4,1)=-zox*Sx
   LET shxyzM(4,2)=-zoy*Sy
   LET shxyzM(4,3)=-zoz*Sz
   !
   !(x,y,z,1)|      1,      0,      0, 0 |
   !         |      0,      1,      0, 0 |
   !         |      0,      0,      1, 0 |
   !         | zox*Sx, zoy*Sy, zoz*Sz, 1 |
   LET shxyzP(4,1)=zox*Sx
   LET shxyzP(4,2)=zoy*Sy
   LET shxyzP(4,3)=zoz*Sz
END SUB

END

!-----
!1)描画されたz軸と平行な、
!  center を通る軸で、常時回転。
!
!2)マウス 左ボタン押下で 一時停止、離すと再開。
!      右ボタン押下で 終了。
!
!3)左ボタン押下のまま、引きずると、
!  xy平面に平行で、center を通る
!  任意な方向の軸で、全体が旋回する。
!
! (z軸 先端を、ドラッグする感じ。)
!
!※ここまで プログラムに含め、実行時のヘルプに。
 

戻る