Difference between revisions of "User:Darkfrei/example functions"
(→Push rectangle from line) |
(→Push rectangle from line) |
||
Line 245: | Line 245: | ||
return intersectX, intersectY, normalX, normalY | return intersectX, intersectY, normalX, normalY | ||
end | end | ||
+ | </source> | ||
+ | |||
+ | |||
+ | == Easy vector math == | ||
+ | |||
+ | <source lang="lua"> | ||
+ | -- Определение метатаблицы для векторов | ||
+ | local Vector = {} | ||
+ | Vector.__index = Vector | ||
+ | |||
+ | -- Конструктор вектора | ||
+ | function Vector.new(x, y) | ||
+ | local v = {x = x or 0, y = y or 0} | ||
+ | setmetatable(v, Vector) | ||
+ | return v | ||
+ | end | ||
+ | |||
+ | -- Перегрузка оператора сложения | ||
+ | function Vector.__add(a, b) | ||
+ | return Vector.new(a.x + b.x, a.y + b.y) | ||
+ | end | ||
+ | |||
+ | -- Перегрузка оператора вычитания | ||
+ | function Vector.__sub(a, b) | ||
+ | return Vector.new(a.x - b.x, a.y - b.y) | ||
+ | end | ||
+ | |||
+ | -- Перегрузка оператора умножения на скаляр | ||
+ | function Vector.__mul(a, b) | ||
+ | if type(a) == "number" then | ||
+ | return Vector.new(b.x * a, b.y * a) | ||
+ | elseif type(b) == "number" then | ||
+ | return Vector.new(a.x * b, a.y * b) | ||
+ | else | ||
+ | error("Can only multiply vector by scalar.") | ||
+ | end | ||
+ | end | ||
+ | |||
+ | -- Пример использования | ||
+ | local v1 = Vector.new(2, 3) | ||
+ | local v2 = Vector.new(4, 5) | ||
+ | local v3 = v1 + v2 -- v3 будет иметь координаты (6, 8) | ||
+ | local v4 = v1 - v2 -- v4 будет иметь координаты (-2, -2) | ||
+ | local v5 = v1 * 2 -- v5 будет иметь координаты (4, 6) | ||
+ | local v6 = 3 * v2 -- v6 будет иметь координаты (12, 15) | ||
+ | |||
+ | |||
+ | print ( | ||
+ | v1.x..' '..v1.y, | ||
+ | v2.x..' '..v2.y, | ||
+ | v3.x..' '..v3.y, | ||
+ | v4.x..' '..v4.y, | ||
+ | v5.x..' '..v5.y, | ||
+ | v6.x..' '..v6.y | ||
+ | ) | ||
</source> | </source> |
Revision as of 10:30, 23 February 2023
Contents
Prints table
print('{' ..table.concat(line,",")..'},')
Draw grid
function draw_grid ()
local grid_size = 20
love.graphics.setLineWidth (1)
love.graphics.setColor(0.25,0.25,0.25)
local width, height = love.graphics.getDimensions( )
for x = grid_size, width-1, grid_size do
love.graphics.line(x, 0, x, height)
end
for y = grid_size, height-1, grid_size do
love.graphics.line(0, y, width, y)
end
end
Draw mouse position
function draw_mouse ()
local mx, my = love.mouse.getPosition ()
local text = mx..' '..my
local font = love.graphics.getFont()
local w = font:getWidth(text)
local h = font:getHeight()
love.graphics.setColor(0,0,0)
love.graphics.rectangle('fill', mx, my-h, w, h)
love.graphics.setColor(1,1,1)
love.graphics.print(mx..' '..my,mx,my-h)
end
Beep
Define it:
local rate = 44100
local length = 1/32
local tone = 440 -- Hz
local p = math.floor(rate/tone) -- 128
local soundData = love.sound.newSoundData(length*rate, rate, 16, 1)
for i=0, length*rate-1 do soundData:setSample(i, i%p>p/2 and 1 or -1) end
local source = love.audio.newSource(soundData)
local function beep() source:play() end
Call it:
beep()
Point in area
function is_in_area (mx,my, x,y,w,h) -- mouse position and rectangle
if (mx > x) and (mx < (x + w)) and
(my > y) and (my < (y + h)) then
return true
end
end
Is value in list
function is_value_in_list (value, list)
for i, v in pairs (list) do
if v == value then
return true
end
end
end
Normalization and multiplication
Set magnitude to this vector:
function normul (x, y, factor) -- normalization and multiplication
local d = (x*x+y*y)^0.5
factor= factor or 1
return factor*x/d, factor*y/d
end
Evaluate a point from any amount of control points
local function evaluate (curve, t)
local ccpc = curve:getControlPointCount( )
if ccpc > 1 then
return curve:evaluate(t)
elseif ccpc == 1 then
return curve:getControlPoint(1)
else
return 0, 0
end
end
Split string with separator
local function split (string, separator)
local tabl = {}
for str in string.gmatch(string, "[^"..separator.."]+") do
table.insert (tabl, str)
end
return tabl
end
--split ("123#456", "#") -- results: {"123", "456"}
Split string to list of symbols
local function split2 (string)
local tabl = {}
string:gsub(".", function(c) table.insert(tabl, tonumber (c)) end)
return tabl
end
--split2 ("123") -- results: {1, 2, 3}
Push rectangle from line
(made with chatGPT Feb 13 2023)
function pushRectOutOfLine(x, y, w, h, x1, y1, x2, y2)
-- Вычисляем вектор направления линии
local lineDirX = x2 - x1
local lineDirY = y2 - y1
-- Нормализуем вектор направления линии
local lineLength = math.sqrt(lineDirX^2 + lineDirY^2)
lineDirX = lineDirX / lineLength
lineDirY = lineDirY / lineLength
-- Вычисляем вектор от начальной точки линии до прямоугольника
local toRectX = x - x1
local toRectY = y - y1
-- Проекция вектора от начальной точки линии до прямоугольника на вектор направления линии
local dot = toRectX * lineDirX + toRectY * lineDirY
-- Находим ближайшую точку на линии
local nearestX, nearestY
if dot <= 0 then
nearestX, nearestY = x1, y1
elseif dot >= lineLength then
nearestX, nearestY = x2, y2
else
nearestX = x1 + dot * lineDirX
nearestY = y1 + dot * lineDirY
end
-- Вычисляем вектор от ближайшей точки на линии до прямоугольника
local toRectX = x - nearestX
local toRectY = y - nearestY
-- Если прямоугольник пересекает линию
if math.abs(toRectX) < w/2 and math.abs(toRectY) < h/2 then
-- Вычисляем вектор выталкивания
local pushX = (w/2 - math.abs(toRectX)) * math.sign(toRectX)
local pushY = (h/2 - math.abs(toRectY)) * math.sign(toRectY)
-- Возвращаем вектор выталкивания и нормаль линии
return pushX, pushY, lineDirX, lineDirY
end
return 0, 0, 0, 0
end
Short version:
function PushOutRectangleFromLine(x, y, w, h, x1, y1, x2, y2)
local toRectX, toRectY = x - x1, y - y1
local lineDirectionX, lineDirectionY = x2 - x1, y2 - y1
local lineLength = math.sqrt(lineDirectionX^2 + lineDirectionY^2)
lineDirectionX, lineDirectionY = lineDirectionX / lineLength, lineDirectionY / lineLength
local dotProduct = toRectX * lineDirectionX + toRectY * lineDirectionY
local closestPointX, closestPointY = x1 + dotProduct * lineDirectionX, y1 + dotProduct * lineDirectionY
local distanceX, distanceY = x - closestPointX, y - closestPointY
local intersectX, intersectY = closestPointX, closestPointY
if dotProduct < 0 then
intersectX, intersectY = x1, y1
distanceX, distanceY = x - x1, y - y1
elseif dotProduct > lineLength then
intersectX, intersectY = x2, y2
distanceX, distanceY = x - x2, y - y2
end
if math.abs(distanceX) < w / 2 and math.abs(distanceY) < h / 2 then
local pushX, pushY = 0, 0
if w / 2 - math.abs(distanceX) < h / 2 - math.abs(distanceY) then
pushX = math.sign(distanceX) * (w / 2 - math.abs(distanceX))
else
pushY = math.sign(distanceY) * (h / 2 - math.abs(distanceY))
end
return pushX, pushY
end
return 0, 0
end
(fixed normal)
function PushOutRectangleFromLine(x, y, w, h, x1, y1, x2, y2)
local toRectX, toRectY = x - x1, y - y1
local lineLength = math.sqrt((x2 - x1) ^ 2 + (y2 - y1) ^ 2)
local normalX, normalY = (y2 - y1) / lineLength, -(x2 - x1) / lineLength
local dot = toRectX * normalX + toRectY * normalY
local intersectX, intersectY = x - dot * normalX, y - dot * normalY
if intersectX < x then
intersectX = x
elseif intersectX > x + w then
intersectX = x + w
end
if intersectY < y then
intersectY = y
elseif intersectY > y + h then
intersectY = y + h
end
local distance = (toRectX - intersectX) * normalX + (toRectY - intersectY) * normalY
if distance < 0 then
intersectX = intersectX + distance * normalX
intersectY = intersectY + distance * normalY
end
return intersectX, intersectY, normalX, normalY
end
Easy vector math
-- Определение метатаблицы для векторов
local Vector = {}
Vector.__index = Vector
-- Конструктор вектора
function Vector.new(x, y)
local v = {x = x or 0, y = y or 0}
setmetatable(v, Vector)
return v
end
-- Перегрузка оператора сложения
function Vector.__add(a, b)
return Vector.new(a.x + b.x, a.y + b.y)
end
-- Перегрузка оператора вычитания
function Vector.__sub(a, b)
return Vector.new(a.x - b.x, a.y - b.y)
end
-- Перегрузка оператора умножения на скаляр
function Vector.__mul(a, b)
if type(a) == "number" then
return Vector.new(b.x * a, b.y * a)
elseif type(b) == "number" then
return Vector.new(a.x * b, a.y * b)
else
error("Can only multiply vector by scalar.")
end
end
-- Пример использования
local v1 = Vector.new(2, 3)
local v2 = Vector.new(4, 5)
local v3 = v1 + v2 -- v3 будет иметь координаты (6, 8)
local v4 = v1 - v2 -- v4 будет иметь координаты (-2, -2)
local v5 = v1 * 2 -- v5 будет иметь координаты (4, 6)
local v6 = 3 * v2 -- v6 будет иметь координаты (12, 15)
print (
v1.x..' '..v1.y,
v2.x..' '..v2.y,
v3.x..' '..v3.y,
v4.x..' '..v4.y,
v5.x..' '..v5.y,
v6.x..' '..v6.y
)