summaryrefslogtreecommitdiff
path: root/math.lua
blob: 4ebd38fabcc618606d970654e277435dcb781a34 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Vec2 = {}
Vec2.__eq = function(a, b) return a.x == b.x and a.y == b.y end
Vec2.__index = Vec2
Vec2.__add = function(a, b) return vec2(a.x + b.x, a.y + b.y) end
Vec2.__unm = function(a) return vec2(-a.x, -a.y) end
Vec2.__sub = function(a, b) return a + (-b) end
Vec2.__mul = function(a, b)
    if (type(b) == "number") then return vec2(a.x * b, a.y * b) end -- scalar mult
    return vec2(a.x * b.x, a.y * b.y)
end
Vec2.__div = function(a, b)
    if (type(b) == "number") then return vec2(a.x / b, a.y / b) end -- scalar div
    return vec2(a.x / b.x, a.y / b.y)
end
Vec2.__tostring = function(a) return "(" .. fmt(a.x) .. "," .. fmt(a.y) .. ")" end

function Vec2:in_bounds(low, hi)
    return self.x >= low.x and self.x <= hi.x and self.y >= low.y and self.y <= hi.y
end

function Vec2:magnitude()
    return sqrt(self.x * self.x + self.y * self.y)
end

function Vec2:normal()
    local m = self:magnitude()
    if m == 0 then return vec2(self.x, self.y) end
    return vec2(self / m)
end

-- 1 picorad == 2pi
function Vec2:clockwise_rotate(picorads)
    local m = self:magnitude()
    local a = atan2(self.x, self.y) + picorads
    return vec2(m * cos(a), m * sin(a))
end

function Vec2:apply(f)
    return vec2(f(self.x), f(self.y))
end

function vec2(x, y)
    if type(x) == "table" then return vec2(x.x, x.y) end
    return setmetatable({ x = x, y = y }, Vec2)
end

function normalize_scalar(x)
    if x == 0 then return 0 end
    if x < 0 then return -1 end
    return 1
end