1
0

feat: Pack circles into an area using a stencil

This commit is contained in:
Rokas Puzonas 2021-06-01 20:55:22 +03:00
parent a43f26353e
commit a97161b582
6 changed files with 150 additions and 0 deletions

25
.lua-format Normal file
View File

@ -0,0 +1,25 @@
column_limit: 80
indent_width: 1
use_tab: true
tab_width: 2
continuation_indent_width: 1
spaces_before_call: 0
keep_simple_control_block_one_line: true
keep_simple_function_one_line: false
align_args: false
break_after_functioncall_lp: false
break_before_functioncall_rp: false
align_parameter: true
chop_down_parameter: true
break_after_functiondef_lp: false
break_before_functiondef_rp: false
align_table_field: true
break_after_table_lb: true
break_before_table_rb: true
chop_down_table: true
chop_down_kv_table: true
table_sep: ","
extra_sep_at_table_end: false
break_after_operator: true
double_quote_to_single_quote: false
single_quote_to_double_quote: true

32
Circle.lua Normal file
View File

@ -0,0 +1,32 @@
local Circle = {}
Circle.__index = Circle
function Circle.new(class, x, y)
local self = setmetatable({}, class)
self.x = x
self.y = y
self.r = 1
self.growing = true
return self
end
function Circle:grow(grow_speed)
if self.growing then
self.r = self.r + (grow_speed or 1)
end
end
function Circle:edges()
local w, h = love.graphics.getDimensions()
return self.x + self.r > w or self.x - self.r < 0 or self.y + self.r > h or
self.y - self.r < 0
end
function Circle:draw()
love.graphics.circle("line", self.x, self.y, self.r)
end
return Circle

View File

@ -1,5 +1,7 @@
# Circle packing
![Exampel](example.gif)
I was inspired by this video "[Coding Challenge #50.1: Animated Circle Packing](https://www.youtube.com/watch?v=QHEQuoIKgNE)".
So yeah, this is my implementation of that, but with Lua and a couple extra features.

BIN
example.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 613 KiB

View File

@ -0,0 +1,91 @@
local Circle = require("Circle")
local circles = {}
local spots = {}
function love.load()
local stencil_data = love.image.newImageData("stencil.png")
local w, h = stencil_data:getDimensions()
for x=0, w-1 do
for y=0, h-1 do
local r, g, b = stencil_data:getPixel(x, y)
local brigthness = (r + g + b)/3
if brigthness > 0.9 then
table.insert(spots, { x, y })
end
end
end
end
local function dist(x1, y1, x2, y2)
return ((x1-x2)^2 + (y1-y2)^2)^0.5
end
local function isInCircle(x, y)
for _, circle in ipairs(circles) do
local d = dist(circle.x, circle.y, x, y)
if d < circle.r then
return true
end
end
end
local function areCirclesOverlapping(circle1, circle2)
local d = dist(circle1.x, circle1.y, circle2.x, circle2.y)
if d - 2 < circle1.r + circle2.r then
return true
end
end
local function isCircleOverlapping(circle)
for _, other_circle in ipairs(circles) do
if other_circle ~= circle and areCirclesOverlapping(circle, other_circle) then
return true
end
end
end
local function createCircle()
local w, h = love.graphics.getDimensions()
-- local x = love.math.random(0, w)
-- local y = love.math.random(0, h)
local index = love.math.random(1, #spots)
local x = spots[index][1]
local y = spots[index][2]
if isInCircle(x, y) then return end
return Circle:new(x, y)
end
function love.update(dt)
local total = 3
for _=1, total do
local c = createCircle()
if c then
table.insert(circles, c)
end
end
for _, circle in ipairs(circles) do
if circle.growing then
if isCircleOverlapping(circle) then
circle.growing = false
end
if circle:edges() then
circle.growing = false
end
end
circle:grow(5*dt)
end
end
function love.draw()
for _, circle in ipairs(circles) do
circle:draw()
end
end

BIN
stencil.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB