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
ivan
Party member
Posts: 1911
Joined: Fri Mar 07, 2008 1:39 pm
Contact:

Re: Small Useful Functions

Post by ivan »

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
This method is used in the 'path' library by Cosmin Apreutesei.
I added the last line to calculate the 'point of intersection' in addition to the intersection times:

Code: Select all

function intersect(x1, y1, x2, y2, x3, y3, x4, y4)
  local dx1, dy1 = x2 - x1, y2 - y1
  local dx2, dy2 = x4 - x3, y4 - y3
  local dx3, dy3 = x1 - x3, y1 - y3
  local d = dx1*dy2 - dy1*dx2
  if d == 0 then
    return -- collinear
  end
  local t1 = (dx2*dy3 - dy2*dx3)/d
  local t2 = (dx1*dy3 - dy1*dx3)/d
  return x1 + t1*dx1, y1 + t1*dy1, t1, t2
end
Very easy to modify it and support segments:

Code: Select all

function intersectSegment(x1, y1, x2, y2, x3, y3, x4, y4)
  local dx1, dy1 = x2 - x1, y2 - y1
  local dx2, dy2 = x4 - x3, y4 - y3
  local dx3, dy3 = x1 - x3, y1 - y3
  local d = dx1*dy2 - dy1*dx2
  if d == 0 then
    return -- collinear
  end
  local t1 = (dx2*dy3 - dy2*dx3)/d
  if (t1 < 0) or (t1 > 1) then
    return -- non-intersecting segment 
  end
  local t2 = (dx1*dy3 - dy1*dx3)/d
  if (t2 < 0) or (t2 > 1) then
    return -- non-intersecting segment
  end
  return x1 + t1*dx1, y1 + t1*dy1, t1, t2
end
Slightly faster than Nixola's version because it bails out as soon as the t1/t2 checks fail.
User avatar
bakpakin
Party member
Posts: 114
Joined: Sun Mar 15, 2015 9:29 am
Location: Boston

Re: Small Useful Functions

Post by bakpakin »

Perfect ivan. I remember the solution had something to do with checking if a parametric t was between 0 and 1. I actually originally got the algorithm from wikipedia https://en.wikipedia.org/wiki/Line%E2%8 ... tersection

Also, here's OO in like 10 lines. I don't really like using class frameworks in lua because I like being able to play with metatables, but classes are pretty useful sometimes. Here are two functions for simple lua classes with constructors, inheritance, and callable classes to create instances. I just stick this at the top of a file if I want to use classes in a module.

Code: Select all

local function new(c, ...)
    local inst, ctor = setmetatable({}, c), c.init
    if ctor then ctor(inst, ...) end
    return inst
end

local class = function (super)
    local class = setmetatable({ super = super }, { __index = super, __call = new })
    class.__index = class
    return class
end
This has been done a thousand times already I'm sure, but here's my own two cents. Classes are created like

Code: Select all

local myClass = class(mySuperClass)
and instances can be created via

Code: Select all

local instance = new(myClass, ...)
or

Code: Select all

local instance = myClass(...)
Super classes are optional, and passing nil to the class function works fine as well.
((_((_CRAYOLA_((_((_> GitHub <_((_((_CRAYOLA_((_(()
User avatar
georgeprosser
Citizen
Posts: 68
Joined: Fri Mar 28, 2014 5:55 pm

Re: Small Useful Functions

Post by georgeprosser »

Haven't seen this one posted. Maybe that's because it's so obvious and simple, but I use it all the time. This function returns true with the supplied probability.

Code: Select all

function chance(p)
    return math.random() < p
end
Means you can write neat stuff like this:

Code: Select all

if chance(0.5) then
    print('heads')
else
    print('tails')
end
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Small Useful Functions

Post by airstruck »

Maybe this has been posted before, but this little snippet has helped me catch a few mistakes since I started using it.

Code: Select all

-- lock global table

setmetatable(_G, {
    __index = function () error('referenced an undefined variable', 2) end,
    __newindex = function () error('new global variables disabled', 2) end
})
Drop it in at the top of main.lua to catch accidental global declarations and references. If you want to declare some globals, do it above this snippet.
User avatar
zorg
Party member
Posts: 3436
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Small Useful Functions

Post by zorg »

time thief wrote:...
Or, you know, there's always strict.lua :3
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
georgeprosser
Citizen
Posts: 68
Joined: Fri Mar 28, 2014 5:55 pm

Re: Small Useful Functions

Post by georgeprosser »

Here's another while I'm sharing. This function gives you the angular distance between two angles.

Code: Select all

function angularDistance(a, b)
    return math.abs(math.atan2(math.sin(a - b), math.cos(a - b)))
end
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Small Useful Functions

Post by airstruck »

zorg wrote: Or, you know, there's always strict.lua :3
I'm aware of strict.lua. IMO the debug module is overkill for this sort of thing (and probably has no place in production code at all other than in something like a test framework). In fact I think strict.lua on the whole is overkill. YMMV.
User avatar
Davidobot
Party member
Posts: 1226
Joined: Sat Mar 31, 2012 5:18 am
Location: Oxford, UK
Contact:

Re: Small Useful Functions

Post by Davidobot »

Code to normalize (find the difference between) two angles:

Code: Select all

function angleDifference(t1, t2)
   return (t1 - t2 + math.pi) % (math.pi * 2) - math.pi
end
PM me on here or elsewhere if you'd like to discuss porting your game to Nintendo Switch via mazette!
personal page and a raycaster
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: Small Useful Functions

Post by airstruck »

Davidobot wrote:Code to normalize (find the difference between) two angles:

Code: Select all

function angleDifference(t1, t2)
   return (t1 - t2 + math.pi) % (math.pi * 2) - math.pi
end
Yoink
User avatar
Davidobot
Party member
Posts: 1226
Joined: Sat Mar 31, 2012 5:18 am
Location: Oxford, UK
Contact:

Re: Small Useful Functions

Post by Davidobot »

time thief wrote:...
No problem, man! You shouldn't really thank me though, Jasoco first sent me this code.
PM me on here or elsewhere if you'd like to discuss porting your game to Nintendo Switch via mazette!
personal page and a raycaster
Post Reply

Who is online

Users browsing this forum: No registered users and 52 guests