## Small Useful Functions

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
I~=Spam
Party member
Posts: 206
Joined: Fri Dec 14, 2012 11:59 pm

### Re: Small Useful Functions

I don't think this is usable because of the license because it is strait out of garry's mod client...
My Tox ID: 0F1FB9170B94694A90FBCF6C4DDBDB9F58A9E4CDD0B4267E50BF9CDD62A0F947E376C5482610

Inny
Party member
Posts: 652
Joined: Fri Jan 30, 2009 3:41 am
Location: New York

### Re: Small Useful Functions

I like coroutine.wrap, but it has the one deficiency that it eats errors and makes debugging coroutines hard. So this is my better version:

Code: Select all

local function error_wrap(co, err, ...)
if err == false then
io.stderr:write(debug.traceback(co))
error(...)
else
return ...
end
end

function COWRAP(start)
local co = coroutine.create(start)
return function(...)
return error_wrap(co, coroutine.resume(co, ...))
end
end

HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Somewhere in Brazil
Contact:

### Re: Small Useful Functions

I ran on a few problems with my translation functions I previously posted here:
viewtopic.php?p=185159#p185159 (last page of this very thread)

It turns out that, the way I had it set up, would make multiple translations in the same push/pop stop working. It wouldn't crash the game, but rather glitch out things like scissors and other translations further ahead. Here's the fi:xed version, though. Same functionalities, nothing changed:

Code: Select all

_translate = love.graphics.translate
_translateX, _translateY = {0}, {0}
_translateCounter = {0}
_pop = love.graphics.pop
_push = love.graphics.push
_origin = love.graphics.origin
_scissor = love.graphics.setScissor

