rect.monkey2 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. Namespace std.geom
  2. #rem monkeydoc Convenience type alias for Rect\<Int\>.
  3. #end
  4. Alias Recti:Rect<Int>
  5. #rem monkeydoc Convenience type alias for Rect\<Int\>.
  6. #end
  7. Alias Rectf:Rect<Float>
  8. #rem monkeydoc The Rect class provides support for manipulating rectangular regions.
  9. #end
  10. Struct Rect<T>
  11. #rem monkeydoc Minimum rect coordinates.
  12. #end
  13. Field min:Vec2<T>
  14. #rem monkeydoc Maximum rect coordinates.
  15. #end
  16. Field max:Vec2<T>
  17. #rem monkeydoic Creates a new Rect.
  18. #end
  19. Method New()
  20. End
  21. Method New( min:Vec2<T>,max:Vec2<T> )
  22. Self.min=min
  23. Self.max=max
  24. End
  25. Method New( x0:T,y0:T,x1:T,y1:T )
  26. min=New Vec2<T>( x0,y0 )
  27. max=New Vec2<T>( x1,y1 )
  28. End
  29. Method New( x0:T,y0:T,max:Vec2<T> )
  30. Self.min=New Vec2<T>( x0,y0 )
  31. Self.max=max
  32. End
  33. Method New( min:Vec2<T>,x1:T,y1:T )
  34. Self.min=min
  35. Self.max=New Vec2<T>( x1,y1 )
  36. End
  37. #rem monkeydoc The minimum X coordinate.
  38. #end
  39. Property X:T()
  40. Return min.x
  41. Setter( x:T )
  42. min.x=x
  43. End
  44. #rem monkeydoc The minimum Y coordinate.
  45. #end
  46. Property Y:T()
  47. Return min.y
  48. Setter( y:T )
  49. min.y=y
  50. End
  51. #rem monkeydoc The width of the rect.
  52. ' Writing to this property modifies the maximum Y coordinate only.
  53. #end
  54. Property Width:T()
  55. Return max.x-min.x
  56. ' Setter( width:T )
  57. ' max.x=min.x+width
  58. End
  59. #rem monkeydoc The height of the rect.
  60. ' Writing to this property modifies the maximum Y coordinate only.
  61. #end
  62. Property Height:T()
  63. Return max.y-min.y
  64. ' Setter( height:T )
  65. ' max.y=min.y+height
  66. End
  67. #rem monkeydoc The minimum X coordinate.
  68. #end
  69. Property Left:T()
  70. Return min.x
  71. Setter( left:T )
  72. min.x=left
  73. End
  74. #rem monkeydoc The minimum Y coordinate.
  75. #end
  76. Property Top:T()
  77. Return min.y
  78. Setter( top:T )
  79. min.y=top
  80. End
  81. #rem monkeydoc The maximum X coordinate.
  82. #end
  83. Property Right:T()
  84. Return max.x
  85. Setter( right:T )
  86. max.x=right
  87. End
  88. #rem monkeydoc The maximum X coordinate.
  89. #end
  90. Property Bottom:T()
  91. Return max.y
  92. Setter( bottom:T )
  93. max.y=bottom
  94. End
  95. #rem monkeydoc The top-left of the rect.
  96. #end
  97. Property Origin:Vec2<T>()
  98. Return min
  99. Setter( origin:Vec2<T> )
  100. min=origin
  101. End
  102. #rem monkeydoc The width and height of the rect.
  103. #end
  104. Property Size:Vec2<T>()
  105. Return max-min
  106. Setter( size:Vec2<T> )
  107. max=min+size
  108. End
  109. #rem monkeydoc The center of the rect.
  110. #end
  111. Property Center:Vec2<T>()
  112. Return (min+max)/2
  113. ' Setter( center:Vec2<T> )
  114. End
  115. #rem monkeydoc The top-left of the rect.
  116. #end
  117. Property TopLeft:Vec2<T>()
  118. Return min
  119. Setter( v:Vec2<T> )
  120. min=v
  121. End
  122. #rem monkeydoc The top-right of the rect.
  123. #end
  124. Property TopRight:Vec2<T>()
  125. Return New Vec2<T>( max.x,min.y )
  126. Setter( v:Vec2<T> )
  127. max.x=v.x
  128. min.y=v.y
  129. End
  130. #rem monkeydoc The bottom-right of the rect.
  131. #end
  132. Property BottomRight:Vec2<T>()
  133. Return max
  134. Setter( v:Vec2<T> )
  135. max=v
  136. End
  137. #rem monkeydoc The bottom-left of the rect.
  138. #end
  139. Property BottomLeft:Vec2<T>()
  140. Return New Vec2<T>( min.x,max.y )
  141. Setter( v:Vec2<T> )
  142. min.x=v.x
  143. max.y=v.y
  144. End
  145. #rem monkeydoc True if Right\<=Left or Bottom\<=Top.
  146. #end
  147. Property Empty:Bool()
  148. Return max.x<=min.x Or max.y<=min.y
  149. End
  150. #rem monkeydoc Adds another rect to the rect and returns the result.
  151. #end
  152. Operator+:Rect( r:Rect )
  153. Return New Rect( min+r.min,max+r.max )
  154. End
  155. #rem monkeydoc Subtracts another rect from the rect and returns the result.
  156. #end
  157. Operator-:Rect( r:Rect )
  158. Return New Rect( min-r.min,max-r.max )
  159. End
  160. #rem monkeydoc Multiples the rect by a vector and returns the result.
  161. #end
  162. Operator*:Rect( v:Vec2<T> )
  163. Return New Rect( min.x*v.x,min.y*v.y,max.x*v.x,max.y*v.y )
  164. End
  165. #rem monkeydoc Divides the rect by a vector and returns the result.
  166. #end
  167. Operator/:Rect( v:Vec2<T> )
  168. Return New Rect( min.x/v.x,min.y/v.y,max.x/v.x,max.y/v.y )
  169. End
  170. #rem monkeydoc Adds a vector to the rect and returns the result.
  171. #end
  172. Operator+:Rect( v:Vec2<T> )
  173. Return New Rect( min+v,max+v )
  174. End
  175. #rem monkeydoc Subtracts a vector from the rect and returns the result.
  176. #end
  177. Operator-:Rect( v:Vec2<T> )
  178. Return New Rect( min-v,max-v )
  179. End
  180. #rem monkeydoc Adds another rect to the rect.
  181. #end
  182. Operator+=( r:Rect )
  183. min+=r.min
  184. max+=r.max
  185. End
  186. #rem monkeydoc Subtracts another rect from the rect.
  187. #end
  188. Operator-=( r:Rect )
  189. min-=r.min
  190. max-=r.max
  191. End
  192. #rem monkeydoc Multiples the rect by a vector.
  193. #end
  194. Operator*=( v:Vec2<T> )
  195. min*=v
  196. max*=v
  197. End
  198. #rem monkeydoc Divides the rect by a vector.
  199. #end
  200. Operator/=( v:Vec2<T> )
  201. min/=v
  202. max/=v
  203. End
  204. #rem monkeydoc Adds a vector to the rect.
  205. #end
  206. Operator+=( v:Vec2<T> )
  207. min+=v
  208. max+=v
  209. End
  210. #rem monkeydoc Subtracts a vector from the rect.
  211. #end
  212. Operator-=( v:Vec2<T> )
  213. min-=v
  214. max-=v
  215. End
  216. #rem monkeydoc Computes the intersection of the rect with another rect and returns the result.
  217. #end
  218. Operator&:Rect( r:Rect )
  219. Local x0:=Max( min.x,r.min.x )
  220. Local y0:=Max( min.y,r.min.y )
  221. Local x1:=Min( max.x,r.max.x )
  222. Local y1:=Min( max.y,r.max.y )
  223. Return New Rect( x0,y0,x1,y1 )
  224. End
  225. #rem monkeydoc Computes the union of the rest with another rect and returns the result.
  226. #end
  227. Operator|:Rect( r:Rect )
  228. Local x0:=Min( min.x,r.min.x )
  229. Local y0:=Min( min.y,r.min.y )
  230. Local x1:=Max( max.x,r.max.x )
  231. Local y1:=Max( max.y,r.max.y )
  232. Return New Rect( x0,y0,x1,y1 )
  233. End
  234. #rem monkeydoc Intersects the rect with another rect.
  235. #end
  236. Operator&=( r:Rect )
  237. min.x=Max( min.x,r.min.x )
  238. min.y=Max( min.y,r.min.y )
  239. max.x=Min( max.x,r.max.x )
  240. max.y=Min( max.y,r.max.y )
  241. End
  242. #rem monkeydoc Unions the rect with another rect.
  243. #end
  244. Operator|=( r:Rect )
  245. min.x=Min( min.x,r.min.x )
  246. min.y=Min( min.y,r.min.y )
  247. max.x=Max( max.x,r.max.x )
  248. max.y=Max( max.y,r.max.y )
  249. End
  250. #rem monkeydoc Gets the rect centered within another rect.
  251. #end
  252. Method Centered:Rect( r:Rect )
  253. Local x:=(r.Width-Width)/2+min.x
  254. Local y:=(r.Height-Height)/2+min.y
  255. Return New Rect( x,y,x+Width,y+Height )
  256. End
  257. #rem monkeydoc Checks if the rect contains a vector or another rect.
  258. #end
  259. Method Contains:Bool( v:Vec2<T> )
  260. Return v.x>=min.x And v.x<max.x And v.y>=min.y And v.y<max.y
  261. End
  262. Method Contains:Bool( r:Rect )
  263. Return min.x<=r.min.x And max.x>=r.max.x And min.y<=r.min.y And max.y>=r.max.y
  264. End
  265. #rem monkeydoc Checks if the rect intersects another rect.
  266. #end
  267. Method Intersects:Bool( r:Rect )
  268. Return r.max.x>min.x And r.min.x<max.x And r.max.y>min.y And r.min.y<max.y
  269. End
  270. #rem monkeydoc Gets a string describing the rect.
  271. #end
  272. Method ToString:String()
  273. Return "Rect("+min.ToString()+","+max.ToString()+")"
  274. End
  275. End
  276. #rem monkeydoc Transforms a Rect\<Int\> by an AffineMat3.
  277. #end
  278. Function TransformRecti<T>:Recti( rect:Recti,matrix:AffineMat3<T> )
  279. Local min:=matrix * New Vec2<T>( rect.min.x,rect.min.y )
  280. Local max:=matrix * New Vec2<T>( rect.max.x,rect.max.y )
  281. Return New Recti( Round( min.x ),Round( min.y ),Round( max.x ),Round( max.y ) )
  282. End