215 lines
5.2 KiB
Lua
215 lines
5.2 KiB
Lua
-- NEEDS OPTIMIZATIONS
|
|
local angle = 0
|
|
local relativeGap = 0.5
|
|
local relativeMarker = 0.1
|
|
local relativeWidth = 0.08
|
|
local rows, cols, circles, curves, markerSize, gap
|
|
local opacity = 0.3
|
|
local constants = {
|
|
circleRadius = 20,
|
|
speed = 1,
|
|
drawLines = false,
|
|
colors = true,
|
|
drawMarkers = true,
|
|
drawCircles = true,
|
|
drawTable = true
|
|
}
|
|
|
|
function HSV(h, s, v, a)
|
|
if s <= 0 then return v,v,v end
|
|
h, s, v = h/256*6, s/255, v/255
|
|
local c = v*s
|
|
local x = (1-math.abs((h%2)-1))*c
|
|
local m,r,g,b = (v-c), 0,0,0
|
|
if h < 1 then r,g,b = c,x,0
|
|
elseif h < 2 then r,g,b = x,c,0
|
|
elseif h < 3 then r,g,b = 0,c,x
|
|
elseif h < 4 then r,g,b = 0,x,c
|
|
elseif h < 5 then r,g,b = x,0,c
|
|
else r,g,b = c,0,x
|
|
end return (r+m),(g+m),(b+m), a or 1
|
|
end
|
|
|
|
function addColors(h1, h2)
|
|
local r1, g1, b1, a1 = HSV(h2, 255, 255)
|
|
local r2, g2, b2, a2 = HSV(h1, 255, 255)
|
|
return (r1+r2)/2, (g1+g2)/2, (b1+b2)/2, (a1+a2)/2
|
|
end
|
|
|
|
local function distance(x1,y1,x2,y2)
|
|
return ((x1-x2)^2 + (y1-y2)^2)^0.5
|
|
end
|
|
|
|
function Curve()
|
|
local self = {}
|
|
self._points = {}
|
|
self.draw = function(self)
|
|
if #self._points >= 4 then
|
|
love.graphics.line(self._points)
|
|
end
|
|
end
|
|
self.addPoint = function(self, x, y)
|
|
table.insert(self._points, x)
|
|
table.insert(self._points, y)
|
|
end
|
|
self.clear = function(self)
|
|
self._points = {}
|
|
end
|
|
return self
|
|
end
|
|
|
|
function genTable(default, N)
|
|
local t = {}
|
|
for i=0, N-1 do
|
|
if type(default) == "function" then
|
|
t[i] = default()
|
|
else
|
|
t[i] = default
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
|
|
function roundDown(X)
|
|
return X - (X / 10)
|
|
end
|
|
|
|
function recalc(w, h)
|
|
local realSize = (relativeGap + 1) * constants.circleRadius
|
|
local rows = roundDown(w / realSize)
|
|
local cols = roundDown(h / realSize)
|
|
circles = genTable(angle, math.max(rows, cols))
|
|
curves = {}
|
|
for i=0, rows-1 do
|
|
curves[i] = genTable(Curve, cols)
|
|
end
|
|
end
|
|
|
|
function love.load(args, unfilteredArgs)
|
|
for i=1,#args do
|
|
for name in pairs(constants) do
|
|
if "-"..name == args[i] then
|
|
if type(constants[name]) == "boolean" then
|
|
constants[name] = args[i+1] == "true"
|
|
elseif type(constants[name]) == "number" then
|
|
constants[name] = tonumber(args[i+1])
|
|
end
|
|
i = i + 1
|
|
break
|
|
end
|
|
end
|
|
end
|
|
|
|
markerSize = constants.circleRadius*relativeMarker
|
|
gap = constants.circleRadius*(1+relativeGap)
|
|
|
|
recalc(love.graphics.getDimensions())
|
|
end
|
|
|
|
function love.update(dt)
|
|
angle = angle + constants.speed * dt
|
|
for i in pairs(circles) do
|
|
circles[i] = angle * (i+1)
|
|
end
|
|
if angle > math.pi*2 then
|
|
angle = angle % math.pi*2
|
|
for _, j in pairs(curves) do
|
|
for _, curve in pairs(j) do
|
|
curve:clear()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function setColor(r,g,b,a)
|
|
if constants.colors then
|
|
love.graphics.setColor(r,g,b,a)
|
|
else
|
|
love.graphics.setColor(1, 1, 1, a)
|
|
end
|
|
end
|
|
|
|
function drawMarker(x, y)
|
|
if constants.drawMarkers then
|
|
love.graphics.circle("fill", x, y, markerSize)
|
|
end
|
|
end
|
|
|
|
function drawCircle(x, y)
|
|
if constants.drawCircles then
|
|
love.graphics.circle("line", x, y, constants.circleRadius)
|
|
end
|
|
end
|
|
|
|
function love.draw()
|
|
local w,h = love.graphics.getDimensions()
|
|
|
|
love.graphics.setLineJoin("none")
|
|
love.graphics.setLineStyle("smooth")
|
|
-- Circles and lines
|
|
for i, circleAngle in pairs(circles) do
|
|
local dist = constants.circleRadius + (i+1) * gap*2
|
|
local p = i/#circles
|
|
|
|
-- X-axis
|
|
if dist+gap < w then
|
|
local x = dist + constants.circleRadius * math.cos(circleAngle-math.pi/2)
|
|
local y = gap + constants.circleRadius * math.sin(circleAngle-math.pi/2)
|
|
setColor(HSV(p*511, 255, 255))
|
|
love.graphics.setLineWidth(constants.circleRadius * relativeWidth)
|
|
drawMarker(x, y)
|
|
drawCircle(dist, gap)
|
|
|
|
if constants.drawLines then
|
|
setColor(HSV(p*511, 255, 255, opacity))
|
|
love.graphics.line(x, 0, x, h)
|
|
end
|
|
end
|
|
-- Y-axis
|
|
if dist+gap < h then
|
|
local x = gap + constants.circleRadius * math.cos(circleAngle-math.pi/2)
|
|
local y = dist + constants.circleRadius * math.sin(circleAngle-math.pi/2)
|
|
setColor(HSV(p*511, 255, 255))
|
|
love.graphics.setLineWidth(constants.circleRadius * relativeWidth)
|
|
drawMarker(x, y)
|
|
drawCircle(gap, dist)
|
|
|
|
if constants.drawLines then
|
|
setColor(HSV(p*511, 255, 255, opacity))
|
|
love.graphics.line(0, y, w, y)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Draw intersection point
|
|
for i, circleAngle1 in pairs(circles) do
|
|
for j, circleAngle2 in pairs(circles) do
|
|
local distX = (constants.circleRadius + (i+1) * gap*2)
|
|
local distY = (constants.circleRadius + (j+1) * gap*2)
|
|
if distX+gap < w and distY+gap < h then
|
|
local x = constants.circleRadius * math.cos(circleAngle1-math.pi/2) + distX
|
|
local y = constants.circleRadius * math.sin(circleAngle2-math.pi/2) + distY
|
|
|
|
setColor(addColors(i/#circles*511, j/#circles*511))
|
|
drawMarker(x, y)
|
|
curves[i][j]:addPoint(x, y)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Draw curves
|
|
if constants.drawTable then
|
|
for n1, j in pairs(curves) do
|
|
for n2, curve in pairs(j) do
|
|
setColor(addColors(n1/#circles*511, n2/#circles*511))
|
|
curve:draw()
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function love.resize(w, h)
|
|
angle = 0
|
|
recalc(w,h)
|
|
end
|