-
Notifications
You must be signed in to change notification settings - Fork 2
/
picocam.lua
57 lines (57 loc) · 1.72 KB
/
picocam.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
cameralib = {
new = function(init)
init = init or {}
local self = {}
self.z = init.z or -3
self.focallength = init.focallength or 5
self.fov = init.fov or 45
self.theta = init.theta or 0
self.width = init.width or 128
self.height = init.height or 128
-- public
self.line = cameralib.line
self.point = cameralib.point
-- private
self._perspective = cameralib._perspective
self._tan = cameralib._tan
self._coordstopx = cameralib._coordstopx
self._map = cameralib._map
return self
end,
line = function(self, p1, p2)
local px_1 = self:_coordstopx(self:_perspective(p1))
local px_2 = self:_coordstopx(self:_perspective(p2))
line(px_1[1], px_1[2], px_2[1], px_2[2])
end,
point = function(self, p)
local px = self:_coordstopx(self:_perspective(p))
pset(px[1],px[2])
end,
_perspective = function(self, p)
local x,y,z = p[1],p[2],p[3]
local x_rot = x * cos(self.theta) - z * sin(self.theta)
local z_rot = x * sin(self.theta) + z * cos(self.theta)
local dz = z_rot - self.z
local out_z = self.z + self.focallength
local m_xz = x_rot / dz
local m_yz = y / dz
local out_x = m_xz * out_z
local out_y = m_yz * out_z
return { out_x, out_y }
end,
_map = function(v, a, b, c, d)
local partial = (v - a) / (b - a)
return partial * (d - c) + c
end,
_tan = function(v)
return sin(v) / cos(v)
end,
_coordstopx = function(self,coords)
local x = coords[1]
local y = coords[2]
local radius = self.focallength * self._tan(self.fov / 2 / 360)
local pixel_x = self._map(x, -radius, radius, 0, self.width)
local pixel_y = self._map(y, -radius, radius, 0, self.height)
return { pixel_x, pixel_y }
end
}