matrix3.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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. // Matrix3 is 3x3 matrix organized internally as column matrix
  6. type Matrix3 [9]float32
  7. // NewMatrix3 creates and returns a pointer to a new Matrix3
  8. // initialized as the identity matrix.
  9. func NewMatrix3() *Matrix3 {
  10. var m Matrix3
  11. m.Identity()
  12. return &m
  13. }
  14. // Set sets all the elements of the matrix row by row starting at row1, column1,
  15. // row1, column2, row1, column3 and so forth.
  16. // Returns the pointer to this updated Matrix.
  17. func (m *Matrix3) Set(n11, n12, n13, n21, n22, n23, n31, n32, n33 float32) *Matrix3 {
  18. m[0] = n11
  19. m[3] = n12
  20. m[6] = n13
  21. m[1] = n21
  22. m[4] = n22
  23. m[7] = n23
  24. m[2] = n31
  25. m[5] = n32
  26. m[8] = n33
  27. return m
  28. }
  29. // Identity sets this matrix as the identity matrix.
  30. // Returns the pointer to this updated matrix.
  31. func (m *Matrix3) Identity() *Matrix3 {
  32. m.Set(
  33. 1, 0, 0,
  34. 0, 1, 0,
  35. 0, 0, 1,
  36. )
  37. return m
  38. }
  39. // Copy copies src matrix into this one.
  40. // Returns the pointer to this updated matrix.
  41. func (m *Matrix3) Copy(src *Matrix3) *Matrix3 {
  42. *m = *src
  43. return m
  44. }
  45. // ApplyToVector3Array multiplies length vectors in the array starting at offset by this matrix.
  46. // Returns pointer to the updated array.
  47. // This matrix is unchanged.
  48. func (m *Matrix3) ApplyToVector3Array(array []float32, offset int, length int) []float32 {
  49. var v1 Vector3
  50. j := offset
  51. for i := 0; i < length; i += 3 {
  52. v1.X = array[j]
  53. v1.Y = array[j+1]
  54. v1.Z = array[j+2]
  55. v1.ApplyMatrix3(m)
  56. array[j] = v1.X
  57. array[j+1] = v1.Y
  58. array[j+2] = v1.Z
  59. }
  60. return array
  61. }
  62. // MultiplyScalar multiplies each of this matrix's components by the specified scalar.
  63. // Returns pointer to this updated matrix.
  64. func (m *Matrix3) MultiplyScalar(s float32) *Matrix3 {
  65. m[0] *= s
  66. m[3] *= s
  67. m[6] *= s
  68. m[1] *= s
  69. m[4] *= s
  70. m[7] *= s
  71. m[2] *= s
  72. m[5] *= s
  73. m[8] *= s
  74. return m
  75. }
  76. // Determinant calculates and returns the determinant of this matrix.
  77. func (m *Matrix3) Determinant() float32 {
  78. return m[0]*m[4]*m[8] -
  79. m[0]*m[5]*m[7] -
  80. m[1]*m[3]*m[8] +
  81. m[1]*m[5]*m[6] +
  82. m[2]*m[3]*m[7] -
  83. m[2]*m[4]*m[6]
  84. }
  85. // GetInverse sets this matrix to the inverse of the src matrix and
  86. // returns pointer to this updated matrix.
  87. // If the src matrix cannot be inverted returns nil and
  88. // sets this matrix to the identity matrix.
  89. func (m *Matrix3) GetInverse(src *Matrix4) *Matrix3 {
  90. m[0] = src[10]*src[5] - src[6]*src[9]
  91. m[1] = -src[10]*src[1] + src[2]*src[9]
  92. m[2] = src[6]*src[1] - src[2]*src[5]
  93. m[3] = -src[10]*src[4] + src[6]*src[8]
  94. m[4] = src[10]*src[0] - src[2]*src[8]
  95. m[5] = -src[6]*src[0] + src[2]*src[4]
  96. m[6] = src[9]*src[4] - src[5]*src[8]
  97. m[7] = -src[9]*src[0] + src[1]*src[8]
  98. m[8] = src[5]*src[0] - src[1]*src[4]
  99. det := src[0]*m[0] + src[1]*m[3] + src[2]*m[6]
  100. // no inverse
  101. if det == 0 {
  102. m.Identity()
  103. return nil
  104. }
  105. m.MultiplyScalar(1.0 / det)
  106. return m
  107. }
  108. // Transpose transposes this matrix.
  109. // Returns pointer to this updated matrix.
  110. func (m *Matrix3) Transpose() *Matrix3 {
  111. var tmp float32
  112. tmp = m[1]
  113. m[1] = m[3]
  114. m[3] = tmp
  115. tmp = m[2]
  116. m[2] = m[6]
  117. m[6] = tmp
  118. tmp = m[5]
  119. m[5] = m[7]
  120. m[7] = tmp
  121. return m
  122. }
  123. // GetNormalMatrix set this matrix to the matrix to transform the normal vectors
  124. // from the src matrix to transform the vertices.
  125. // If the src matrix cannot be inverted, returns nil
  126. // otherwise returns pointer to this updated matrix.
  127. func (m *Matrix3) GetNormalMatrix(src *Matrix4) *Matrix3 {
  128. inv := m.GetInverse(src)
  129. m.Transpose()
  130. if inv == nil {
  131. return nil
  132. }
  133. return m
  134. }
  135. // FromArray set this matrix array starting at offset.
  136. // Returns pointer to this updated matrix.
  137. func (m *Matrix3) FromArray(array []float32, offset int) *Matrix3 {
  138. copy(m[:], array[offset:offset+9])
  139. return m
  140. }
  141. // ToArray copies this matrix to array starting at offset.
  142. // Returns pointer to the updated array.
  143. func (m *Matrix3) ToArray(array []float32, offset int) []float32 {
  144. copy(array[offset:], m[:])
  145. return array
  146. }
  147. // Clone creates and returns a pointer to a copy of this matrix.
  148. func (m *Matrix3) Clone() *Matrix3 {
  149. var cloned Matrix3
  150. cloned = *m
  151. return &cloned
  152. }