物理エンジンを使う 3, 円を円にぶつける

-- 物理エンジンを使う 3, 円を円にぶつける
require "physics"

W, H = platform.window:width(), platform.window:height()

dt      = 0.01   
gravity = 0

mass    = 0.1
radius  = W/30
inertia = physics.misc.momentForCircle(mass, 0, radius, physics.Vect(0, 0)) -- 円形の慣性モーメントを計算するヘルパールーチン。第 2 引数は内半径、第 3 引数は外半径、第 4 引数は重心からのずれ(ベクトルで設定する)。

friction   = 1
elasticity = 1

angle1 = -math.pi/2
angle2 = -math.pi/2

velX1, velY1 = 60, 0
posX1, posY1 = 0, H/2

velX2, velY2 = 0, 0
posX2, posY2 = W/3, H/2.4

space = physics.Space()
space:setGravity(physics.Vect(0, gravity))

newBody1 = physics.Body(mass, inertia)
newBody1:setVel(physics.Vect(velX1, velY1))
newBody1:setPos(physics.Vect(posX1, posY1))
newBody1:setAngle(angle1)
newShape1 = physics.CircleShape(newBody1, radius, physics.Vect(0, 0)) -- Body に関連付ける Shape を作る。第 3 引数は重心からのずれ(ベクトルで設定する)。 
newShape1:setRestitution(elasticity)
newShape1:setFriction(friction)
space:addBody(newBody1)
space:addShape(newShape1) -- Body と同じく Shape も空間へ投入する。

newBody2 = physics.Body(mass, inertia) 
newBody2:setVel(physics.Vect(velX2, velY2))
newBody2:setPos(physics.Vect(posX2, posY2))
newBody2:setAngle(angle2)
newShape2 = physics.CircleShape(newBody2, radius, physics.Vect(0, 0))
newShape2:setRestitution(elasticity)
newShape2:setFriction(friction)
space:addBody(newBody2)
space:addShape(newShape2)

function on.paint(gc)
   fillCircleCenter(posX1, posY1, radius, angle1, 0x7171C6, gc)
   fillCircleCenter(posX2, posY2, radius, angle2, 0x388E8E, gc)
end
function on.timer()
   space:step(dt)
   
   pos1  = newBody1:pos()
   posX1, posY1 = pos1:x(), pos1:y()
   
   pos2  = newBody2:pos()
   posX2, posY2 = pos2:x(), pos2:y()
   
   angle1 = newBody1:angle()
   angle2 = newBody2:angle()
   print(angle1, angle2)
   platform.window:invalidate()
end
function on.enterKey()
   timer.start(dt)
end

-----------------------
-- general functions --
-----------------------
function fillCircleCenter(cx, cy, radius, radian, color, gc)
   gc:setColorRGB(color)
   gc:fillArc(cx - radius, cy - radius, radius + radius, radius + radius, 0, 360)
   gc:setColorRGB(0x000000)
   gc:drawLine(cx, cy, cx + radius * math.sin(-radian), cy + radius  * math.cos(-radian))
end