(25)振子の運動 6(アニメ化)

トンデミーナはだいたいこんな感じ:

youtu.be

local w = platform.window:width() -- 画面幅を取得
local h = platform.window:height() -- 画面高さを取得
local center = {x = w/2, y = h/2}  -- 画面中央座標
local length = 0.9 * h/2   -- 画面上の棒の長さ

local g = 9.80665 --重力加速度〔m/s/s〕
local L = 26 -- 棒の長さ〔m〕
local tMin = 0 -- スタート時間〔s〕
local tMax = 0.02 -- ストップ時間〔s〕
local angleInit = (120/180)* math.pi -- 角度初期値〔rad〕
local velInit = 0 -- 角速度初期値〔rad/s〕
local step = tMax -- 時間ステップ〔s〕
local tol = 1e-4 -- 許容差

function on.paint(gc)
   timer.start(step)

   -- 「今の角度、角速度」から「次の角度、角速度」を計算する。
   local mat = math.eval("rk23({vel,((−"..g..")/("..L.."))*sin(θ)},t,{θ,vel},{"..tMin..","..tMax.."},{"..angleInit..","..velInit.."},"..step..","..tol..")")

   -- 計算結果を表示する。
   for i = 1, #mat do
      for j = 1, #mat[1] do
         gc:drawString(mat[i][j], (j-0.9) * 150, (i-0.5) * 15)
      end
   end

   -- 支点から「重りの現在位置」まで直線を引く。
   gc:drawLine(center.x, center.y, center.x + length * math.sin(mat[2][1]), center.y + length * math.cos(mat[2][1]))

   -- 計算された「次の角度、角速度」を初期値に入れ換える。
   angleInit = mat[2][2]
   velInit = mat[3][2]
end
function on.timer()
   platform.window:invalidate()
end