affinemat3.monkey2 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. Namespace std.geom
  2. #rem monkeydoc Convenience type alias for AffineMat3\<Float\>
  3. #end
  4. Alias AffineMat3f:AffineMat3<Float>
  5. #rem monkeydoc The generic AffineMat3f class provides support for affine 3x3 matrices.
  6. An affine 3x3 matrix is a 3x3 matrix whose right hand column is always 0,0,1.
  7. Affine 3x3 matrices are often used for 2d transformations such as scaling, rotation and translation.
  8. Unless otherwise noted, methods and operators always return a new vec3 containing the result, without modifying any parameters or 'self'.
  9. This allows you to chain operators together easily just like 'real' expressions.
  10. #end
  11. Struct AffineMat3<T>
  12. #rem monkeydoc The first row of the matrix.
  13. #end
  14. Field i:Vec2<T>
  15. #rem monkeydoc The second row of the matrix.
  16. #end
  17. Field j:Vec2<T>
  18. #rem monkeydoc The third row of the matrix.
  19. #end
  20. Field t:Vec2<T>
  21. #rem monkeydoc Creates a new matrix.
  22. #end
  23. Method New()
  24. i.x=1;j.y=1
  25. End
  26. Method New( i:Vec2<T>,j:Vec2<T>,t:Vec2<T> )
  27. Self.i=i;Self.j=j;Self.t=t
  28. End
  29. Method New( ix:T,iy:T,jx:T,jy:T,tx:T,ty:T )
  30. Self.i.x=ix;Self.i.y=iy;Self.j.x=jx;Self.j.y=jy;Self.t.x=tx;Self.t.y=ty
  31. End
  32. #rem monkeydoc Converts the matrix to a matrix of a different type, or a printable string.
  33. #end
  34. Operator To<C>:AffineMat3<C>()
  35. Return New AffineMat3<C>( i.x,i.y,j.x,j.y,t.x,t.y )
  36. End
  37. #rem monkeydoc Converts the matrix to a printable string.
  38. #end
  39. Operator To:String()
  40. Return "AffineMat3("+i.x+","+i.y+","+j.x+","+j.y+","+t.x+","+t.y+")"
  41. End
  42. #rem monkeydoc Inverts the matrix.
  43. #end
  44. Operator-:AffineMat3()
  45. Local idet:=1.0/(i.x*j.y-i.y*j.x)
  46. Return New AffineMat3(
  47. j.y*idet , -i.y*idet,
  48. -j.x*idet , i.x*idet,
  49. (j.x*t.y-j.y*t.x)*idet , (i.y*t.x-i.x*t.y)*idet )
  50. End
  51. #rem monkeydoc Multiplies a vector by the matrix.
  52. #end
  53. Operator*:Vec2<T>( v:Vec2<T> )
  54. Return New Vec2<T>( i.x*v.x + j.x*v.y + t.x , i.y*v.x + j.y*v.y + t.y )
  55. End
  56. #rem monkeydoc Multiplies a rect by the matrix.
  57. #end
  58. Operator*:Rect<T>( r:Rect<T> )
  59. Return New Rect<T>( Self * r.min,Self * r.max )
  60. End
  61. #rem monkeydoc Multiplies the matrix by another matrix.
  62. #end
  63. Operator*:AffineMat3( m:AffineMat3 )
  64. Return New AffineMat3(
  65. i.x*m.i.x + j.x*m.i.y , i.y*m.i.x + j.y*m.i.y ,
  66. i.x*m.j.x + j.x*m.j.y , i.y*m.j.x + j.y*m.j.y ,
  67. i.x*m.t.x + j.x*m.t.y + t.x , i.y*m.t.x + j.y*m.t.y + t.y )
  68. End
  69. #rem monkeydoc Multiplies a vector by the matrix.
  70. #end
  71. Method Transform:Vec2<T>( v:Vec2<T> )
  72. Return New Vec2<T>( i.x*v.x + j.x*v.y + t.x , i.y*v.x + j.y*v.y + t.y )
  73. End
  74. #rem monkeydoc Multiplies a vector by the matrix.
  75. #end
  76. Method Transform:Vec2<T>( x:T,y:T )
  77. Return New Vec2<T>( i.x*x + j.x*y + t.x , i.y*x + j.y*y + t.y )
  78. End
  79. #rem monkeydoc Multiplies the matrix by another matrix.
  80. #end
  81. Method Transform:AffineMat3( ix:Float,iy:Float,jx:Float,jy:Float,tx:Float,ty:Float )
  82. Return New AffineMat3(
  83. i.x*ix + j.x*iy , i.y*ix + j.y*iy ,
  84. i.x*jx + j.x*jy , i.y*jx + j.y*jy ,
  85. i.x*tx + j.x*ty + t.x , i.y*tx + j.y*ty + t.y )
  86. End
  87. #rem monkeydoc Applies a translation transformation to the matrix.
  88. #end
  89. Method Translate:AffineMat3( tx:T,ty:T )
  90. Return Transform( 1,0,0,1,tx,ty )
  91. End
  92. Method Translate:AffineMat3( tv:Vec2<T> )
  93. Return Transform( 1,0,0,1,tv.x,tv.y )
  94. End
  95. #rem monkeydoc Applies a rotation transformation to the matrix.
  96. #end
  97. Method Rotate:AffineMat3( rz:Double )
  98. Return Transform( Cos( rz ),-Sin( rz ),Sin( rz ),Cos( rz ),0,0 )
  99. End
  100. #rem monkeydoc Applies a scale transformation to the matrix.
  101. #end
  102. Method Scale:AffineMat3( sx:T,sy:T )
  103. Return Transform( sx,0,0,sy,0,0 )
  104. End
  105. Method Scale:AffineMat3( sv:Vec2<T> )
  106. Return Transform( sv.x,0,0,sv.y,0,0 )
  107. End
  108. #rem monkeydoc Creates a matrix representing a translation.
  109. #end
  110. Function Translation:AffineMat3( tx:T,ty:T )
  111. Return New AffineMat3( 1,0,0,1,tx,ty )
  112. End
  113. Function Translation:AffineMat3( tv:Vec2<T> )
  114. Return New AffineMat3( 1,0,0,1,tv.x,tv.y )
  115. End
  116. #rem monkeydoc Creates a matrix representing a rotation.
  117. The `rotation` parameter is in radians.
  118. #end
  119. Function Rotation:AffineMat3( rz:Double )
  120. Return New AffineMat3( Cos( rz ),-Sin( rz ),Sin( rz ),Cos( rz ),0,0 )
  121. End
  122. #rem monkeydoc Creates a matrix representing a scaling.
  123. #end
  124. Function Scaling:AffineMat3( sx:T,sy:T )
  125. Return New AffineMat3( sx,0,0,sy,0,0 )
  126. End
  127. Function Scaling:AffineMat3( sv:Vec2<T> )
  128. Return New AffineMat3( sv.x,0,0,sv.y,0,0 )
  129. End
  130. #rem monkeydoc Creates a matrix representing an orthographic projection.
  131. #end
  132. Function Ortho:AffineMat3( left:T,right:T,bottom:T,top:T )
  133. Local w:=right-left,h:=top-bottom
  134. Local r:AffineMat3
  135. r.i.x=2/w
  136. r.j.y=2/h
  137. r.t.x=-(right+left)/w
  138. r.t.y=-(top+bottom)/h
  139. Return r
  140. End
  141. End