Drawing with a pen on a pendulum
Lua Carousel » Devlog

The kids have been playing with a pen on a pendulum, and I started wanting to tweak the friction on it.
-- We have a surface we view through a viewport.
-- The surface has the same dimensions as the viewport: Carousel's Safe_width x Safe_height.
local w = Safe_width/2
local h = Safe_height/2
-- (w, h) in surface coordinates is at (center.x, center.y) in viewport coordinates
local center = {type='viewport', x=w, y=h}
local vel = {x=0, y=0}
local mx0,my0
local V = 2 -- velocity coefficient when dragging
function s(vp)
assert(vp.type == 'viewport')
return {type='surface',
x=w - center.x + vp.x,
y=h - center.y + vp.y}
end
function v(sp)
assert(sp.type == 'surface')
return {type='viewport',
x=center.x - w + sp.x,
y=center.y - w + sp.y}
end
local points = {} -- in surface coordinates
local State = {name='init'} -- move draw
local niters = 1000000
local K = 1 -- Hooke's constant
local f = 0.01 -- 0 = no friction
local colors = {
{0,0,0}, -- black
{1,0,0}, -- red
{0,1,0}, -- green
{0.2,0.2,1}, -- blue
}
local color_index = 1 -- black at the start
function draw_colors()
for i, c in ipairs(colors) do
if i == color_index then
color(0.8,0.8,0.8)
rect('fill', 50-20, 50+i*50-20, 40,40, 2,2)
end
color(unpack(c))
circle('fill', 50, 50+i*50, 20)
end
end
function change_color(mx,my)
for i, c in ipairs(colors) do
if dist(mx,my, 50, 50+i*50) < 20 then
color_index = i
return true
end end end
function car.draw()
draw_colors()
color(0.5,0.5,0.5)
rect('line', center.x-w, center.y-h, w*2, h*2)
line(center.x-w, center.y, center.x+w, center.y)
line(center.x, center.y-h, center.x, center.y+h)
color(0,0,0)
local p1
for _,p2 in ipairs(points) do
color(unpack(p2.color))
local vp2 = v(p2)
if p1 then
local vp1 = v(p1)
line(vp1.x, vp1.y, vp2.x, vp2.y)
end
p1 = p2
end
if State.name == 'draw' then
circle('fill', w,h, 2)
end
end
function car.mousepressed(mx,my)
if change_color(mx,my) then return end
mx0,my0 = mx,my
if State.name ~= 'init' then return end
points = {}
State = {name='move', x=mx, y=my}
end
function car.mousereleased(mx,my)
if mx0 == nil then return end
vel.x = (mx-mx0)*V
vel.y = (my-my0)*V
mx0,my0 = nil
end
function car.update(dt)
local s = State.name
if s == 'move' then
umove(dt)
elseif s == 'draw' then
udraw(dt)
end
end
function umove(dt)
if abs(center.x - 2*w + State.x) < 1 then
State = {name='draw', iters = 0}
return
end
center.x = center.x - (State.x - w)*dt
center.y = center.y - (State.y - h)*dt
end
function udraw(dt)
State.iters = State.iters+1
if State.iters >= niters then
State = {name='init'}
center = {type='viewport', x=w, y=h}
vel = {type='viewport', x=0, y=0}
return
end
local ax = -K*(center.x-w)
local ay = -K*(center.y-h)
vel.x = (1 - f*dt) * (vel.x + ax*dt)
vel.y = (1 - f*dt) * (vel.y + ay*dt)
local x = center.x + vel.x*dt
local y = center.y + vel.y*dt
local p = s{type='viewport', x=w, y=w}
p.color = colors[color_index]
table.insert(points, p)
center.x, center.y = x, y
end
function dist(x1,y1, x2,y2)
return math.sqrt((x1-x2)^2 + (y1-y2)^2)
end
Don't forget to first run the abbreviations on one of the example screens. Or if you've deleted that screen, here are the abbreviations I used in this post:
g = love.graphics line = g.line rect = g.rectangle circle = g.circle color = g.setColor abs = math.abs
Files
carousel2-ak.love 103 kB
Jan 04, 2025
Get Lua Carousel
Lua Carousel
Write programs on desktop and mobile
| Status | In development |
| Category | Tool |
| Author | Kartik Agaram |
| Tags | LÖVE |
More posts
- Programming on your device with your preferred language53 days ago
- Lua Carousel: program on the device you have, with docs at your fingertipsMay 12, 2025
- Pong Wars, MMO editionFeb 16, 2025
- New version after 41 days, and stop-motion animationFeb 15, 2025
- New version after 16 daysJan 04, 2025
- New version after 9 daysDec 19, 2024
- New version after 3 daysNov 17, 2024
- New version after 40 daysNov 14, 2024
- Turn your phone or tablet into a chess clockNov 01, 2024
Leave a comment
Log in with itch.io to leave a comment.