-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaff.lua
68 lines (56 loc) · 1.4 KB
/
aff.lua
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
--[[
Affine transformation matrix:
| a c e |
| b d f |
| 0 0 1 |
]]
local Affine = {}
Affine.__index = Affine
function Affine:reset()
self.a = 1; self.c = 0; self.e = 0
self.b = 0; self.d = 1; self.f = 0
end
function Affine:add_custom(a, b, c, d, e, f)
local na = a*self.a + c*self.b
local nb = b*self.a + d*self.b
local nc = a*self.c + c*self.d
local nd = b*self.c + d*self.d
local ne = a*self.e + c*self.f + e
local nf = b*self.e + d*self.f + f
self.a = na; self.c = nc; self.e = ne
self.b = nb; self.d = nd; self.f = nf
end
function Affine:add_squeeze(k)
self:add_custom(k, 0, 0, 1/k, 0, 0)
end
function Affine:add_scale(x, y)
y = y or x
self:add_custom(x, 0, 0, y, 0, 0)
end
function Affine:add_hshear(h)
self:add_custom(1, 0, h, 1, 0, 0)
end
function Affine:add_vshear(v)
self:add_custom(1, v, 0, 1, 0, 0)
end
function Affine:add_rotate(a)
local c, s = math.cos(a), math.sin(a)
self:add_custom(c, -s, s, c, 0, 0)
end
function Affine:add_translate(x, y)
self:add_custom(1, 0, 0, 1, x, y)
end
function Affine:apply(points)
local x, y
for i, p in ipairs(points) do
x = self.a*p[1] + self.c*p[2] + self.e
y = self.b*p[1] + self.d*p[2] + self.f
p[1], p[2] = x, y
end
end
local function new_affine()
local self = setmetatable({}, Affine)
self:reset()
return self
end
return {new_affine=new_affine}