mat3.monkey2 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. Namespace std.geom
  2. #rem monkeydoc Convenience type alias for Mat3\<Float\>.
  3. #end
  4. Alias Mat3f:Mat3<Float>
  5. #rem monkeydoc The generic Mat3 class provides support for 3x3 matrices.
  6. #end
  7. Struct Mat3<T>
  8. #rem monkeydoc The first row of the matrix.
  9. #end
  10. Field i:Vec3<T>
  11. #rem monkeydoc The second row of the matrix.
  12. #end
  13. Field j:Vec3<T>
  14. #rem monkeydoc The third row of the matrix.
  15. #end
  16. Field k:Vec3<T>
  17. #rem monkeydoc Creates a new Matrix.
  18. #end
  19. Method New()
  20. i.x=1;j.y=1;k.z=1
  21. End
  22. Method New( ix:Float,jy:Float,kz:Float )
  23. i.x=ix; j.y=jy; k.z=kz
  24. End
  25. Method New( ix:T,iy:T,iz:T,jx:T,jy:T,jz:T,kx:T,ky:T,kz:T )
  26. i.x=ix; i.y=iy; i.z=iz
  27. j.x=jx; j.y=jy; j.z=jz
  28. k.x=kx; k.y=ky; k.z=kz
  29. End
  30. Method New( i:Vec3<T>,j:Vec3<T>,k:Vec3<T> )
  31. Self.i=i; Self.j=j; Self.k=k
  32. End
  33. Method New( quat:Quat<T> )
  34. Local xx:=quat.v.x*quat.v.x , yy:=quat.v.y*quat.v.y , zz:=quat.v.z*quat.v.z
  35. Local xy:=quat.v.x*quat.v.y , xz:=quat.v.x*quat.v.z , yz:=quat.v.y*quat.v.z
  36. Local wx:=quat.w*quat.v.x , wy:=quat.w*quat.v.y , wz:=quat.w*quat.v.z
  37. i.x=1-2*(yy+zz) ; i.y= 2*(xy-wz) ; i.z= 2*(xz+wy)
  38. j.x= 2*(xy+wz) ; j.y=1-2*(xx+zz) ; j.z= 2*(yz-wx)
  39. k.x= 2*(xz-wy) ; k.y= 2*(yz+wx) ; k.z=1-2*(xx+yy)
  40. End
  41. #rem monkeydoc Converts the matrix to a matrix of another type, or to a quaternion or printable string.
  42. #end
  43. Operator To<C>:Mat3<C>()
  44. Return New Mat3<C>( i,j,k )
  45. End
  46. Operator To:Quat<T>()
  47. Return New Quat<T>( Self )
  48. End
  49. Operator To:String()
  50. Return "Mat3("+i+","+j+","+k+")"
  51. End
  52. #rem monkeydoc The determinant of the matrix.
  53. #end
  54. Property Determinant:T()
  55. Return i.x*(j.y*k.z-j.z*k.y )-i.y*(j.x*k.z-j.z*k.x )+i.z*(j.x*k.y-j.y*k.x )
  56. End
  57. #rem monkeydoc Computes the transpose of the matrix.
  58. #end
  59. Operator~:Mat3()
  60. Return New Mat3( i.x,j.x,k.x, i.y,j.y,k.y, i.z,j.z,k.z )
  61. End
  62. #rem monkeydoc Computes the inverse of the matrix.
  63. #end
  64. Operator-:Mat3()
  65. Local t:=1.0/Determinant
  66. Return New Mat3(
  67. t*(j.y*k.z-j.z*k.y),-t*(i.y*k.z-i.z*k.y), t*(i.y*j.z-i.z*j.y),
  68. -t*(j.x*k.z-j.z*k.x), t*(i.x*k.z-i.z*k.x),-t*(i.x*j.z-i.z*j.x),
  69. t*(j.x*k.y-j.y*k.x),-t*(i.x*k.y-i.y*k.x), t*(i.x*j.y-i.y*j.x) )
  70. End
  71. #rem monkeydoc Multiplies the matrix by another matrix.
  72. #end
  73. Operator*:Mat3( m:Mat3 )
  74. Return New Mat3(
  75. i.x*m.i.x+j.x*m.i.y+k.x*m.i.z, i.y*m.i.x+j.y*m.i.y+k.y*m.i.z, i.z*m.i.x+j.z*m.i.y+k.z*m.i.z,
  76. i.x*m.j.x+j.x*m.j.y+k.x*m.j.z, i.y*m.j.x+j.y*m.j.y+k.y*m.j.z, i.z*m.j.x+j.z*m.j.y+k.z*m.j.z,
  77. i.x*m.k.x+j.x*m.k.y+k.x*m.k.z, i.y*m.k.x+j.y*m.k.y+k.y*m.k.z, i.z*m.k.x+j.z*m.k.y+k.z*m.k.z )
  78. End
  79. #rem monkeydoc Multiplies a vector by the matrix.
  80. #end
  81. Operator*:Vec3<T>( v:Vec3<T> )
  82. Return New Vec3<T>( i.x*v.x+j.x*v.y+k.x*v.z,i.y*v.x+j.y*v.y+k.y*v.z,i.z*v.x+j.z*v.y+k.z*v.z )
  83. End
  84. #rem monkeydoc Gets a row of the matrix.
  85. #end
  86. Method GetRow:Vec3<T>( row:Int )
  87. Return row=0 ? i Else (row=1 ? j Else k)
  88. End
  89. #rem monkeydoc Gets a column of the matrix.
  90. #end
  91. Method GetColumn:Vec3<T>( col:Int )
  92. Return col=0 ? New Vec3<T>( i.x,j.x,k.x ) Else (col=1 ? New Vec3<T>( i.y,j.y,k.y ) Else New Vec3<T>( i.z,j.z,k.z ))
  93. End
  94. #rem monkeydocs Computes the cofactor matrix.
  95. #end
  96. Method Cofactor:Mat3()
  97. Return New Mat3(
  98. (j.y*k.z-j.z*k.y),-(j.x*k.z-j.z*k.x), (j.x*k.y-j.y*k.x),
  99. -(i.y*k.z-i.z*k.y), (i.x*k.z-i.z*k.x),-(i.x*k.y-i.y*k.x),
  100. (i.y*j.z-i.z*j.y),-(i.x*j.z-i.z*j.x), (i.x*j.y-i.y*j.x) )
  101. End
  102. #rem monkeydocs Computes the pitch of the matrix in radians.
  103. Pitch is the angle of rotation around the X axis.
  104. #end
  105. Method GetPitch:Double()
  106. Return k.Pitch
  107. End
  108. #rem monkeydocs Computes the yaw of the matrix in radians.
  109. Yaw is the angle of rotation around the Y axis.
  110. #end
  111. Method GetYaw:Double()
  112. Return k.Yaw
  113. End
  114. #rem monkeydocs Computes the roll of the matrix in radians.
  115. Roll is the angle of rotation around the Z axis.
  116. #end
  117. Method GetRoll:Double()
  118. Return ATan2( i.y,j.y )
  119. End
  120. #rem monkeydoc Computes the pitch, yaw and roll angles of rotation in radians.
  121. #end
  122. Method GetRotation:Vec3<T>()
  123. Return New Vec3<T>( GetPitch(),GetYaw(),GetRoll() )
  124. End
  125. #rem monkeydoc Computes the scaling term of the matrix.
  126. #end
  127. Method GetScaling:Vec3<T>()
  128. Return New Vec3<T>( i.Length,j.Length,k.Length )
  129. End
  130. #rem monkeydoc Rotates the matrix by euler angles or a quaternion.
  131. #end
  132. Method Rotate:Mat3( rv:Vec3<T> )
  133. Return Self * Rotation( rv )
  134. End
  135. Method Rotate:Mat3( rx:Double,ry:Double,rz:Double )
  136. Return Self * Rotation( rx,ry,rz )
  137. End
  138. Method Rotate:Mat3( q:Quat<T> )
  139. Return Self * Rotation( q )
  140. End
  141. #rem monkeydoc Scales the matrix.
  142. #end
  143. Method Scale:Mat3( rv:Vec3<T> )
  144. Return Self * Scaling( rv )
  145. End
  146. Method Scale:Mat3( sx:T,sy:T,sz:T )
  147. Return Self * Scaling( sx,sy,sz )
  148. End
  149. Method Scale:Mat3( t:T )
  150. Return Self * Scaling( t )
  151. End
  152. #rem monkeydoc Orthogonalizes the matrix.
  153. #end
  154. Method Orthogonalize:Mat3()
  155. Local k:=Self.k.Normalize()
  156. Return New Mat3( j.Cross( k ).Normalize(),k.Cross( i ).Normalize(),k )
  157. End
  158. #rem monkeydoc Creates a yaw rotation matrix.
  159. Returns a matrix representing a rotation of `angle` radians around the Y axis.
  160. #end
  161. Function Yaw:Mat3( angle:Double )
  162. Local sin:=Sin(angle),cos:=Cos(angle)
  163. Return New Mat3( cos,0,sin, 0,1,0, -sin,0,cos )
  164. End
  165. #rem monkeydoc Creates a pitch rotation matrix.
  166. Returns a matrix representing a rotation of `angle` radians around the X axis.
  167. #end
  168. Function Pitch:Mat3( angle:Double )
  169. Local sin:=Sin(angle),cos:=Cos(angle)
  170. return New Mat3( 1,0,0, 0,cos,sin, 0,-sin,cos )
  171. End
  172. #rem monkeydoc Creates a yaw rotation matrix.
  173. Returns a matrix representing a rotation of `angle` radians around the Y axis.
  174. #end
  175. Function Roll:Mat3( angle:Double )
  176. Local sin:=Sin(angle),cos:=Cos(angle)
  177. Return New Mat3( cos,sin,0, -sin,cos,0, 0,0,1 )
  178. End
  179. #rem monkeydoc Creates a rotation matrix from euler angles or a quat.
  180. For euler angles, the order of rotation is Yaw * Pitch * Roll.
  181. #end
  182. Function Rotation:Mat3( rv:Vec3<Double> )
  183. Return Yaw( rv.y ) * Pitch( rv.x ) * Roll( rv.z )
  184. End
  185. Function Rotation:Mat3( rx:Double,ry:Double,rz:Double )
  186. Return Yaw( ry ) * Pitch( rx ) * Roll( rz )
  187. End
  188. Function Rotation:Mat3( q:Quat<T> )
  189. Return New Mat3( q )
  190. End
  191. #rem monkeydoc Creates a scaling matrix.
  192. #end
  193. Function Scaling:Mat3( sv:Vec3<T> )
  194. Return New Mat3( sv.x,sv.y,sv.z )
  195. End
  196. Function Scaling:Mat3( sx:T,sy:T,sz:T )
  197. Return New Mat3( sx,sy,sz )
  198. End
  199. Function Scaling:Mat3( t:T )
  200. Return New Mat3( t,t,t )
  201. End
  202. End