2025-11-16 22:51:51 -05:00
|
|
|
local inspect = require('inspect')
|
|
|
|
|
|
2025-11-16 12:06:35 -05:00
|
|
|
local phys = {
|
|
|
|
|
tau = 2 * math.pi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-- returns true if the two actors intersect
|
|
|
|
|
function phys.intersects(actor1, actor2)
|
|
|
|
|
return (actor1.x - actor2.x) ^ 2 + (actor1.y - actor2.y) ^ 2 <= (actor1.radius + actor2.radius) ^ 2
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
-- updates the actor's location by applying the passage of time
|
|
|
|
|
-- TODO spin
|
|
|
|
|
function phys.update(actor, dt)
|
2025-11-16 22:51:51 -05:00
|
|
|
assert(actor.speed >= 0)
|
2025-11-16 12:06:35 -05:00
|
|
|
local dv = actor.speed * dt
|
|
|
|
|
actor.x = actor.x + math.cos(actor.angle) * dv
|
|
|
|
|
actor.y = actor.y + math.sin(actor.angle) * dv
|
|
|
|
|
end
|
|
|
|
|
|
2025-11-16 22:51:51 -05:00
|
|
|
function phys.rotate(actor, angle)
|
|
|
|
|
actor.angle = (actor.angle + angle) % phys.tau
|
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
function phys.apply(actor, force)
|
|
|
|
|
assert(actor.speed >= 0)
|
|
|
|
|
assert(force.speed >= 0)
|
|
|
|
|
local ax = math.cos(actor.angle) * actor.speed
|
|
|
|
|
local ay = math.sin(actor.angle) * actor.speed
|
|
|
|
|
local fx = math.cos(force.angle) * force.speed
|
|
|
|
|
local fy = math.sin(force.angle) * force.speed
|
|
|
|
|
local x = ax + fx
|
|
|
|
|
local y = ay + fy
|
|
|
|
|
|
|
|
|
|
local speed = math.sqrt(x ^ 2 + y ^ 2)
|
|
|
|
|
local angle = math.atan(y, x) % phys.tau
|
|
|
|
|
actor.speed = speed
|
|
|
|
|
actor.angle = angle
|
|
|
|
|
end
|
|
|
|
|
|
2025-11-16 12:06:35 -05:00
|
|
|
return phys
|