likocam.lua 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. local pi2 = math.pi*2
  2. local function cos(a)
  3. return math.cos(a*pi2)
  4. end
  5. local function sin(a)
  6. return -math.sin(a*pi2)
  7. end
  8. local cameralib
  9. cameralib = {
  10. new = function(init)
  11. init = init or {}
  12. local self = {}
  13. self.z = init.z or -3
  14. self.focallength = init.focallength or 5
  15. self.fov = init.fov or 45
  16. self.theta = init.theta or 0
  17. self.width = init.width or screenWidth()
  18. self.height = init.height or screenHeight()
  19. -- public
  20. self.line = cameralib.line
  21. self.point = cameralib.point
  22. self.object = cameralib.object
  23. -- private
  24. self._perspective = cameralib._perspective
  25. self._tan = cameralib._tan
  26. self._coordstopx = cameralib._coordstopx
  27. self._map = cameralib._map
  28. return self
  29. end,
  30. line = function(self, p1, p2)
  31. local px_1 = self:_coordstopx(self:_perspective(p1))
  32. local px_2 = self:_coordstopx(self:_perspective(p2))
  33. line(px_1[1], px_1[2], px_2[1], px_2[2])
  34. end,
  35. point = function(self, p)
  36. local px = self:_coordstopx(self:_perspective(p))
  37. point(px[1],px[2])
  38. end,
  39. object = function(self,s)
  40. for sn, side in ipairs(s) do
  41. for k,v in ipairs(side ) do
  42. local v2
  43. if k == #side then
  44. v2 = side[1]
  45. else
  46. v2 = side[k+1]
  47. end
  48. self:line(v,v2)
  49. end
  50. end
  51. end,
  52. _perspective = function(self, p)
  53. local x,y,z = p[1],p[2],p[3]
  54. local x_rot = x * cos(self.theta) - z * sin(self.theta)
  55. local z_rot = x * sin(self.theta) + z * cos(self.theta)
  56. local dz = z_rot - self.z
  57. local out_z = self.z + self.focallength
  58. local m_xz = x_rot / dz
  59. local m_yz = y / dz
  60. local out_x = m_xz * out_z
  61. local out_y = m_yz * out_z
  62. return { out_x, out_y }
  63. end,
  64. _map = function(v, a, b, c, d)
  65. local partial = (v - a) / (b - a)
  66. return partial * (d - c) + c
  67. end,
  68. _tan = function(v)
  69. return sin(v) / cos(v)
  70. end,
  71. _coordstopx = function(self,coords)
  72. local x = coords[1]
  73. local y = coords[2]
  74. local radius = self.focallength * self._tan(self.fov / 2 / 360)
  75. local pixel_x = self._map(x, -radius, radius, 0, self.width)
  76. local pixel_y = self._map(y, -radius, radius, 0, self.height)
  77. return { pixel_x, pixel_y }
  78. end
  79. }
  80. return cameralib