matrix3.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package math32
  5. import "errors"
  6. // Matrix3 is 3x3 matrix organized internally as column matrix
  7. type Matrix3 [9]float32
  8. // NewMatrix3 creates and returns a pointer to a new Matrix3
  9. // initialized as the identity matrix.
  10. func NewMatrix3() *Matrix3 {
  11. var m Matrix3
  12. m.Identity()
  13. return &m
  14. }
  15. // Set sets all the elements of the matrix row by row starting at row1, column1,
  16. // row1, column2, row1, column3 and so forth.
  17. // Returns the pointer to this updated Matrix.
  18. func (m *Matrix3) Set(n11, n12, n13, n21, n22, n23, n31, n32, n33 float32) *Matrix3 {
  19. m[0] = n11
  20. m[3] = n12
  21. m[6] = n13
  22. m[1] = n21
  23. m[4] = n22
  24. m[7] = n23
  25. m[2] = n31
  26. m[5] = n32
  27. m[8] = n33
  28. return m
  29. }
  30. // Identity sets this matrix as the identity matrix.
  31. // Returns the pointer to this updated matrix.
  32. func (m *Matrix3) Identity() *Matrix3 {
  33. m.Set(
  34. 1, 0, 0,
  35. 0, 1, 0,
  36. 0, 0, 1,
  37. )
  38. return m
  39. }
  40. // Zero sets this matrix as the zero matrix.
  41. // Returns the pointer to this updated matrix.
  42. func (m *Matrix3) Zero() *Matrix3 {
  43. m.Set(
  44. 0, 0, 0,
  45. 0, 0, 0,
  46. 0, 0, 0,
  47. )
  48. return m
  49. }
  50. // Copy copies src matrix into this one.
  51. // Returns the pointer to this updated matrix.
  52. func (m *Matrix3) Copy(src *Matrix3) *Matrix3 {
  53. *m = *src
  54. return m
  55. }
  56. // ApplyToVector3Array multiplies length vectors in the array starting at offset by this matrix.
  57. // Returns pointer to the updated array.
  58. // This matrix is unchanged.
  59. func (m *Matrix3) ApplyToVector3Array(array []float32, offset int, length int) []float32 {
  60. var v1 Vector3
  61. j := offset
  62. for i := 0; i < length; i += 3 {
  63. v1.X = array[j]
  64. v1.Y = array[j+1]
  65. v1.Z = array[j+2]
  66. v1.ApplyMatrix3(m)
  67. array[j] = v1.X
  68. array[j+1] = v1.Y
  69. array[j+2] = v1.Z
  70. }
  71. return array
  72. }
  73. // Multiply multiply this matrix by the other matrix
  74. // Returns pointer to this updated matrix.
  75. func (m *Matrix3) Multiply(other *Matrix3) *Matrix3 {
  76. return m.MultiplyMatrices(m, other)
  77. }
  78. // MultiplyMatrices multiply matrix a by b storing the result in this matrix.
  79. // Returns pointer to this updated matrix.
  80. func (m *Matrix3) MultiplyMatrices(a, b *Matrix3) *Matrix3 {
  81. a11 := a[0]
  82. a12 := a[3]
  83. a13 := a[6]
  84. a21 := a[1]
  85. a22 := a[4]
  86. a23 := a[7]
  87. a31 := a[2]
  88. a32 := a[5]
  89. a33 := a[8]
  90. b11 := b[0]
  91. b12 := b[3]
  92. b13 := b[6]
  93. b21 := b[1]
  94. b22 := b[4]
  95. b23 := b[7]
  96. b31 := b[2]
  97. b32 := b[5]
  98. b33 := b[8]
  99. m[0] = a11*b11 + a12*b21 + a13*b31
  100. m[3] = a11*b12 + a12*b22 + a13*b32
  101. m[6] = a11*b13 + a12*b23 + a13*b33
  102. m[1] = a21*b11 + a22*b21 + a23*b31
  103. m[4] = a21*b12 + a22*b22 + a23*b32
  104. m[7] = a21*b13 + a22*b23 + a23*b33
  105. m[2] = a31*b11 + a32*b21 + a33*b31
  106. m[5] = a31*b12 + a32*b22 + a33*b32
  107. m[8] = a31*b13 + a32*b23 + a33*b33
  108. return m
  109. }
  110. // MultiplyScalar multiplies each of this matrix's components by the specified scalar.
  111. // Returns pointer to this updated matrix.
  112. func (m *Matrix3) MultiplyScalar(s float32) *Matrix3 {
  113. m[0] *= s
  114. m[3] *= s
  115. m[6] *= s
  116. m[1] *= s
  117. m[4] *= s
  118. m[7] *= s
  119. m[2] *= s
  120. m[5] *= s
  121. m[8] *= s
  122. return m
  123. }
  124. // Determinant calculates and returns the determinant of this matrix.
  125. func (m *Matrix3) Determinant() float32 {
  126. return m[0]*m[4]*m[8] -
  127. m[0]*m[5]*m[7] -
  128. m[1]*m[3]*m[8] +
  129. m[1]*m[5]*m[6] +
  130. m[2]*m[3]*m[7] -
  131. m[2]*m[4]*m[6]
  132. }
  133. // GetInverse sets this matrix to the inverse of the src matrix.
  134. // If the src matrix cannot be inverted returns error and
  135. // sets this matrix to the identity matrix.
  136. func (m *Matrix3) GetInverse(src *Matrix4) error {
  137. m[0] = src[10]*src[5] - src[6]*src[9]
  138. m[1] = -src[10]*src[1] + src[2]*src[9]
  139. m[2] = src[6]*src[1] - src[2]*src[5]
  140. m[3] = -src[10]*src[4] + src[6]*src[8]
  141. m[4] = src[10]*src[0] - src[2]*src[8]
  142. m[5] = -src[6]*src[0] + src[2]*src[4]
  143. m[6] = src[9]*src[4] - src[5]*src[8]
  144. m[7] = -src[9]*src[0] + src[1]*src[8]
  145. m[8] = src[5]*src[0] - src[1]*src[4]
  146. det := src[0]*m[0] + src[1]*m[3] + src[2]*m[6]
  147. // no inverse
  148. if det == 0 {
  149. m.Identity()
  150. return errors.New("Cannot inverse matrix")
  151. }
  152. m.MultiplyScalar(1.0 / det)
  153. return nil
  154. }
  155. // Transpose transposes this matrix.
  156. // Returns pointer to this updated matrix.
  157. func (m *Matrix3) Transpose() *Matrix3 {
  158. var tmp float32
  159. tmp = m[1]
  160. m[1] = m[3]
  161. m[3] = tmp
  162. tmp = m[2]
  163. m[2] = m[6]
  164. m[6] = tmp
  165. tmp = m[5]
  166. m[5] = m[7]
  167. m[7] = tmp
  168. return m
  169. }
  170. // GetNormalMatrix set this matrix to the matrix to transform the normal vectors
  171. // from the src matrix to transform the vertices.
  172. // If the src matrix cannot be inverted returns error.
  173. func (m *Matrix3) GetNormalMatrix(src *Matrix4) error {
  174. err := m.GetInverse(src)
  175. m.Transpose()
  176. return err
  177. }
  178. // FromArray set this matrix array starting at offset.
  179. // Returns pointer to this updated matrix.
  180. func (m *Matrix3) FromArray(array []float32, offset int) *Matrix3 {
  181. copy(m[:], array[offset:offset+9])
  182. return m
  183. }
  184. // ToArray copies this matrix to array starting at offset.
  185. // Returns pointer to the updated array.
  186. func (m *Matrix3) ToArray(array []float32, offset int) []float32 {
  187. copy(array[offset:], m[:])
  188. return array
  189. }
  190. // Clone creates and returns a pointer to a copy of this matrix.
  191. func (m *Matrix3) Clone() *Matrix3 {
  192. var cloned Matrix3
  193. cloned = *m
  194. return &cloned
  195. }