Rectangle.h 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. /******************************************************************************
  2. Use 'Rect' to handle rectangle shape, Flt type
  3. Use 'RectI' to handle rectangle shape, Int type
  4. /******************************************************************************/
  5. enum FIT_MODE : Byte // Fit Mode, these modes specify fitting while preserving original proportions
  6. {
  7. FIT_FULL , // fit width and height to fit the entire source
  8. FIT_FILL , // fit width and height to fill the entire destination
  9. FIT_WIDTH , // fit width
  10. FIT_HEIGHT, // fit height
  11. };
  12. /******************************************************************************/
  13. struct Rect // Rectangle Shape
  14. {
  15. Vec2 min, max;
  16. Rect& zero( ) { min.zero(); max.zero(); return T;} // zero rectangle coordinates
  17. Rect& set (C Vec2 &min, C Vec2 &max ) {T.min=min ; T.max=max ; return T;} // set rectangle from minimum maximum coordinates
  18. Rect& set ( Flt min_x, Flt min_y, Flt max_x, Flt max_y) {min.set(min_x, min_y); max.set(max_x, max_y); return T;} // set rectangle from minimum maximum coordinates
  19. Rect& setX(Flt x ) {T.min.x=x ; T.max.x= x; return T;}
  20. Rect& setY(Flt y ) {T.min.y=y ; T.max.y= y; return T;}
  21. Rect& setX(Flt min, Flt max) {T.min.x=min; T.max.x=max; return T;}
  22. Rect& setY(Flt min, Flt max) {T.min.y=min; T.max.y=max; return T;}
  23. Rect& setRU(C Vec2 &ru, C Vec2 &size) {min.set(ru.x-size.x , ru.y-size.y ); max.set(ru.x , ru.y ); return T;} // set rectangle by specifying its "Right Up" position
  24. Rect& setLU(C Vec2 &lu, C Vec2 &size) {min.set(lu.x , lu.y-size.y ); max.set(lu.x+size.x , lu.y ); return T;} // set rectangle by specifying its "Left Up" position
  25. Rect& setRD(C Vec2 &rd, C Vec2 &size) {min.set(rd.x-size.x , rd.y ); max.set(rd.x , rd.y+size.y ); return T;} // set rectangle by specifying its "Right Down" position
  26. Rect& setLD(C Vec2 &ld, C Vec2 &size) {min.set(ld.x , ld.y ); max.set(ld.x+size.x , ld.y+size.y ); return T;} // set rectangle by specifying its "Left Down" position
  27. Rect& setR (C Vec2 &r , C Vec2 &size) {min.set( r.x-size.x , r.y-size.y*0.5f); max.set( r.x , r.y+size.y*0.5f); return T;} // set rectangle by specifying its "Right" position
  28. Rect& setL (C Vec2 &l , C Vec2 &size) {min.set( l.x , l.y-size.y*0.5f); max.set( l.x+size.x , l.y+size.y*0.5f); return T;} // set rectangle by specifying its "Left" position
  29. Rect& setU (C Vec2 &u , C Vec2 &size) {min.set( u.x-size.x*0.5f, u.y-size.y ); max.set( u.x+size.x*0.5f, u.y ); return T;} // set rectangle by specifying its "Up" position
  30. Rect& setD (C Vec2 &d , C Vec2 &size) {min.set( d.x-size.x*0.5f, d.y ); max.set( d.x+size.x*0.5f, d.y+size.y ); return T;} // set rectangle by specifying its "Down" position
  31. Rect& setC (C Vec2 &c , C Vec2 &size) {min.set( c.x-size.x*0.5f, c.y-size.y*0.5f); max.set( c.x+size.x*0.5f, c.y+size.y*0.5f); return T;} // set rectangle by specifying its "Center" position
  32. Rect& setRU(C Vec2 &ru, Flt w, Flt h) {min.set(ru.x-w , ru.y-h ); max.set(ru.x , ru.y ); return T;} // set rectangle by specifying its "Right Up" position
  33. Rect& setLU(C Vec2 &lu, Flt w, Flt h) {min.set(lu.x , lu.y-h ); max.set(lu.x+w , lu.y ); return T;} // set rectangle by specifying its "Left Up" position
  34. Rect& setRD(C Vec2 &rd, Flt w, Flt h) {min.set(rd.x-w , rd.y ); max.set(rd.x , rd.y+h ); return T;} // set rectangle by specifying its "Right Down" position
  35. Rect& setLD(C Vec2 &ld, Flt w, Flt h) {min.set(ld.x , ld.y ); max.set(ld.x+w , ld.y+h ); return T;} // set rectangle by specifying its "Left Down" position
  36. Rect& setR (C Vec2 &r , Flt w, Flt h) {min.set( r.x-w , r.y-h*0.5f); max.set( r.x , r.y+h*0.5f); return T;} // set rectangle by specifying its "Right" position
  37. Rect& setL (C Vec2 &l , Flt w, Flt h) {min.set( l.x , l.y-h*0.5f); max.set( l.x+w , l.y+h*0.5f); return T;} // set rectangle by specifying its "Left" position
  38. Rect& setU (C Vec2 &u , Flt w, Flt h) {min.set( u.x-w*0.5f, u.y-h ); max.set( u.x+w*0.5f, u.y ); return T;} // set rectangle by specifying its "Up" position
  39. Rect& setD (C Vec2 &d , Flt w, Flt h) {min.set( d.x-w*0.5f, d.y ); max.set( d.x+w*0.5f, d.y+h ); return T;} // set rectangle by specifying its "Down" position
  40. Rect& setC (C Vec2 &c , Flt w, Flt h) {min.set( c.x-w*0.5f, c.y-h*0.5f); max.set( c.x+w*0.5f, c.y+h*0.5f); return T;} // set rectangle by specifying its "Center" position
  41. Rect& setC (C Vec2 &c , Flt r ) {min.set( c.x-r , c.y-r ); max.set( c.x+r , c.y+r ); return T;} // set rectangle by specifying its "Center" position
  42. Rect& setRU(Flt x, Flt y, Flt w, Flt h) {min.set(x-w , y-h ); max.set(x , y ); return T;} // set rectangle by specifying its "Right Up" position
  43. Rect& setLU(Flt x, Flt y, Flt w, Flt h) {min.set(x , y-h ); max.set(x+w , y ); return T;} // set rectangle by specifying its "Left Up" position
  44. Rect& setRD(Flt x, Flt y, Flt w, Flt h) {min.set(x-w , y ); max.set(x , y+h ); return T;} // set rectangle by specifying its "Right Down" position
  45. Rect& setLD(Flt x, Flt y, Flt w, Flt h) {min.set(x , y ); max.set(x+w , y+h ); return T;} // set rectangle by specifying its "Left Down" position
  46. Rect& setR (Flt x, Flt y, Flt w, Flt h) {min.set(x-w , y-h*0.5f); max.set(x , y+h*0.5f); return T;} // set rectangle by specifying its "Right" position
  47. Rect& setL (Flt x, Flt y, Flt w, Flt h) {min.set(x , y-h*0.5f); max.set(x+w , y+h*0.5f); return T;} // set rectangle by specifying its "Left" position
  48. Rect& setU (Flt x, Flt y, Flt w, Flt h) {min.set(x-w*0.5f, y-h ); max.set(x+w*0.5f, y ); return T;} // set rectangle by specifying its "Up" position
  49. Rect& setD (Flt x, Flt y, Flt w, Flt h) {min.set(x-w*0.5f, y ); max.set(x+w*0.5f, y+h ); return T;} // set rectangle by specifying its "Down" position
  50. Rect& setC (Flt x, Flt y, Flt w, Flt h) {min.set(x-w*0.5f, y-h*0.5f); max.set(x+w*0.5f, y+h*0.5f); return T;} // set rectangle by specifying its "Center" position
  51. Rect& setC (Flt x, Flt y, Flt r ) {min.set(x-r , y-r ); max.set(x+r , y+r ); return T;} // set rectangle by specifying its "Center" position
  52. Rect& operator+=(C Vec2 &v) {min+=v ; max+=v ; return T;}
  53. Rect& operator-=(C Vec2 &v) {min-=v ; max-=v ; return T;}
  54. Rect& operator+=(C Vec &v) {min+=v.xy; max+=v.xy; return T;}
  55. Rect& operator-=(C Vec &v) {min-=v.xy; max-=v.xy; return T;}
  56. Rect& operator*=( Flt r) {min*=r ; max*=r ; return T;}
  57. Rect& operator/=( Flt r) {min/=r ; max/=r ; return T;}
  58. Rect& operator*=(C Vec2 &v) {min*=v ; max*=v ; return T;}
  59. Rect& operator/=(C Vec2 &v) {min/=v ; max/=v ; return T;}
  60. Rect& operator|=(C Vec2 &v) {return include(v);}
  61. Rect& operator|=(C Rect &r) {return include(r);}
  62. Rect& operator&=(C Rect &r); // intersect
  63. Rect& operator&=(C RectI &r); // intersect
  64. Bool operator==(C Rect &r)C {return min==r.min && max==r.max;}
  65. Bool operator!=(C Rect &r)C {return min!=r.min || max!=r.max;}
  66. friend Rect operator+ (C Rect &rect, C Vec2 &v) {return Rect(rect)+=v;}
  67. friend Rect operator- (C Rect &rect, C Vec2 &v) {return Rect(rect)-=v;}
  68. friend Rect operator* (C Rect &rect, Flt r) {return Rect(rect)*=r;}
  69. friend Rect operator/ (C Rect &rect, Flt r) {return Rect(rect)/=r;}
  70. friend Rect operator* (C Rect &rect, C Vec2 &v) {return Rect(rect)*=v;}
  71. friend Rect operator/ (C Rect &rect, C Vec2 &v) {return Rect(rect)/=v;}
  72. friend Rect operator| (C Rect &rect, C Vec2 &v) {return Rect(rect)|=v;} // union
  73. friend Rect operator| (C Rect &rect, C Rect &r) {return Rect(rect)|=r;} // union
  74. friend Rect operator& (C Rect &rect, C Rect &r) {return Rect(rect)&=r;} // intersection
  75. friend Rect operator& (C Rect &rect, C RectI &r) {return Rect(rect)&=r;} // intersection
  76. // get
  77. Flt w ( )C {return max.x - min.x ;} // get width
  78. Flt h ( )C {return max.y - min.y ;} // get height
  79. Vec2 size ( )C {return max - min ;} // get size
  80. Vec2 ld ( )C {return min ;} // get Left Down corner
  81. Vec2 ru ( )C {return max ;} // get Right Up corner
  82. Vec2 lu ( )C {return Vec2(min.x , max.y ) ;} // get Left Up corner
  83. Vec2 rd ( )C {return Vec2(max.x , min.y ) ;} // get Right Down corner
  84. Vec2 left ( )C {return Vec2(min.x , centerY() ) ;} // get Left point
  85. Vec2 right ( )C {return Vec2(max.x , centerY() ) ;} // get Right point
  86. Vec2 down ( )C {return Vec2(centerX() , min.y ) ;} // get Down point
  87. Vec2 up ( )C {return Vec2(centerX() , max.y ) ;} // get Up point
  88. Flt centerX ( )C {return Avg(min.x , max.x ) ;} // get center X
  89. Flt centerY ( )C {return Avg(min.y , max.y ) ;} // get center Y
  90. Vec2 center ( )C {return Vec2(centerX() , centerY() ) ;} // get center
  91. Vec2 xs ( )C {return Vec2(min.x , max.x ) ;} // get min max X's as Vec2
  92. Vec2 ys ( )C {return Vec2(min.y , max.y ) ;} // get min max Y's as Vec2
  93. Flt lerpX (Flt s )C {return Lerp(min.x , max.x, s ) ;} // lerp between min.x and max.x
  94. Flt lerpY (Flt s )C {return Lerp(min.y , max.y, s ) ;} // lerp between min.y and max.y
  95. Vec2 lerp (Flt x, Flt y)C {return Vec2(lerpX( x), lerpY( y)) ;} // lerp between min and max
  96. Vec2 lerp (C Vec2 &s )C {return Vec2(lerpX(s.x), lerpY(s.y)) ;} // lerp between min and max
  97. Bool includesX( Flt x )C {return x>=min.x && x<=max.x ;} // if rectangle includes 'x'
  98. Bool includesY( Flt y )C {return y>=min.y && y<=max.y ;} // if rectangle includes 'y'
  99. Bool includes (C Vec2 &v )C {return includesX(v.x) && includesY(v.y);} // if rectangle includes vector
  100. Bool validX ( )C {return min.x<=max.x ;} // if has valid X's
  101. Bool validY ( )C {return min.y<=max.y ;} // if has valid Y's
  102. Bool valid ( )C {return validX() && validY() ;} // if is valid
  103. Bool vertical ( )C {return h()>w() ;} // if rectangle is vertical (height greater than width)
  104. Flt area ( )C {return w()*h() ;} // get surface area
  105. Flt aspect ( )C {return w()/h() ;} // get aspect ratio
  106. Str asText()C {return S+"Min: "+min+", Max: "+max;} // get text description
  107. // operations
  108. Rect& extendX ( Flt e ); // extend rectangle X's
  109. Rect& extendY ( Flt e ); // extend rectangle Y's
  110. Rect& extend ( Flt e ); // extend rectangle
  111. Rect& extend (C Vec2 &v ); // extend rectangle
  112. Rect& extend ( Flt x , Flt y ); // extend rectangle
  113. Rect& includeX ( Flt x ); // extend rectangle to include 'x'
  114. Rect& includeY ( Flt y ); // extend rectangle to include 'y'
  115. Rect& includeX ( Flt min, Flt max); // extend rectangle to include min..max range
  116. Rect& includeY ( Flt min, Flt max); // extend rectangle to include min..max range
  117. Rect& include (C Vec2 &v ); // extend rectangle to include vector
  118. Rect& include (C Rect &r ); // extend rectangle to include rectangle
  119. Rect& moveX ( Flt dx ); // move rectangle X's by 'dx'
  120. Rect& moveY ( Flt dy ); // move rectangle Y's by 'dy'
  121. Rect& from (C Vec2 &a, C Vec2 &b); // create from 2 points
  122. Rect& swapX ( ); // swap 'min.x' with 'max.x'
  123. Rect& swapY ( ); // swap 'min.y' with 'max.y'
  124. Rect& rotatePI_2( Int rotations ); // rotate rectangle by "rotations*PI_2" angle
  125. // draw
  126. void draw (C Color &color , Bool fill=true )C; // draw
  127. void drawBorder (C Color &color , Flt border)C; // draw border
  128. void drawBorder (C Color &color , C Vec2 &border)C; // draw border
  129. void drawShadedX (C Color &color0, C Color &color1 )C; // draw shaded horizontally
  130. void drawShadedY (C Color &color0, C Color &color1 )C; // draw shaded vertically
  131. void drawShaded (C Color &color0, C Color &color1, Flt border)C; // draw shaded inside<->outside
  132. void drawBorderShaded(C Color &color0, C Color &color1, C Rect &border)C; // draw border shaded inside<->outside
  133. Rect() {}
  134. Rect(C Vec2 &vec ) {set(vec, vec);}
  135. Rect(C Vec2 &min , C Vec2 &max ) {set(min, max);}
  136. Rect( Flt min_x, Flt min_y, Flt max_x, Flt max_y) {set(min_x, min_y, max_x, max_y);}
  137. Rect(C RectI &rect );
  138. Rect(C RectD &rect );
  139. Rect(C Box &box );
  140. Rect(C Extent &ext );
  141. Rect(C Circle &circle);
  142. Rect(C Edge2 &edge );
  143. Rect(C Tri2 &tri );
  144. Rect(C Quad2 &quad );
  145. Rect(C MeshBase &mshb );
  146. };
  147. /******************************************************************************/
  148. // rectangles with helper constructors
  149. struct Rect_RU : Rect { Rect_RU(C Vec2 &ru, C Vec2 &size) {setRU(ru, size);} Rect_RU(C Vec2 &ru, Flt w, Flt h) {setRU(ru, w, h);} Rect_RU(Flt x, Flt y, Flt w, Flt h) {setRU(x, y, w, h);} Rect_RU(C Rect &rect) {SCAST(Rect, T)=rect;} }; // create rectangle by specifying its "Right Up " position
  150. struct Rect_LU : Rect { Rect_LU(C Vec2 &lu, C Vec2 &size) {setLU(lu, size);} Rect_LU(C Vec2 &lu, Flt w, Flt h) {setLU(lu, w, h);} Rect_LU(Flt x, Flt y, Flt w, Flt h) {setLU(x, y, w, h);} Rect_LU(C Rect &rect) {SCAST(Rect, T)=rect;} }; // create rectangle by specifying its "Left Up " position
  151. struct Rect_RD : Rect { Rect_RD(C Vec2 &rd, C Vec2 &size) {setRD(rd, size);} Rect_RD(C Vec2 &rd, Flt w, Flt h) {setRD(rd, w, h);} Rect_RD(Flt x, Flt y, Flt w, Flt h) {setRD(x, y, w, h);} Rect_RD(C Rect &rect) {SCAST(Rect, T)=rect;} }; // create rectangle by specifying its "Right Down" position
  152. struct Rect_LD : Rect { Rect_LD(C Vec2 &ld, C Vec2 &size) {setLD(ld, size);} Rect_LD(C Vec2 &ld, Flt w, Flt h) {setLD(ld, w, h);} Rect_LD(Flt x, Flt y, Flt w, Flt h) {setLD(x, y, w, h);} Rect_LD(C Rect &rect) {SCAST(Rect, T)=rect;} }; // create rectangle by specifying its "Left Down" position
  153. struct Rect_R : Rect { Rect_R (C Vec2 &r , C Vec2 &size) {setR (r , size);} Rect_R (C Vec2 &r , Flt w, Flt h) {setR (r , w, h);} Rect_R (Flt x, Flt y, Flt w, Flt h) {setR (x, y, w, h);} Rect_R (C Rect &rect) {SCAST(Rect, T)=rect;} }; // create rectangle by specifying its "Right " position
  154. struct Rect_L : Rect { Rect_L (C Vec2 &l , C Vec2 &size) {setL (l , size);} Rect_L (C Vec2 &l , Flt w, Flt h) {setL (l , w, h);} Rect_L (Flt x, Flt y, Flt w, Flt h) {setL (x, y, w, h);} Rect_L (C Rect &rect) {SCAST(Rect, T)=rect;} }; // create rectangle by specifying its "Left " position
  155. struct Rect_U : Rect { Rect_U (C Vec2 &u , C Vec2 &size) {setU (u , size);} Rect_U (C Vec2 &u , Flt w, Flt h) {setU (u , w, h);} Rect_U (Flt x, Flt y, Flt w, Flt h) {setU (x, y, w, h);} Rect_U (C Rect &rect) {SCAST(Rect, T)=rect;} }; // create rectangle by specifying its "Up " position
  156. struct Rect_D : Rect { Rect_D (C Vec2 &d , C Vec2 &size) {setD (d , size);} Rect_D (C Vec2 &d , Flt w, Flt h) {setD (d , w, h);} Rect_D (Flt x, Flt y, Flt w, Flt h) {setD (x, y, w, h);} Rect_D (C Rect &rect) {SCAST(Rect, T)=rect;} }; // create rectangle by specifying its "Down " position
  157. struct Rect_C : Rect { Rect_C (C Vec2 &c , C Vec2 &size) {setC (c , size);} Rect_C (C Vec2 &c , Flt w, Flt h) {setC (c, w, h);} Rect_C (Flt x, Flt y, Flt w, Flt h) {setC (x, y, w, h);} Rect_C (C Rect &rect) {SCAST(Rect, T)=rect;} Rect_C(C Vec2 &c, Flt r) {setC(c, r);} Rect_C(Flt x, Flt y, Flt r) {setC(x, y, r);} }; // create rectangle by specifying its "Center" position
  158. /******************************************************************************/
  159. struct RectD // Rectangle Shape (double precision)
  160. {
  161. VecD2 min, max;
  162. RectD& zero( ) { min.zero(); max.zero(); return T;} // zero rectangle coordinates
  163. RectD& set (C VecD2 &min, C VecD2 &max ) {T.min=min ; T.max=max ; return T;} // set rectangle from minimum maximum coordinates
  164. RectD& set (Dbl min_x, Dbl min_y, Dbl max_x, Dbl max_y) {min.set(min_x, min_y); max.set(max_x, max_y); return T;} // set rectangle from minimum maximum coordinates
  165. RectD& setX(Dbl x ) {T.min.x=x ; T.max.x= x; return T;}
  166. RectD& setY(Dbl y ) {T.min.y=y ; T.max.y= y; return T;}
  167. RectD& setX(Dbl min, Dbl max) {T.min.x=min; T.max.x=max; return T;}
  168. RectD& setY(Dbl min, Dbl max) {T.min.y=min; T.max.y=max; return T;}
  169. RectD& operator+=(C VecD2 &v) {min+=v ; max+=v ; return T;}
  170. RectD& operator-=(C VecD2 &v) {min-=v ; max-=v ; return T;}
  171. RectD& operator+=(C VecD &v) {min+=v.xy; max+=v.xy; return T;}
  172. RectD& operator-=(C VecD &v) {min-=v.xy; max-=v.xy; return T;}
  173. RectD& operator*=( Dbl r) {min*=r ; max*=r ; return T;}
  174. RectD& operator/=( Dbl r) {min/=r ; max/=r ; return T;}
  175. RectD& operator*=(C VecD2 &v) {min*=v ; max*=v ; return T;}
  176. RectD& operator/=(C VecD2 &v) {min/=v ; max/=v ; return T;}
  177. RectD& operator|=(C VecD2 &v) {return include(v);}
  178. RectD& operator|=(C RectD &r) {return include(r);}
  179. RectD& operator&=(C RectD &r); // intersect
  180. RectD& operator&=(C RectI &r); // intersect
  181. Bool operator==(C RectD &r)C {return min==r.min && max==r.max;}
  182. Bool operator!=(C RectD &r)C {return min!=r.min || max!=r.max;}
  183. friend RectD operator+ (C RectD &rect, C VecD2 &v) {return RectD(rect)+=v;}
  184. friend RectD operator- (C RectD &rect, C VecD2 &v) {return RectD(rect)-=v;}
  185. friend RectD operator* (C RectD &rect, Dbl r) {return RectD(rect)*=r;}
  186. friend RectD operator/ (C RectD &rect, Dbl r) {return RectD(rect)/=r;}
  187. friend RectD operator* (C RectD &rect, C VecD2 &v) {return RectD(rect)*=v;}
  188. friend RectD operator/ (C RectD &rect, C VecD2 &v) {return RectD(rect)/=v;}
  189. friend RectD operator| (C RectD &rect, C VecD2 &v) {return RectD(rect)|=v;} // union
  190. friend RectD operator| (C RectD &rect, C RectD &r) {return RectD(rect)|=r;} // union
  191. friend RectD operator& (C RectD &rect, C RectD &r) {return RectD(rect)&=r;} // intersection
  192. friend RectD operator& (C RectD &rect, C RectI &r) {return RectD(rect)&=r;} // intersection
  193. // get
  194. Dbl w ( )C {return max.x - min.x ;} // get width
  195. Dbl h ( )C {return max.y - min.y ;} // get height
  196. VecD2 size ( )C {return max - min ;} // get size
  197. VecD2 ld ( )C {return min ;} // get Left Down corner
  198. VecD2 ru ( )C {return max ;} // get Right Up corner
  199. VecD2 lu ( )C {return VecD2(min.x , max.y ) ;} // get Left Up corner
  200. VecD2 rd ( )C {return VecD2(max.x , min.y ) ;} // get Right Down corner
  201. VecD2 left ( )C {return VecD2(min.x , centerY() ) ;} // get Left point
  202. VecD2 right ( )C {return VecD2(max.x , centerY() ) ;} // get Right point
  203. VecD2 down ( )C {return VecD2(centerX() , min.y ) ;} // get Down point
  204. VecD2 up ( )C {return VecD2(centerX() , max.y ) ;} // get Up point
  205. Dbl centerX ( )C {return Avg(min.x , max.x ) ;} // get center X
  206. Dbl centerY ( )C {return Avg(min.y , max.y ) ;} // get center Y
  207. VecD2 center ( )C {return VecD2(centerX() , centerY() ) ;} // get center
  208. VecD2 xs ( )C {return VecD2(min.x , max.x ) ;} // get min max X's as VecD2
  209. VecD2 ys ( )C {return VecD2(min.y , max.y ) ;} // get min max Y's as VecD2
  210. Dbl lerpX (Dbl s )C {return Lerp(min.x , max.x, s ) ;} // lerp between min.x and max.x
  211. Dbl lerpY (Dbl s )C {return Lerp(min.y , max.y, s ) ;} // lerp between min.y and max.y
  212. VecD2 lerp (Dbl x, Dbl y)C {return VecD2(lerpX( x), lerpY( y)) ;} // lerp between min and max
  213. VecD2 lerp (C VecD2 &s )C {return VecD2(lerpX(s.x), lerpY(s.y)) ;} // lerp between min and max
  214. Bool includesX( Dbl x )C {return x>=min.x && x<=max.x ;} // if rectangle includes 'x'
  215. Bool includesY( Dbl y )C {return y>=min.y && y<=max.y ;} // if rectangle includes 'y'
  216. Bool includes (C VecD2 &v )C {return includesX(v.x) && includesY(v.y);} // if rectangle includes vector
  217. Bool validX ( )C {return min.x <= max.x ;} // if has valid X's
  218. Bool validY ( )C {return min.y <= max.y ;} // if has valid Y's
  219. Bool valid ( )C {return validX() && validY() ;} // if is valid
  220. Bool vertical ( )C {return h()>w() ;} // if rectangle is vertical (height greater than width)
  221. Dbl area ( )C {return w()*h() ;} // get surface area
  222. Dbl aspect ( )C {return w()/h() ;} // get aspect ratio
  223. Str asText()C {return S+"Min: "+min+", Max: "+max;} // get text description
  224. // operations
  225. RectD& extendX ( Dbl e ); // extend rectangle X's
  226. RectD& extendY ( Dbl e ); // extend rectangle Y's
  227. RectD& extend ( Dbl e ); // extend rectangle
  228. RectD& extend (C VecD2 &v ); // extend rectangle
  229. RectD& extend ( Dbl x , Dbl y ); // extend rectangle
  230. RectD& includeX ( Dbl x ); // extend rectangle to include x
  231. RectD& includeY ( Dbl y ); // extend rectangle to include y
  232. RectD& includeX ( Dbl min, Dbl max ); // extend rectangle to include min..max range
  233. RectD& includeY ( Dbl min, Dbl max ); // extend rectangle to include min..max range
  234. RectD& include (C VecD2 &v ); // extend rectangle to include vector
  235. RectD& include (C RectD &r ); // extend rectangle to include rectangle
  236. RectD& moveX ( Dbl dx ); // move rectangle X's by 'dx'
  237. RectD& moveY ( Dbl dy ); // move rectangle Y's by 'dy'
  238. RectD& from (C VecD2 &a, C VecD2 &b); // create from 2 points
  239. RectD& swapX ( ); // swap 'min.x' with 'max.x'
  240. RectD& swapY ( ); // swap 'min.y' with 'max.y'
  241. RectD& rotatePI_2( Int rotations ); // rotate rectangle by "rotations*PI_2" angle
  242. RectD() {}
  243. RectD(C VecD2 &vec ) {set(vec, vec);}
  244. RectD(C VecD2 &min, C VecD2 &max ) {set(min, max);}
  245. RectD(Dbl min_x, Dbl min_y, Dbl max_x, Dbl max_y) {set(min_x, min_y, max_x, max_y);}
  246. };
  247. /******************************************************************************/
  248. struct RectI // Rectangle Shape (integer)
  249. {
  250. VecI2 min, max;
  251. RectI& zero( ) { min.zero(); max.zero(); return T;} // zero rectangle coordinates
  252. RectI& set (C VecI2 &min , C VecI2 &max ) {T.min=min ; T.max=max ; return T;} // set rectangle from minimum maximum coordinates
  253. RectI& set ( Int min_x, Int min_y, Int max_x, Int max_y) {min.set(min_x, min_y); max.set(max_x, max_y); return T;} // set rectangle from minimum maximum coordinates
  254. RectI& setRU(C VecI2 &ru, C VecI2 &size) {min.set(ru.x-size.x, ru.y-size.y); max.set(ru.x , ru.y ); return T;} // set rectangle by specifying its "Right Up" position
  255. RectI& setLU(C VecI2 &lu, C VecI2 &size) {min.set(lu.x , lu.y-size.y); max.set(lu.x+size.x, lu.y ); return T;} // set rectangle by specifying its "Left Up" position
  256. RectI& setRD(C VecI2 &rd, C VecI2 &size) {min.set(rd.x-size.x, rd.y ); max.set(rd.x , rd.y+size.y); return T;} // set rectangle by specifying its "Right Down" position
  257. RectI& setLD(C VecI2 &ld, C VecI2 &size) {min.set(ld.x , ld.y ); max.set(ld.x+size.x, ld.y+size.y); return T;} // set rectangle by specifying its "Left Down" position
  258. RectI& setRU(C VecI2 &ru, Int w, Int h) {min.set(ru.x-w, ru.y-h); max.set(ru.x , ru.y ); return T;} // set rectangle by specifying its "Right Up" position
  259. RectI& setLU(C VecI2 &lu, Int w, Int h) {min.set(lu.x , lu.y-h); max.set(lu.x+w, lu.y ); return T;} // set rectangle by specifying its "Left Up" position
  260. RectI& setRD(C VecI2 &rd, Int w, Int h) {min.set(rd.x-w, rd.y ); max.set(rd.x , rd.y+h); return T;} // set rectangle by specifying its "Right Down" position
  261. RectI& setLD(C VecI2 &ld, Int w, Int h) {min.set(ld.x , ld.y ); max.set(ld.x+w, ld.y+h); return T;} // set rectangle by specifying its "Left Down" position
  262. RectI& setRU(Int x, Int y, Int w, Int h) {min.set(x-w, y-h); max.set(x , y ); return T;} // set rectangle by specifying its "Right Up" position
  263. RectI& setLU(Int x, Int y, Int w, Int h) {min.set(x , y-h); max.set(x+w, y ); return T;} // set rectangle by specifying its "Left Up" position
  264. RectI& setRD(Int x, Int y, Int w, Int h) {min.set(x-w, y ); max.set(x , y+h); return T;} // set rectangle by specifying its "Right Down" position
  265. RectI& setLD(Int x, Int y, Int w, Int h) {min.set(x , y ); max.set(x+w, y+h); return T;} // set rectangle by specifying its "Left Down" position
  266. RectI& operator +=(C VecI2 &v) {min +=v; max +=v; return T;}
  267. RectI& operator -=(C VecI2 &v) {min -=v; max -=v; return T;}
  268. RectI& operator *=( Int i) {min *=i; max *=i; return T;}
  269. RectI& operator /=( Int i) {min /=i; max /=i; return T;}
  270. RectI& operator>>=( Int i) {min>>=i; max>>=i; return T;}
  271. RectI& operator<<=( Int i) {min<<=i; max<<=i; return T;}
  272. RectI& operator |=(C VecI2 &v) {return include(v);}
  273. RectI& operator |=(C RectI &r) {return include(r);}
  274. RectI& operator &=(C RectI &r);
  275. Bool operator== (C RectI &r)C {return min==r.min && max==r.max;}
  276. Bool operator!= (C RectI &r)C {return min!=r.min || max!=r.max;}
  277. friend RectI operator + (C RectI &rect, C VecI2 &v) {return RectI(rect) +=v;}
  278. friend RectI operator - (C RectI &rect, C VecI2 &v) {return RectI(rect) -=v;}
  279. friend RectI operator * (C RectI &rect, Int i) {return RectI(rect) *=i;}
  280. friend RectI operator / (C RectI &rect, Int i) {return RectI(rect) /=i;}
  281. friend Rect operator * (C RectI &rect, Flt f) {return Rect (rect) *=f;}
  282. friend Rect operator / (C RectI &rect, Flt f) {return Rect (rect) /=f;}
  283. friend RectI operator>> (C RectI &rect, Int i) {return RectI(rect)>>=i;}
  284. friend RectI operator<< (C RectI &rect, Int i) {return RectI(rect)<<=i;}
  285. friend RectI operator | (C RectI &rect, C VecI2 &v) {return RectI(rect) |=v;} // union
  286. friend RectI operator | (C RectI &rect, C RectI &r) {return RectI(rect) |=r;} // union
  287. friend RectI operator & (C RectI &rect, C RectI &r) {return RectI(rect) &=r;} // intersection
  288. // get
  289. Int w ( )C {return max.x - min.x ;} // get width
  290. Int h ( )C {return max.y - min.y ;} // get height
  291. VecI2 size ( )C {return max - min ;} // get size
  292. VecI2 ld ( )C {return min ;} // get Left Down corner
  293. VecI2 ru ( )C {return max ;} // get Right Up corner
  294. VecI2 lu ( )C {return VecI2(min.x , max.y );} // get Left Up corner
  295. VecI2 rd ( )C {return VecI2(max.x , min.y );} // get Right Down corner
  296. Int centerXI( )C {return AvgI (min.x , max.x );} // get center X (Int)
  297. Flt centerXF( )C {return AvgF (min.x , max.x );} // get center X (Flt)
  298. Int centerYI( )C {return AvgI (min.y , max.y );} // get center Y (Int)
  299. Flt centerYF( )C {return AvgF (min.y , max.y );} // get center Y (Flt)
  300. VecI2 centerI ( )C {return VecI2(centerXI(), centerYI());} // get center (VecI2)
  301. Vec2 centerF ( )C {return Vec2 (centerXF(), centerYF());} // get center (Vec2 )
  302. VecI2 xs ( )C {return VecI2(min.x , max.x );} // get min max X's as VecI2
  303. VecI2 ys ( )C {return VecI2(min.y , max.y );} // get min max Y's as VecI2
  304. Flt lerpX (Flt s )C {return Lerp (min.x , max.x, s );} // lerp between min.x and max.x
  305. Flt lerpY (Flt s )C {return Lerp (min.y , max.y, s );} // lerp between min.y and max.y
  306. Vec2 lerp (Flt x, Flt y)C {return Vec2 (lerpX( x), lerpY( y));} // lerp between min and max
  307. Vec2 lerp (C Vec2 &s )C {return Vec2 (lerpX(s.x), lerpY(s.y));} // lerp between min and max
  308. Bool validX ( )C {return min.x <= max.x ;} // if has valid X's
  309. Bool validY ( )C {return min.y <= max.y ;} // if has valid Y's
  310. Bool valid ( )C {return validX() && validY() ;} // if is valid
  311. Int area ( )C {return w() *h() ;} // get surface area
  312. Flt aspect ( )C {return Flt(w())/h() ;} // get aspect ratio
  313. Bool includesX( Int x)C {return x>=min.x && x<=max.x ;} // if rectangle includes 'x'
  314. Bool includesY( Int y)C {return y>=min.y && y<=max.y ;} // if rectangle includes 'y'
  315. Bool includes (C VecI2 &v)C {return includesX(v.x) && includesY(v.y);} // if rectangle includes vector
  316. Str asText()C {return S+"Min: "+min+", Max: "+max;} // get text description
  317. // set
  318. RectI& setX(Int x ) {T.min.x=x ; T.max.x= x; return T;}
  319. RectI& setY(Int y ) {T.min.y=y ; T.max.y= y; return T;}
  320. RectI& setX(Int min, Int max) {T.min.x=min; T.max.x=max; return T;}
  321. RectI& setY(Int min, Int max) {T.min.y=min; T.max.y=max; return T;}
  322. // operations
  323. RectI& extendX ( Int x ); // extend X's by 'x'
  324. RectI& extendY ( Int y ); // extend Y's by 'y'
  325. RectI& extend ( Int e ); // extend by 'e'
  326. RectI& extend (C VecI2 &v ); // extend by 'v'
  327. RectI& extend ( Int x , Int y ); // extend by 'x, y'
  328. RectI& includeX ( Int x ); // extend rectangle to include 'x'
  329. RectI& includeY ( Int y ); // extend rectangle to include 'y'
  330. RectI& includeX ( Int min, Int max ); // extend rectangle to include min..max range
  331. RectI& includeY ( Int min, Int max ); // extend rectangle to include min..max range
  332. RectI& include (C VecI2 &v ); // extend rectangle to include vector
  333. RectI& include (C RectI &r ); // extend rectangle to include rectangle
  334. RectI& from (C VecI2 &a, C VecI2 &b); // create from 2 points
  335. RectI& rotatePI_2( Int rotations ); // rotate rectangle by "rotations*PI_2" angle
  336. RectI() {}
  337. RectI(C VecI2 &vec ) {set(vec, vec);}
  338. RectI(C VecI2 &min , C VecI2 &max ) {set(min, max);}
  339. RectI( Int min_x, Int min_y, Int max_x, Int max_y) {set(min_x, min_y, max_x, max_y);}
  340. };
  341. /******************************************************************************/
  342. struct Rects // Rectangles, allows space partitioning divided into "cells.x * cells.y" cells (sub-rectangles)
  343. {
  344. VecI2 cells; // number of cells in each dimension
  345. Vec2 size ; // size of a single cell
  346. Rect rect ; // rectangle covering all cells
  347. // set
  348. void set(C Rect &rect, C VecI2 &cells); // set partitioning according to 'rect' space divided into "cells.x * cells.y" cells
  349. void set(C Rect &rect, Int elms ); // set partitioning according to 'rect' space divided into approximately "elms" cells, 'cells' will be calculated automatically
  350. // get
  351. VecI2 coords (C Vec2 &pos )C; // get cell coordinates of 'pos' world position , coordinates are automatically clamped to 0..cells-1 range
  352. RectI coords (C Rect &rect)C; // get cell coordinates of 'rect' world rectangle, coordinates are automatically clamped to 0..cells-1 range
  353. Rect getRect(C VecI2 &cell)C; // get world rectangle from 'cell' coordinates
  354. Int index (C VecI2 &pos )C {return pos.x + cells.x*pos.y;} // get cell index of cell position
  355. Int index (C Vec2 &pos )C {return index(coords(pos)) ;} // get cell index of world position
  356. Int num ( )C {return cells.x*cells.y ;} // get total number of cells
  357. // draw
  358. void draw(C Color &grid_color, C Color &back_color=TRANSPARENT)C;
  359. #if EE_PRIVATE
  360. void draw(C Color &grid_color, C Color &field_color, Index *rect_edge)C;
  361. #endif
  362. Rects() {}
  363. Rects(C Rect &rect, C VecI2 &cells) {set(rect, cells);}
  364. Rects(C Rect &rect, Int elms ) {set(rect, elms );}
  365. };
  366. /******************************************************************************/
  367. inline RectI Round(C Rect &r) {return RectI(Round(r.min.x), Round(r.min.y), Round(r.max.x), Round(r.max.y));}
  368. inline RectI Floor(C Rect &r) {return RectI(Floor(r.min.x), Floor(r.min.y), Floor(r.max.x), Floor(r.max.y));}
  369. #if EE_PRIVATE
  370. inline RectI RoundGPU(C Rect &r) {return RectI(RoundGPU(r.min.x), RoundGPU(r.min.y), RoundGPU(r.max.x), RoundGPU(r.max.y));}
  371. #endif
  372. // distance
  373. Flt Dist (C Vec2 &point, C Rect &rect); // distance between point and a rectangle
  374. Flt Dist (C Vec2 &point, C RectI &rect); // distance between point and a rectangle
  375. Flt Dist2(C Vec2 &point, C Rect &rect); // squared distance between point and a rectangle
  376. Flt Dist2(C Vec2 &point, C RectI &rect); // squared distance between point and a rectangle
  377. Flt Dist (C Rect &a , C Rect &b ); // distance between rectangle and a rectangle
  378. Flt Dist2PointSquare(C Vec2 &pos, C Vec2 &square_center, Flt square_radius);
  379. Flt Dist2PointSquare(C Vec2 &pos, C VecI2 &square_center, Flt square_radius);
  380. // cuts
  381. inline Bool Cuts (C Vec2 &point, C Rect &rect) {return rect.includes(point);} // if point cuts rectangle
  382. inline Bool Cuts (C VecD2 &point, C RectD &rect) {return rect.includes(point);} // if point cuts rectangle
  383. inline Bool Cuts (C VecI2 &point, C RectI &rect) {return rect.includes(point);} // if point cuts rectangle
  384. Bool Cuts (C Edge2 &edge , C Rect &rect); // if edge cuts rectangle
  385. Bool Cuts (C Rect &a , C Rect &b ); // if rectangle cuts rectangle
  386. Bool Cuts (C RectI &a , C RectI &b ); // if rectangle cuts rectangle
  387. Bool CutsEps(C Vec2 &point, C Rect &rect); // if point cuts rectangle, with EPS epsilon tolerance
  388. Bool Inside (C Rect &a, C Rect &b); // if 'a' is fully inside 'b'
  389. Bool Inside (C RectI &a, C RectI &b); // if 'a' is fully inside 'b'
  390. Bool InsideEps(C Rect &a, C Rect &b); // if 'a' is fully inside 'b', with EPS epsilon tolerance
  391. // fit
  392. Rect Fit(Flt src_aspect, C Rect &dest_rect, FIT_MODE fit=FIT_FULL); // get a rectangle that will fit in the 'dest_rect' while preserving the 'src_aspect' source aspect ratio using the 'fit' mode
  393. // sweep
  394. Bool SweepPointRect(C Vec2 &point, C Vec2 &move, C Rect &rect, Flt *hit_frac=null, Vec2 *hit_normal=null, Vec2 *hit_pos=null); // if moving point cuts through a static rectangle
  395. // pack rectangles
  396. struct RectSizeAnchor
  397. {
  398. VecI2 size , // size of the rectangle
  399. anchor; // anchor position (used when 'align_for_compression' is enabled)
  400. RectSizeAnchor() {anchor.zero();}
  401. };
  402. struct RectIndex : RectI
  403. {
  404. Int index;
  405. };
  406. Bool PackRectsKnownLimit (C MemPtr<RectSizeAnchor> &sizes, MemPtr<RectI > rects, C VecI2 &limit , Bool allow_rotate=true, Int border=0, Bool align_for_compression=false, Bool compact_arrangement=false ); // pack rectangles defined by their 'sizes' into 'rects', 'limit' =specified size which should be able to contain the rectangles, 'allow_rotate'=if allow rectangles to be rotated, 'border'=spacing between rectangles, 'align_for_compression'=if align rectangles on a 4-pixel boundary to allow for equal compression on all images (enabled 'allow_rotate' may prevent this option from best effect), 'compact_arrangement'=if try to make the arrangement of rectangles as compact as possible (this affects only arrangement and does not affect being able to fit in the limit), false on fail (if rectangles don't fit)
  407. Bool PackRectsUnknownLimit(C MemPtr<RectSizeAnchor> &sizes, MemPtr<RectI > rects, VecI2 &limit , Bool allow_rotate=true, Int border=0, Bool align_for_compression=false, Bool compact_arrangement=false, Bool only_square=false, Int max_size=65536); // pack rectangles defined by their 'sizes' into 'rects', 'limit' =calculated size which should be able to contain the rectangles, 'allow_rotate'=if allow rectangles to be rotated, 'border'=spacing between rectangles, 'align_for_compression'=if align rectangles on a 4-pixel boundary to allow for equal compression on all images (enabled 'allow_rotate' may prevent this option from best effect), 'compact_arrangement'=if try to make the arrangement of rectangles as compact as possible (this affects only arrangement and does not affect being able to fit in the limit), 'only_square'=if test only squares (otherwise rectangles are tested too), 'max_size'=max size to test, false on fail (if rectangles don't fit)
  408. Bool PackRectsMultiLimit (C MemPtr<RectSizeAnchor> &sizes, MemPtr<RectIndex> rects, MemPtr<VecI2> limits, Bool allow_rotate=true, Int border=0, Bool align_for_compression=false, Bool compact_arrangement=false, Bool only_square=false, Int max_size=65536); // pack rectangles defined by their 'sizes' into 'rects', 'limits'=calculated sizes which should be able to contain the rectangles, 'allow_rotate'=if allow rectangles to be rotated, 'border'=spacing between rectangles, 'align_for_compression'=if align rectangles on a 4-pixel boundary to allow for equal compression on all images (enabled 'allow_rotate' may prevent this option from best effect), 'compact_arrangement'=if try to make the arrangement of rectangles as compact as possible (this affects only arrangement and does not affect being able to fit in the limit), 'only_square'=if test only squares (otherwise rectangles are tested too), 'max_size'=max size to test, 'index' member of 'rects' specifies the index in 'limits' array that rectangle got placed, false on fail (if rectangles don't fit)
  409. Bool BestFit(Vec2 *point, Int points, Vec2 &axis); // find best-fit rectangle axis direction to store the points, false on fail
  410. Bool BestFit(VecD2 *point, Int points, VecD2 &axis); // find best-fit rectangle axis direction to store the points, false on fail
  411. /******************************************************************************/