Posted December 27, 2023 by Kartik Agaram
New version with just a couple of minor tweaks:
Today's program is a small equation plotter:
v = {x=-5, y=-5*Safe_height/Safe_width} v.w, v.h = -2*v.x, -2*v.y v.zoom = Safe_width/v.w f,s = nil -- ids of first and second touches start, curr = {}, {} -- coords of touches initzoom = nil initpos = nil -- for panning function car.draw() color(0.5,0.5,0.5) line(0, vy(0), Safe_width, vy(0)) line(vx(0), 0, vx(0), Safe_height) color(0,0,1) plot(sin) color(0,0.6,0) plot(function(x) return sin(2*x) end) color(0,0.8,1) plot(function(x) return 2*sin(x) end) color(0.8,0.6,0) plot(function(x) return x^2 end) color(0.5, 0.5, 0.5) for _,touch in ipairs(touches()) do if curr[touch] then circle('fill', curr[touch].x, curr[touch].y, 10) end end end function plot(f) for vx=0,Safe_width do circle('fill', vx, vy(f(sx(vx))), 1) end end function car.touchpressed(id, x,y, ...) if f == nil then f = id initpos = {x=v.x, y=v.y} else s = id initzoom = v.zoom end start[id] = {x=x, y=y} curr[id] = {x=x, y=y} end function car.touchreleased(id, x,y, ...) f,s = nil start, curr = {}, {} initzoom = nil initpos = nil end function car.touchmoved(id, x,y, ...) if start[id] then curr[id] = {x=x, y=y} if s then local oldzoom = v.zoom v.zoom = dist(curr[f], curr[s])/dist(start[f], start[s])*initzoom adjust_viewport(oldzoom, v.zoom) elseif f then v.x = initpos.x + iscale(start[f].x - x) v.y = initpos.y + iscale(start[f].y - y) end end end function adjust_viewport(oldzoom, zoom) -- ensure centroid of fingers remains in view local c = centroid(curr[f], curr[s]) v.x = v.x + c.x/oldzoom - c.x/zoom v.y = v.y + c.y/oldzoom - c.y/zoom end function centroid(a, b) return{x=(a.x+b.x)/2, y=(a.y+b.y)/2} end function vx(sx) return scale(sx-v.x) end function vy(sy) return scale(sy-v.y) end function scale(d) return d*v.zoom end function sx(vx) return v.x + iscale(vx) end function sy(vy) return v.y + iscale(vy) end function iscale(d) return d/v.zoom end function dist(p1, p2) return ((p2.x-p1.x)^2 + (p2.y-p1.y)^2) ^ 0.5 end
If you try pasting this program into Lua Carousel, remember 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, circle = g.line, g.circle color = g.setColor sin = math.sin touches = love.touch.getTouches