Page 9 of 13

Re: Small Useful Functions

Posted: Tue Feb 24, 2015 4:00 pm
by HugoBDesigner
Here are 3 quick drawing functions I wrote for my Andralog library:

fade
Gets the mix between two colors at a given rate. I already posted this function here, but reposting for the sake of making it easy
Time passed, Time limit, First color's table, Second color's table

Code: Select all

function fade(currenttime, maxtime, c1, c2)
	local tp = currenttime/maxtime
	local ret = {} --return color

	for i = 1, #c1 do
		ret[i] = c1[i]+(c2[i]-c1[i])*tp
		ret[i] = math.max(ret[i], 0)
		ret[i] = math.min(ret[i], 255)
	end

	return unpack(ret)
end
distance
Just a quick mathematical function that gets the distance between two points (a.k.a Pythagoras' Theorem)
Point 1 x, Point 1 y, Point 2 x, Point 2 y

Code: Select all

function distance(cx, cy, x, y)
	return math.sqrt( math.abs(x-cx)^2 + math.abs(y-cy)^2 )
end
renderGradient
Generates an image of a radial gradient between two colors. Requires the "fade" and "distance" functions.
Gradient's radius, First color's table, Second color's table

Code: Select all

function renderGradient(size, c1, c2)
	local i = love.image.newImageData(size*2, size*2)
	for x = 0, size*2-1 do
		for y = 0, size*2-1 do
			local d = self.distance(size, size, x+1, y+1)
			local f = d/size
			f = math.max(0, f)
			i:setPixel(x, y, self.fade(f, 1, c1, c2))
		end
	end
	return love.graphics.newImage(i)
end
pokedStencil
Used to make a stencil of a circle with a hole in it (can also be used as a drawing polygon on it's own)
Center's x, Center's y, Hole's radius, Circle's radius, Circle's segments

Code: Select all

function pokedStencil(cx, cy, d1, d2, s)
	for a = 0, s-1 do
		local p1x = math.cos(a/s*(math.pi*2))*d2
		local p1y = -math.sin(a/s*(math.pi*2))*d2
		
		local p2x = math.cos(a/s*(math.pi*2))*d1
		local p2y = -math.sin(a/s*(math.pi*2))*d1
		
		local p3x = math.cos((a+1)/s*(math.pi*2))*d1
		local p3y = -math.sin((a+1)/s*(math.pi*2))*d1
		
		local p4x = math.cos((a+1)/s*(math.pi*2))*d2
		local p4y = -math.sin((a+1)/s*(math.pi*2))*d2
		
		love.graphics.polygon("fill", cx+p1x, cy+p1y, cx+p2x, cy+p2y, cx+p3x, cy+p3y, cx+p4x, cy+p4y)
	end
end

Re: Small Useful Functions

Posted: Tue Feb 24, 2015 7:45 pm
by davisdude
Small note on the distance function:
No need to get the absolute value- if you square the difference it will always be positive.
edit: grammar fixes

Re: Small Useful Functions

Posted: Tue Feb 24, 2015 9:37 pm
by ivan
When you need the ratio between two distances, you can use the squared distance and avoid "sqrt" altogether:

Code: Select all

function distance2(cx, cy, x, y)
   local dx, dy = cx - x, cy - y
   return dx*dx + dy*dy -- dx^2 + dy^2
end
function renderGradient(size, c1, c2)
   local size2 = size*size -- size^2
   local i = love.image.newImageData(size*2, size*2)
   for x = 0, size*2-1 do
      for y = 0, size*2-1 do
         local d2 = self.distance2(size, size, x+1, y+1)
         local f = d2/size2 -- f is always 0 or greater, i suggest assert(size2 >0 and size2<=d2)
Yes, I admit that your code is easier to read. :)

Re: Small Useful Functions

Posted: Wed Feb 25, 2015 8:31 am
by Robin
ivan wrote:

Code: Select all

         local f = d2/size2 -- f is always 0 or greater, i suggest assert(size2 >0 and size2<=d2)
'cept that is not the same. The original code gave a linear gradient*, while this one creates a quadratic gradient.

*Well, the RGB colorspace isn't linear but whatever.

Re: Small Useful Functions

Posted: Thu Feb 26, 2015 7:26 am
by ivan
Good catch Robin. :)
Forgot about:
a^2/b^2 = 2*a/b^2

Re: Small Useful Functions

Posted: Thu Feb 26, 2015 10:26 am
by Robin
ivan wrote:a^2/b^2 = 2*a/b^2
Wait what?

Did you mean a^2/b^2 = (a/b)^2?

Re: Small Useful Functions

Posted: Thu Feb 26, 2015 11:29 am
by ivan
Right again. I better stop since this is getting embarrassing. :)

Re: Small Useful Functions

Posted: Sun Apr 12, 2015 4:55 pm
by davisdude
Some useful looping functions:

Code: Select all

-- Reverse ipairs
function ripairs( tab )
    local i = table.getn( tab ) + 1
    local stop = 0
    return function() 
        i = i - 1
        if i > stop then return i, tab[i] end
    end 
end

-- Use:
for i, v in ripairs( tab ) do
...
end

Code: Select all

-- Cyclic ipairs
function cipairs( tab, reps )
    local i = 0
    local length = table.getn( tab )
    local stop = reps or table.getn( tab )
    return function()
        i = i + 1
        local trueIndex = ( i - 1 ) % length + 1
        if i <= stop then return trueIndex, i, tab[trueIndex] end
    end
end
-- Use: 
for index, times, value in cipairs( tab, 10 )
    -- Loop for 10 times
end

Re: Small Useful Functions

Posted: Sun Apr 12, 2015 8:34 pm
by T-Bone
By far the most useful yet really really small function for me is this one:

Code: Select all

function inherit(parent, child) -- child is optional, if not submitted a new object will be created and returned
	local child = child or {}
	setmetatable(child,{__index = parent})
	return child
end
This is, in many cases, all the object orientation you need.

Re: Small Useful Functions

Posted: Mon Apr 13, 2015 11:31 am
by Robin
That last one can be one line:

Code: Select all

function inherit(parent, child) -- child is optional, if not submitted a new object will be created and returned
	return setmetatable(child or {}, {__index = parent})
end