(46)月ロケットの軌道 4

スライダーで移動体の速度がリアルタイムに変更できるようにしたが、きれいな軌道へはなかなか投入できない。


platform.apilevel = "2.4"

local color = {earth = 0x00FFFF, moon = 0xFFFF00, rocket = 0xFCFCFC, background = 0x104E8B, string = 0x848484}
platform.window:setBackgroundColor(color.background)

local time = 0 -- シム内経過時間〔sec〕
local step = 150 --〔sec〕

function on.resize()
   w, h = platform.window:width(), platform.window:height()
   unit = h/1000 -- 画面上での 1 単位の画素数
   x0, y0 = w/3, h/2 -- 原点(地球の位置)を設定する
   xm, ym = x0 + unit * 480, y0 -- 月の位置を設定する
   radius_earth = h/50 -- 地球の半径
   dia_earth = radius_earth * 2 -- 地球の直径
   radius_moon = h/80 -- 月の半径
   dia_moon = radius_moon * 2 -- 月直径
   radius_sat = h/80 -- 移動体の半径
   dia_sat = radius_sat * 2 -- 移動体の直径
   fontSize = math.floor(h/17)
end

var.store("g", 1)
var.store("m1", 1)
var.store("m2", 1/80)
var.store("xm", 480)
var.store("tstart", 0)
var.store("tstop", step)
var.store("ini_lx", -8) -- x 方向の初期位置
var.store("ini_vx", -0.017) -- x 方向の初速
var.store("ini_ly", 0) -- y 方向の初期位置
var.store("ini_vy", 0.494) -- y 方向の初速
var.store("step", step)
var.store("tol", 0.0001)

--- 中心座標と半径と直径とで円を描く部分プログラム(円の中心座標, 半径, 直径, 色, gc)
function drawCircle(x, y, radius, dia, color, gc)
   gc:setColorRGB(color)
   gc:fillArc(x - radius, y - radius, dia, dia, 0, 360)
end

function on.paint(gc)
   gc:setPen("thin")
   gc:setFont("sansserif", "r", fontSize)

   -- rk23() を計算
   mat = math.eval("moon_rocket(g, m1, m2, xm, tstart, tstop, ini_lx, ini_vx, ini_ly, ini_vy, step,tol)")
   
   -- 移動体の座標を計算する

   x1 = x0 + unit * mat[2][1]
   y1 = y0 - unit * mat[4][1]
   
   -- 中心質点と移動体とを結ぶ直線を描く
   gc:setColorRGB(color.string)
   gc:drawPolyLine({x0, y0, x1, y1, xm, ym})
      
   -- 原点に地球を描画する
   drawCircle(x0, y0, radius_earth, dia_earth, color.earth, gc)

   -- 月を描画する
   drawCircle(xm, ym, radius_moon, dia_moon, color.moon, gc)

   -- 移動体を描画する
   drawCircle(x1, y1, radius_sat, dia_sat, color.rocket, gc)
         
   --[[ シム内の経過時間を表示
   gc:setColorRGB(brightgray)
   gc:drawString("time = "..math.floor(time).." s", fontSize, fontSize)--]]
end

function on.enterKey()
   timer.start(0.01)
end
function on.escapeKey()
   timer.stop()
end
function on.timer()
   platform.window:invalidate()
   
   --「step 後の値」を初期値に入れ換える
   local v1 = var.recall("v1")
   var.store("ini_lx", mat[2][2])
   var.store("ini_vx", mat[3][2] * v1)
   var.store("ini_ly", mat[4][2])
   var.store("ini_vy", mat[5][2] * v1)
   --time = time + step
end