login

<     >

2021-04-25 11:07:50 (UTC-03:00)

Marcel Rodrigues <marcelgmr@gmail.com>

add affine transformations

diff --git a/aff.lua b/aff.lua
new file mode 100644
index 0000000..5ed98f6
--- /dev/null
+++ b/aff.lua
@@ -0,0 +1,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}