matrix.lua 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. -- everything in this file is licensed under CC0
  2. -- see also minetest PR #8515
  3. matrix3 = {}
  4. function matrix3.new(a, ...)
  5. if not a then
  6. return {0, 0, 0, 0, 0, 0, 0, 0, 0}
  7. elseif type(a) ~= "table" then
  8. return {a, ...}
  9. else
  10. return {a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]}
  11. end
  12. end
  13. matrix3.identity = {1, 0, 0, 0, 1, 0, 0, 0, 1}
  14. function matrix3.apply(m, func)
  15. local mr = {}
  16. for i = 1, 9 do
  17. mr[i] = func(m[i])
  18. end
  19. return mr
  20. end
  21. function matrix3.equals(m1, m2)
  22. for i = 1, 9 do
  23. if m1[i] ~= m2[i] then
  24. return false
  25. end
  26. end
  27. return true
  28. end
  29. function matrix3.index(m, l, c)
  30. return m[(l - 1) * 3 + c]
  31. end
  32. function matrix3.add(m1, m2)
  33. local m3 = {}
  34. for i = 1, 9 do
  35. m3[i] = m1[i] + m2[i]
  36. end
  37. return m3
  38. end
  39. local function multiply_matrix3_scalar(m, a)
  40. local mr = {}
  41. for i = 1, 9 do
  42. mr[i] = m[i] * a
  43. end
  44. return mr
  45. end
  46. local function multiply_matrix3_vector(m1, v)
  47. return {
  48. x = m1[1] * v.x + m1[2] * v.y + m1[3] * v.z,
  49. y = m1[4] * v.x + m1[5] * v.y + m1[6] * v.z,
  50. z = m1[7] * v.x + m1[8] * v.y + m1[9] * v.z,
  51. }
  52. end
  53. function matrix3.multiply(m1, m2)
  54. if type(m2) ~= "table" then
  55. return multiply_matrix3_scalar(m1, m2)
  56. elseif m2.x then
  57. return multiply_matrix3_vector(m1, m2)
  58. end
  59. local m3 = {}
  60. for l = 1, 3 do
  61. for c = 1, 3 do
  62. local i = (l - 1) * 3 + c
  63. m3[i] = 0
  64. for k = 1, 3 do
  65. m3[i] = m3[i] + m1[(l - 1) * 3 + k] * m2[(k - 1) * 3 + c]
  66. end
  67. end
  68. end
  69. return m3
  70. end
  71. function matrix3.tensor_multiply(a, b)
  72. local m1 = matrix3.new()
  73. m1[1] = a.x
  74. m1[4] = a.y
  75. m1[7] = a.z
  76. local m2 = matrix3.new()
  77. m2[1] = a.x
  78. m2[2] = a.y
  79. m2[3] = a.z
  80. return matrix3.multiply(m1, m2)
  81. end
  82. function matrix3.transpose(m)
  83. return {m[1], m[4], m[7],
  84. m[2], m[5], m[8],
  85. m[3], m[6], m[9]}
  86. end
  87. function matrix3.determinant(m)
  88. return m[1] * (m[5] * m[9] - m[6] * m[8])
  89. + m[2] * (m[6] * m[7] - m[4] * m[9])
  90. + m[3] * (m[4] * m[8] - m[5] * m[7])
  91. end
  92. function matrix3.invert(a)
  93. local t11 = a[5] * a[9] - a[6] * a[8]
  94. local t12 = a[6] * a[7] - a[4] * a[9]
  95. local t13 = a[4] * a[8] - a[5] * a[7]
  96. local det = a[1] * t11 + a[2] * t12 + a[3] * t13
  97. if det == 0 then
  98. return false -- there is no inverted
  99. end
  100. local b = {
  101. t11 / det, (a[3]*a[8] - a[2]*a[9]) / det, (a[2]*a[6] - a[3]*a[5]) / det,
  102. t12 / det, (a[1]*a[9] - a[3]*a[7]) / det, (a[3]*a[4] - a[1]*a[6]) / det,
  103. t13 / det, (a[2]*a[7] - a[1]*a[8]) / det, (a[1]*a[5] - a[2]*a[4]) / det
  104. }
  105. return b
  106. end
  107. local function sin(x)
  108. if x % math.pi == 0 then
  109. return 0
  110. else
  111. return math.sin(x)
  112. end
  113. end
  114. local function cos(x)
  115. if x % math.pi == math.pi / 2 then
  116. return 0
  117. else
  118. return math.cos(x)
  119. end
  120. end
  121. function matrix3.rotation_around_x(angle)
  122. local s = sin(angle)
  123. local c = cos(angle)
  124. return {1, 0, 0,
  125. 0, c, -s,
  126. 0, s, c}
  127. end
  128. function matrix3.rotation_around_y(angle)
  129. local s = sin(angle)
  130. local c = cos(angle)
  131. return { c, 0, s,
  132. 0, 1, 0,
  133. -s, 0, c}
  134. end
  135. function matrix3.rotation_around_z(angle)
  136. local s = sin(angle)
  137. local c = cos(angle)
  138. return {c, -s, 0,
  139. s, c, 0,
  140. 0, 0, 1}
  141. end
  142. function matrix3.rotation_around_vector(v, angle)
  143. local length_v = vector.length(v)
  144. v = vector.divide(v, length_v)
  145. angle = angle or length_v
  146. local s = sin(angle)
  147. local c = cos(angle)
  148. local omc = 1 - c
  149. return {
  150. v.x * v.x * omc + c, v.x * v.y * omc - v.z * s, v.x * v.z * omc + v.y * s,
  151. v.y * v.x * omc + v.z * s, v.y * v.y * omc + c, v.y * v.z * omc - v.x * s,
  152. v.z * v.x * omc - v.y * s, v.z * v.y * omc + v.x * s, v.z * v.z * omc + c
  153. }
  154. end
  155. function matrix3.to_pitch_yaw_roll(m)
  156. local r = vector.new()
  157. r.y = math.atan2(-m[3], m[9])
  158. local c2 = math.sqrt(m[4]^2 + m[5]^2)
  159. r.x = math.atan2(m[6], c2)
  160. local s1 = sin(r.y)
  161. local c1 = cos(r.y)
  162. r.z = math.atan2(s1 * m[8] + c1 * m[2], s1 * m[7] + c1 * m[1])
  163. return r
  164. end
  165. function matrix3.from_pitch_yaw_roll(v)
  166. local sx, cx = sin(v.x), cos(v.x)
  167. local sy, cy = sin(v.y), cos(v.y)
  168. local sz, cz = sin(v.z), cos(v.z)
  169. return {
  170. -sy * sx * sz + cy * cz, cz * sy * sx + cy * sz, -cx * sy,
  171. -cx * sz, cx * cz, sx,
  172. cy * sx * sz + cz * sy, -cy * cz * sx + sy * sz, cy * cx
  173. }
  174. end