Skip to content

Instantly share code, notes, and snippets.

@shallaa
Last active December 29, 2015 12:19
Show Gist options
  • Save shallaa/7669353 to your computer and use it in GitHub Desktop.
Save shallaa/7669353 to your computer and use it in GitHub Desktop.
당구공 물리.
-- Billiard
function setup()
parameter.watch("X")
parameter.watch("Y")
parameter.watch("MASS")
parameter.watch("VX")
parameter.watch("VY")
balls = {}
numBalls = 8
for i = 1, numBalls do
local r = math.random(20, 40)
balls[i] = Ball()
balls[i].i = i
balls[i].r = r
balls[i].m = r
balls[i].x = math.random(r, WIDTH)
balls[i].y = math.random(r, HEIGHT)
balls[i].vx = math.random(-5, 5)
balls[i].vy = math.random(-5, 5)
end
end
function draw()
background(0, 0, 0, 255)
for i, ball in ipairs(balls) do
ball.x = ball.x + ball.vx
ball.y = ball.y + ball.vy
checkWalls(ball)
for j = i + 1, numBalls do
checkCollision(ball, balls[j])
end
ball:draw()
end
X = balls[1].x
Y = balls[1].y
MASS = balls[1].m
VX = balls[1].vx
VY = balls[1].vy
end
function checkWalls(ball)
if ball.x + ball.r > WIDTH then
ball.x = WIDTH - ball.r
ball.vx = ball.vx * -1
elseif ball.x - ball.r < 0 then
ball.x = ball.r
ball.vx = ball.vx * -1
end
if ball.y + ball.r > HEIGHT then
ball.y = HEIGHT - ball.r
ball.vy = ball.vy * -1
elseif ball.y - ball.r < 0 then
ball.y = ball.r
ball.vy = ball.vy * -1
end
end
function checkCollision(ball0, ball1)
local dx = ball1.x - ball0.x
local dy = ball1.y - ball0.y
if math.sqrt(dx * dx + dy * dy) < ball0.r + ball1.r then
local a = math.atan2(dy, dx)
local s = math.sin(a)
local c = math.cos(a)
local p0 = vec2(0, 0)
local p1 = rotateP(dx, dy, s, c, true)
local v0 = rotateP(ball0.vx, ball0.vy, s, c, true)
local v1 = rotateP(ball1.vx, ball1.vy, s, c, true)
local vxt = v0.x - v1.x
v0.x = ((ball0.m - ball1.m) * v0.x + 2 * ball1.m * v1.x) / (ball0.m + ball1.m)
v1.x = vxt + v0.x
local av = math.abs(v0.x) + math.abs(v1.x)
local ol = (ball0.r + ball1.r) - math.abs(p0.x - p1.x)
p0.x = p0.x + v0.x / av * ol
p1.x = p1.x + v1.x / av * ol
local pf0 = rotateP(p0.x, p0.y, s, c, false)
local pf1 = rotateP(p1.x, p1.y, s, c, false)
ball1.x = ball0.x + pf1.x
ball1.y = ball0.y + pf1.y
ball0.x = ball0.x + pf0.x
ball0.y = ball0.y + pf0.y
local vf0 = rotateP(v0.x, v0.y, s, c, false)
local vf1 = rotateP(v1.x, v1.y, s, c, false)
ball0.vx = vf0.x
ball0.vy = vf0.y
ball1.vx = vf1.x
ball1.vy = vf1.y
end
end
function rotateP(x, y, s, c, r)
if r then
return vec2(x * c + y * s, y * c - x * s)
else
return vec2(x * c - y * s, y * c + x * s)
end
end
-- Ball
Ball = class()
function Ball:init()
self.x = 0
self.y = 0
self.r = 0
self.m = 0
self.i = 0
self.vx = 0
self.vy = 0
end
function Ball:draw()
if self.i == 1 then
fill(255, 0, 0, 255)
else
fill(255, 255, 255, 255)
end
ellipse(self.x, self.y, self.r * 2, self.r * 2)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment