Page 12 of 13

Re: Small Useful Functions

Posted: Tue Jul 14, 2015 6:01 pm
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.

Re: Small Useful Functions

Posted: Wed Jul 15, 2015 6:05 pm
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.

Re: Small Useful Functions

Posted: Sun Aug 02, 2015 9:18 pm
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

Re: Small Useful Functions

Posted: Sun Aug 02, 2015 9:29 pm
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.

Re: Small Useful Functions

Posted: Sun Aug 02, 2015 9:58 pm
by zorg
time thief wrote:...
Or, you know, there's always strict.lua :3

Re: Small Useful Functions

Posted: Sun Aug 02, 2015 10:47 pm
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

Re: Small Useful Functions

Posted: Sun Aug 02, 2015 11:00 pm
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.

Re: Small Useful Functions

Posted: Mon Aug 03, 2015 5:16 am
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

Re: Small Useful Functions

Posted: Fri Aug 07, 2015 6:13 am
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

Re: Small Useful Functions

Posted: Fri Aug 07, 2015 4:59 pm
by Davidobot
time thief wrote:...
No problem, man! You shouldn't really thank me though, Jasoco first sent me this code.