function love.graphics.pop()
for i = 1, _translateCounter[#_translateCounter] do
table.remove(_translateX)
table.remove(_translateY)
end
table.remove(_translateCounter)
_pop()
end

function love.graphics.push()
table.insert(_translateCounter, 0)
_push()
end

function love.graphics.translate(x, y)
table.insert(_translateX, x)
table.insert(_translateY, y)
_translateCounter[#_translateCounter] = _translateCounter[#_translateCounter] + 1
_translate(x, y)
end

function love.graphics.getTranslation()
return love.graphics.getTranslationX(), love.graphics.getTranslationY()
end

function love.graphics.getTranslationX()
local x = 0
for i, v in ipairs(_translateX) do
x = x + v
end
return x
end

function love.graphics.getTranslationY()
local y = 0
for i, v in ipairs(_translateY) do
y = y + v
end
return y
end

function love.graphics.origin()
for i = 1, _translateCounter[#_translateCounter] do
_translateX[#_translateX - (i-1)] = 0
_translateY[#_translateY - (i-1)] = 0
end
_origin()
end

function love.graphics.setScissor(x, y, w, h)
if x and type(x) == "number" then
x = x + love.graphics.getTranslationX()
end
if y and type(y) == "number" then
y = y + love.graphics.getTranslationY()
end
_scissor(x, y, w, h)
end

HugoBDesigner - my Blog

ejmr
Party member
Posts: 302
Joined: Fri Jun 01, 2012 7:45 am
Location: South Carolina, U.S.A.
Contact:

### Re: Small Useful Functions

A utility to map a function to all values in a table, which also supports partial application.

Code: Select all

function table.map(f, t)
local function apply(values)
local results = {}
for index,value in pairs(values) do
results[index] = f(value)
end
return results
end

if t then
return apply(t)
else
return apply
end
end

A detailed explanation of the code and its uses.
ejmr :: Programming and Game-Dev Blog, GitHub

Ref
Party member
Posts: 682
Joined: Wed May 02, 2012 11:05 pm

### Re: Small Useful Functions

Was playing around with the Box2D tut and found that it is difficult to read the text which was being printed to the screen. The text string is erased when a fixed number of characters are in the string.

My first attempt was to remove the first line of text when a fixed number of characters was reached. Worked but since the number of characters per line varies, the number of lines on the screen varied.

The following code compares the number of lines in the string (as defined by '\n') and deletes the appropriate number of lines from the top to insure only a fixed number of lines will be shown. Works but someone probably has a better function. For debugging, efficiency not too important.

Code: Select all

function scrollText( text, limit )	-- retain only most recent lines (limit determines number)
local limit, numlines, location = limit or 20, 0, {}
location[0]	= 0
while true do
location[ numlines+1 ]		= string.find( text, "\n", location[numlines] + 1 )
if location[ numlines+1 ]	== nil then
break
else
numlines = numlines + 1
end
end
if numlines > limit then
text = string.sub( text, location[ numlines - limit ], #text )
end
return text
end

test

Code: Select all

text = ' line 7\n line 6\n line 5\n line 4\n line 3\n line 2\n line 1\n'
text = scrollText( text, 5 )
print( text )

line 5
line 4
line 3
line 2
line 1


s-ol
Party member
Posts: 1076
Joined: Mon Sep 15, 2014 7:41 pm
Location: Cologne, Germany
Contact:

### Re: Small Useful Functions

Ref wrote:Was playing around with the Box2D tut and found that it is difficult to read the text which was being printed to the screen. The text string is erased when a fixed number of characters are in the string.
-snip-
[/code]
You can use font:getWrap() to find how mans lines text will take up when drawn and wrapped at a certain width (using love.graphics.printf).

s-ol.nu /blog  -  p.s-ol.be /st8.lua  -  g.s-ol.be /gtglg /curcur

Code: Select all

print( type(love) )
if false then
baby:hurt(me)
end

Ref
Party member
Posts: 682
Joined: Wed May 02, 2012 11:05 pm

### Re: Small Useful Functions

Hi Soillos!
Thanks for response.
I'm doing something much less sophisticated.
Not wrapping text, just breaking up a string containing data lines separated by '\n' and only displaying the last # lines.
That way the last entry is always at the same spot on the screen with the last # data lines above it.
(Inefficient process creating multiple new string every time new data added.)
Makes it easy to see who is colliding with what and when it is released.

Obviously other ways to do this (like putting the data into a table) but just trying to patch a existing Box2D tut to help learn love.physics.

bakpakin
Party member
Posts: 114
Joined: Sun Mar 15, 2015 9:29 am
Location: Boston

### Re: Small Useful Functions

Here's some code I wrote for getting the intersection of two lines (not line segments).
The lines run from (x1, y1) to (x2, y2) and (x3, y3) to (x4, y4).
Returns false if there is no intersection (i.e. they're parallel), otherwise returns the coordinate of intersection.

Code: Select all

function intersect(x1, y1, x2, y2, x3, y3, x4, y4)
local x21, x43 = x2 - x1, x4 - x3
local y21, y43 = y2 - y1, y4 - y3
local d = x21 * y43 - y21 * x43
if d == 0 then return false end
local xy34 = x3 * y4 - y3 * x4
local xy12 = x1 * y2 - y1 * x2
local a = xy34 * x21 - xy12 * x43
local b = xy34 * y21 - xy12 * y43
return a / d, b / d
end

I'm pretty sure this can be modified to do segment to segment intersection.
((_((_CRAYOLA_((_((_> GitHub <_((_((_CRAYOLA_((_(()

davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

### Re: Small Useful Functions

*Shameless self-promotion*
I didn't do it that way, but if you want to you can take a look at how I got segment intersections here.
Most of the library will soon undergo a rewrite as I wrote most of the functions a couple of years ago and they may not be extremely efficient as I wasn't too advanced in math, so if you have a suggestion, feel free to suggest/make a pull request.
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim

Nixola
Inner party member
Posts: 1940
Joined: Tue Dec 06, 2011 7:11 pm
Location: Italy

### Re: Small Useful Functions

Code: Select all

function isBetween(n, min, max)
if min > max then
min, max = max, min
end
return (n >= min) and (n <= max)
end

function intersect(x1, y1, x2, y2, x3, y3, x4, y4)
local x21, x43 = x2 - x1, x4 - x3
local y21, y43 = y2 - y1, y4 - y3
local d = x21 * y43 - y21 * x43
if d == 0 then return false end
local xy34 = x3 * y4 - y3 * x4
local xy12 = x1 * y2 - y1 * x2
local a = xy34 * x21 - xy12 * x43
local b = xy34 * y21 - xy12 * y43
return a / d, b / d
end

function intersectL(x1, y1, x2, y2, x3, y3, x4, y4)
local xi, yi = intersect(x1, y1, x2, y2, x3, y3, x4, y4)
if isBetween(xi, x1, x2) and isBetween(yi, y1, y2) and isBetween(xi, x3, x4) and isBetween(yi, y3, y4) then
return xi, yi
end
return false
end
lf = love.filesystem
ls = love.sound
la = love.audio
lp = love.physics