init: tool for graphing functions and slope fields in love2d

This commit is contained in:
Devyn Freet
2026-10-11 23:03:35 -04:00
parent 0bae59383e
commit db61937809
4 changed files with 243 additions and 0 deletions
+165
View File
@@ -0,0 +1,165 @@
local utf8 = require("utf8")
require("coordinates")
-- to use with functions involving e
--local e = require("eulerNumber")
local function differential(x, y)
return 2*y
end
local function loadWindow()
love.window.setTitle("Slope Fields")
love.keyboard.setKeyRepeat(true)
end
love.load = loadWindow
local function drawLine(line)
love.graphics.setColor(unpack(line.color))
love.graphics.line(line.p1.x, line.p1.y, line.p2.x, line.p2.y)
love.graphics.circle("fill", line.midpoint.x, line.midpoint.y, 4)
end
local width, height = love.window.getMode()
local boxMargin = 10
local boxHeight = math.max(height / 12, 20)
local textbox = {
x = boxMargin,
y = height - (boxHeight + boxMargin),
width = width - 2 * boxMargin,
height = boxHeight,
padding = 5,
text = 'x',
active = false,
colors = {
background = {0.2, 0.2, 0.2},
text = {0.9, 0.9, 0.9}
}
}
local graphbox = {
x = boxMargin,
y = boxMargin,
width = width - 2 * boxMargin,
height = textbox.y - 2 * boxMargin,
colors = {
background = {0.2, 0.2, 0.2}
}
}
local center = {
x = graphbox.x + graphbox.width / 2,
y = graphbox.y + graphbox.height / 2
}
local scale = 5
local xScale, yScale
local step
if graphbox.width <= graphbox.height then
step = graphbox.width / (2 * (scale+1))
xScale = scale
yScale = math.floor(graphbox.height / (2 * step)) - 1
else
step = graphbox.height / (2 * (scale+1))
yScale = scale
xScale = math.floor(graphbox.width / (2 * step)) - 1
end
local lines = {
grid = {},
axes = {
x = GetLineFromSlope(center, 0, graphbox.width),
y = GetLineFromSlope(center, nil, graphbox.height)
},
field = {}
}
local xpos, ypos = graphbox.x, graphbox.y + graphbox.height
for y = -yScale, yScale, 1 do
ypos = ypos - step
lines.grid[{y=y}] = GetLineFromSlope({x = center.x, y = ypos}, 0, graphbox.width, {0.3, 0.3, 0.3})
end
for x = -xScale, xScale, 1 do
xpos = xpos + step
lines.grid[{x=x}] = GetLineFromSlope({x = xpos, y = center.y}, nil, graphbox.height, {0.3, 0.3, 0.3})
ypos = graphbox.y + graphbox.height
for y = -yScale, yScale, 1 do
ypos = ypos - step
lines.field[{x, y}] = GetLineFromSlope({x = xpos, y = ypos}, differential(x,y), 50, {0, 0.5, 1})
end
end
local function func(x)
return x^2
end
local points = GraphFunction(graphbox.x, graphbox.y, graphbox.width, graphbox.height, func)
local function drawScene()
love.graphics.setColor(unpack(graphbox.colors.background))
love.graphics.rectangle('fill',
graphbox.x, graphbox.y,
graphbox.width, graphbox.height,
4, 4)
love.graphics.setColor(unpack(textbox.colors.background))
love.graphics.rectangle('fill',
textbox.x, textbox.y,
textbox.width, textbox.height,
4, 4)
love.graphics.setColor(unpack(textbox.colors.text))
love.graphics.printf(textbox.text,
textbox.x + textbox.padding, textbox.y + textbox.padding,
textbox.width, 'left', 0, 2, 2)
for _, line in pairs(lines.grid) do
drawLine(line)
end
for _, line in pairs(lines.axes) do
drawLine(line)
end
for _, line in pairs(lines.field) do
drawLine(line)
end
if points ~= nil then
love.graphics.setColor(0,1,0)
love.graphics.points(points)
end
end
love.draw = drawScene
local function textboxinput(text)
if textbox.active and string.match(text,"[xy+%-%/*%^%d()]") then
textbox.text = textbox.text .. text
end
end
love.textinput = textboxinput
local function keypress(key)
if key == "backspace" then
local byteoffset = utf8.offset(textbox.text, -1)
if byteoffset then
textbox.text = string.sub(textbox.text, 1, byteoffset - 1)
end
return
end
if key == "return" then
textbox.active = false
end
end
love.keypressed = keypress
local function mousepress(x, y)
if
x >= textbox.x and
x <= textbox.x + textbox.width and
y >= textbox.y and
y <= textbox.y + textbox.height
then
textbox.active = true
elseif textbox.active then
textbox.active = false
end
end
love.mousepressed = mousepress