Small Useful Functions

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
User avatar
HugoBDesigner
Party member
Posts: 403
Joined: Mon Feb 24, 2014 6:54 pm
Location: Above the Pocket Dimension
Contact:

Re: Small Useful Functions

Post 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
@HugoBDesigner - Twitter
HugoBDesigner - Blog
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Small Useful Functions

Post 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
Last edited by davisdude on Sun Apr 12, 2015 5:05 pm, edited 1 time in total.
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
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Small Useful Functions

Post 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. :)
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Small Useful Functions

Post 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.
Help us help you: attach a .love.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Small Useful Functions

Post by ivan »

Good catch Robin. :)
Forgot about:
a^2/b^2 = 2*a/b^2
Last edited by ivan on Thu Feb 26, 2015 11:29 am, edited 1 time in total.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Small Useful Functions

Post by Robin »

ivan wrote:a^2/b^2 = 2*a/b^2
Wait what?

Did you mean a^2/b^2 = (a/b)^2?
Help us help you: attach a .love.
User avatar
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Small Useful Functions

Post by ivan »

Right again. I better stop since this is getting embarrassing. :)
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Small Useful Functions

Post 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
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
User avatar
T-Bone
Inner party member
Posts: 1492
Joined: Thu Jun 09, 2011 9:03 am

Re: Small Useful Functions

Post 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.
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Small Useful Functions

Post 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
Help us help you: attach a .love.
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Google [Bot] and 13 guests