Page 1 of 5

Mini Functions Repository

Posted: Sat Apr 02, 2016 9:50 pm
by ZBoyer1000
I thought it would be neat to create a place where people could post small functions that can do useful things and possibly help other people's projects. :D

Here is a function I created that could help create game clocks:

Code: Select all

 gameClocks = {}
function clock(name, time)
index = 0
 for i = 1,#gameClocks do
   if gameClocks[i][1] == tostring(name) then
	 index = i
   end
 end
 if index == 0 then
   local clock = {tostring(name), num = 0}
   table.insert(gameClocks, clock)
 elseif index ~= 0 then
   gameClocks[index].num = gameClocks[index].num + 1
   if gameClocks[index].num >= time then gameClocks[index].num = 0 return true end
 end
end 
Here is an example for it: :o:
l = 0
z = 0
function love.update(dt)
if clock("LClock", 20) == true then
l = l + 1
end
if clock("ZClock", 1) == true then
z = z + 1
end
love.graphics.print(tostring(z) .. " : " .. tostring(l))
end

Re: Mini Functions Repository

Posted: Mon Apr 04, 2016 4:52 pm
by Sulunia
Welp, gonna contribute here.
Lerp funtion

Code: Select all

function lerp(a, b, rate) --EMPLOYEE OF THE MONTH
	local result = (1-rate)*a + rate*b
	return result
end
Usage:
speed = 0.05
myVar = lerp(myVar, newValue, speed)

Clamp function

Code: Select all

function clamp(number, maxvalue, minvalue)
	if number > maxvalue then
		number = maxvalue
	elseif number < minvalue then
		number = minvalue
	end
	return number
end
Usage: Self explanatory

Re: Mini Functions Repository

Posted: Tue Apr 05, 2016 7:52 am
by Roland_Yonaba
Sulunia wrote:Clamp function
A shorter version :

Code: Select all

local function clamp(value, min, max)
  return math.min(max, math.max(value, min))
end
Or in case you need to assign the value within the function :

Code: Select all

local function clamp(value, min, max)
  value = math.min(max, math.max(value, min))
  return value
end
This cheatsheet would be probably useful.

Re: Mini Functions Repository

Posted: Tue Apr 05, 2016 9:49 am
by marco.lizza
Sulunia wrote: Lerp funtion [...]
For the sake of numerical stability and math optimization, a LERP function is better written as follow.

Code: Select all

function lerp(a, b, rate)
  return a + (b-a)*rate
end

Re: Mini Functions Repository

Posted: Tue Apr 05, 2016 1:00 pm
by Sulunia
marco.lizza wrote:
Sulunia wrote: Lerp funtion [...]
For the sake of numerical stability and math optimization, a LERP function is better written as follow.

Code: Select all

function lerp(a, b, rate)
  return a + (b-a)*rate
end

Numerical stability? Math optimization? :huh:
Care for some elaboration? (genuinely curious)

Re: Mini Functions Repository

Posted: Tue Apr 05, 2016 2:12 pm
by marco.lizza
Sulunia wrote:Numerical stability?
Lua threats each number as a floating-point number. By definitions floating-point numbers are approximated and operations need to be taken with care in order to avoid (or at least to keep low) error propagation. By dismissing the additional multiplication we let the error propagate less quickly (in general multiplications propagates errors more quickly that additions, especially when numbers have big differences in the exponent).
Sulunia wrote:Math optimization?
To be honest, this should be called "peephole optimization", since we are only considering a small part of a source-code (a single formula) and reorganize it by reducing the amount of math operations involved. Your version features an additional multiplication that we can get rid of (and remember that in general, and especially on embedded devices, multiplication is by far the most costly operation).

Re: Mini Functions Repository

Posted: Tue Apr 05, 2016 3:40 pm
by Sulunia
Thanks for the insight! It's actually pretty feasible what you said.

Re: Mini Functions Repository

Posted: Tue Apr 05, 2016 3:58 pm
by marco.lizza
You're welcome, @Sulunia!

Re: Mini Functions Repository

Posted: Tue Apr 05, 2016 5:10 pm
by Inny
We had another thread with a lot of small functions in it if you want to have a peak through that: viewtopic.php?f=4&t=77599

As long as we don't start the lua equivalent of NPM's leftpad disaster, I'm all for these kinds of threads. It's a good resource for newbies to learn how different pieces of code would be written.

Re: Mini Functions Repository

Posted: Tue Apr 05, 2016 5:33 pm
by pgimeno
marco.lizza wrote:For the sake of numerical stability and math optimization, a LERP function is better written as follow.

Code: Select all

function lerp(a, b, rate)
  return a + (b-a)*rate
end
I disagree. My own experiments show otherwise:

http://math.stackexchange.com/questions ... erpolation

The version that you've written may go past b even when rate is still < 1. See examples in the above link.

Basically, a*(1-rate) + b*rate guarantees that when rate = 0, the result is exactly a, and when rate = 1, the result is exactly b. The experiments show that it's also monotonic (edit: even if no one was able to give proof).

On the other hand, a+b-a does not always return b.

Edit: The example as a Lua program:

Code: Select all

t = 0.9999999999999999
A = -0.3465728856142666
B = 0.653769243987566
assert(t < 1)
assert(A*(1-t)+B*t <= B, "A*(1-t)+B*t is > B even if t < 1")
assert(A+(B-A)*t <= B, "A+(B-A)*t is > B even if t < 1")

--[[
Error: main.lua:6: A+(B-A)*t is > B even if t < 1
stack traceback:
	[C]: in function 'assert'
	main.lua:5: in main chunk
	[C]: in function 'require'
	[string "boot.lua"]:428: in function <[string "boot.lua"]:274>
	[C]: in function 'xpcall'
--]]
Update: Comparing single-precision with double-precision results using both methods yielded the exact same maximum and minimum errors in the exact same t values. Test program: http://www.formauri.es/personal/pgimeno/pastes/lerp.c