44 typedef typename Vec::coord_type coord_type;
45 typedef typename Vec::extended_type ecoord_type;
46 typedef std::numeric_limits<coord_type> coord_limits;
50 BOX2(
const Vec& aPos,
const Vec& aSize = Vec(0, 0) ) :
59 m_Pos.x = m_Pos.y = coord_limits::lowest() / 2 + coord_limits::epsilon();
60 m_Size.x = m_Size.y = coord_limits::max() - coord_limits::epsilon();
65 return Vec( m_Pos.x + ( m_Size.x / 2 ),
66 m_Pos.y + ( m_Size.y / 2 ) );
74 template <
class Container>
75 void Compute(
const Container& aPointList )
79 typename Container::const_iterator i;
81 if( !aPointList.size() )
84 vmin = vmax = aPointList[0];
86 for( i = aPointList.begin(); i != aPointList.end(); ++i )
89 vmin.x = std::min( vmin.x, p.x );
90 vmin.y = std::min( vmin.y, p.y );
91 vmax.x = std::max( vmax.x, p.x );
92 vmax.y = std::max( vmax.y, p.y );
96 SetSize( vmax - vmin );
104 void Move(
const Vec& aMoveVector )
106 m_Pos += aMoveVector;
116 m_Size.y = -m_Size.y;
122 m_Size.x = -m_Size.x;
136 Vec rel_pos = aPoint - m_Pos;
151 return ( rel_pos.x >= 0 ) && ( rel_pos.y >= 0 ) && ( rel_pos.y <= size.y) &&
152 ( rel_pos.x <= size.x);
172 const Vec& GetSize()
const {
return m_Size; }
173 coord_type GetX()
const {
return m_Pos.x; }
174 coord_type GetY()
const {
return m_Pos.y; }
176 const Vec& GetOrigin()
const {
return m_Pos; }
177 const Vec& GetPosition()
const {
return m_Pos; }
178 const Vec GetEnd()
const {
return Vec( GetRight(), GetBottom() ); }
180 coord_type GetWidth()
const {
return m_Size.x; }
181 coord_type GetHeight()
const {
return m_Size.y; }
182 coord_type GetRight()
const {
return m_Pos.x + m_Size.x; }
183 coord_type GetBottom()
const {
return m_Pos.y + m_Size.y; }
186 coord_type GetLeft()
const {
return GetX(); }
187 coord_type GetTop()
const {
return GetY(); }
188 void MoveTopTo( coord_type aTop ) { m_Pos.y = aTop; }
189 void MoveBottomTo( coord_type aBottom ) { m_Size.y = aBottom - m_Pos.y; }
190 void MoveLeftTo( coord_type aLeft ) { m_Pos.x = aLeft; }
191 void MoveRightTo( coord_type aRight ) { m_Size.x = aRight - m_Pos.x; }
193 void SetOrigin(
const Vec& pos ) { m_Pos = pos; }
194 void SetOrigin( coord_type x, coord_type y ) { m_Pos.x = x; m_Pos.y = y; }
195 void SetSize(
const Vec& size ) { m_Size =
size; }
196 void SetSize( coord_type w, coord_type h ) { m_Size.x = w; m_Size.y = h; }
197 void Offset( coord_type dx, coord_type dy ) { m_Pos.x += dx; m_Pos.y += dy; }
198 void Offset(
const Vec& offset )
200 m_Pos.x += offset.x; m_Pos.y += offset.y;
203 void SetX( coord_type val ) { m_Pos.x = val; }
204 void SetY( coord_type val ) { m_Pos.y = val; }
205 void SetWidth( coord_type val ) { m_Size.x = val; }
206 void SetHeight( coord_type val ) { m_Size.y = val; }
207 void SetEnd( coord_type x, coord_type y ) { SetEnd( Vec( x, y ) ); }
208 void SetEnd(
const Vec& pos )
210 m_Size.x = pos.x - m_Pos.x; m_Size.y = pos.y - m_Pos.y;
228 int left = std::max( me.m_Pos.x, rect.m_Pos.x );
230 int right = std::min( me.m_Pos.x + me.m_Size.x, rect.m_Pos.x + rect.m_Size.x );
232 int top = std::max( me.m_Pos.y, aRect.m_Pos.y );
234 int bottom = std::min( me.m_Pos.y + me.m_Size.y, rect.m_Pos.y + rect.m_Size.y );
237 if( left <= right && top <= bottom )
255 Vec topLeft, bottomRight;
257 topLeft.x = std::max( me.m_Pos.x, rect.m_Pos.x );
258 bottomRight.x = std::min( me.m_Pos.x + me.m_Size.x, rect.m_Pos.x + rect.m_Size.x );
259 topLeft.y = std::max( me.m_Pos.y, rect.m_Pos.y );
260 bottomRight.y = std::min( me.m_Pos.y + me.m_Size.y, rect.m_Pos.y + rect.m_Size.y );
262 if ( topLeft.x < bottomRight.x && topLeft.y < bottomRight.y )
263 return BOX2<Vec>( topLeft, bottomRight - topLeft );
265 return BOX2<Vec>( Vec( 0, 0 ), Vec( 0, 0 ) );
268 const std::string Format()
const
270 std::stringstream ss;
272 ss <<
"( box corner " << m_Pos.Format() <<
" w " << m_Size.x <<
" h " << m_Size.y <<
" )";
285 if( m_Size.x < -2 * dx )
288 m_Pos.x += m_Size.x / 2;
300 if( m_Size.x > -2 * dx )
303 m_Pos.x -= m_Size.x / 2;
316 if( m_Size.y < -2 * dy )
319 m_Pos.y += m_Size.y / 2;
331 if( m_Size.y > 2 * dy )
334 m_Pos.y -= m_Size.y / 2;
369 Vec rect_end = rect.GetEnd();
372 m_Pos.x = std::min( m_Pos.x, rect.m_Pos.x );
373 m_Pos.y = std::min( m_Pos.y, rect.m_Pos.y );
374 end.x = std::max( end.x, rect_end.x );
375 end.y = std::max( end.y, rect_end.y );
392 m_Pos.x = std::min( m_Pos.x, aPoint.x );
393 m_Pos.y = std::min( m_Pos.y, aPoint.y );
394 end.x = std::max( end.x, aPoint.x );
395 end.y = std::max( end.y, aPoint.y );
407 return (ecoord_type) GetWidth() * (ecoord_type) GetHeight();
417 return m_Size.EuclideanNorm();
420 ecoord_type SquaredDistance(
const Vec& aP )
const
422 ecoord_type x2 = m_Pos.x + m_Size.x;
423 ecoord_type y2 = m_Pos.y + m_Size.y;
424 ecoord_type xdiff = std::max( aP.x < m_Pos.x ? m_Pos.x - aP.x : m_Pos.x - x2,
426 ecoord_type ydiff = std::max( aP.y < m_Pos.y ? m_Pos.y - aP.y : m_Pos.y - y2,
428 return xdiff * xdiff + ydiff * ydiff;
431 ecoord_type Distance(
const Vec& aP )
const
433 return sqrt( SquaredDistance( aP ) );
446 if( aBox.m_Pos.x + aBox.m_Size.x < m_Pos.x )
448 ecoord_type d = aBox.m_Pos.x + aBox.m_Size.x - m_Pos.x;
451 else if( aBox.m_Pos.x > m_Pos.x + m_Size.x )
453 ecoord_type d = aBox.m_Pos.x - m_Size.x - m_Pos.x;
457 if( aBox.m_Pos.y + aBox.m_Size.y < m_Pos.y )
459 ecoord_type d = aBox.m_Pos.y + aBox.m_Size.y - m_Pos.y;
462 else if( aBox.m_Pos.y > m_Pos.y + m_Size.y )
464 ecoord_type d = aBox.m_Pos.y - m_Size.y - m_Pos.y;
479 return sqrt( SquaredDistance( aBox ) );
482 bool operator==(
const BOX2<Vec>& aOther )
const
488 return ( t1.m_Pos == t2.m_Pos && t1.m_Size == t2.m_Size );
491 bool operator!=(
const BOX2<Vec>& aOther )
const
497 return ( t1.m_Pos != t2.m_Pos || t1.m_Size != t2.m_Size );
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition box2.h:281