/* Copyright 2004, 2005 Nicholas Bishop * * This file is part of SharpConstruct. * * SharpConstruct is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * SharpConstruct is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SharpConstruct; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef MATH_H #define MATH_H #include namespace SharpConstruct { namespace Math { class PolarPoint { public: PolarPoint( float m, float a ) : _magnitude( m ), _angle( a ) {} float Magnitude() const { return _magnitude; } float Angle() const { return _angle; } void SetMagnitude( float m ) { _magnitude = m; } void SetAngle( float a ) { _angle = a; } void Set( float m, float a ) { _magnitude = m; _angle = a; } private: float _magnitude, _angle; }; template< typename Coord > class Point2D { public: Point2D() : _x( 0 ), _y( 0 ) {} Point2D( Coord x, Coord y ) : _x( x ), _y( y ) {} Coord X() const { return _x; } Coord Y() const { return _y; } template< typename T > void SetX( T x ) { _x = static_cast< Coord >( x ); } template< typename T > void SetY( T y ) { _y = static_cast< Coord >( y ); } void Set( Coord x, Coord y ) { SetX( x ); SetY( y ); } private: Coord _x, _y; }; template< typename Coord > class Size2D { public: Size2D() : _w( 0 ), _h( 0 ) {} Size2D( Coord w, Coord h ) : _w( w ), _h( h ) {} Coord W() const { return _w; } Coord H() const { return _h; } void SetW( Coord w ) { _w = w; } void SetH( Coord h ) { _h = h; } void Set( Coord w, Coord h ) { _w = w; _h = h; } private: Coord _w, _h; }; template< class Coord > class Rect2D { public: Rect2D( Coord x, Coord y, Coord w, Coord h ) : _loc( x, y ), _size( w, h ) {} virtual ~Rect2D() {} const Point2D< Coord >& Location() const { return _loc; } Coord X() const { return Location().X(); } Coord Y() const { return Location().Y(); } Coord Right() const { return X() + W() - 1; } Coord Bottom() const { return Y() + H() - 1; } Coord W() const { return _size.W(); } Coord H() const { return _size.H(); } const Size2D< Coord >& Size() const { return _size; } virtual void AnchoredSetX( Coord x ) { Coord delta = x - X(); SetX( x ); _size.SetW( W() - delta ); } virtual void AnchoredSetY( Coord y ) { Coord delta = y - Y(); SetY( y ); _size.SetH( H() - delta ); } virtual void AnchoredSetRight( Coord r ) { _size.SetW( r - X() + 1 ); } virtual void AnchoredSetBottom( Coord b ) { _size.SetH( b - Y() + 1 ); } virtual void SetX( Coord x ) { _loc.SetX( x ); } virtual void SetY( Coord y ) { _loc.SetY( y ); } virtual void SetRight( Coord r ) { SetX( X() + r - Right() ); } virtual void SetBottom( Coord b ) { SetY( Y() + b - Bottom() ); } virtual void SetW( Coord w ) { _size.SetW( w ); } virtual void SetH( Coord h ) { _size.SetH( h ); } virtual void SetSize( Coord w, Coord h ) { _size.Set( w, h ); } virtual void Set( Coord x, Coord y, Coord w, Coord h ) { SetX( x ); SetY( y ); SetSize( w, h ); } Point2D< Coord > Center() const { return Point2D< Coord >( X() + W() / 2, Y() + H() / 2 ); } virtual bool Contains( Point2D< Coord > t ) const { return t.X() >= X() && t.Y() >= Y() && t.X() <= Right() && t.Y() <= Bottom(); } private: Point2D< Coord > _loc; Size2D< Coord > _size; }; template< typename T > const Rect2D< T > BoundingRect( const Rect2D< T >& r1, const Rect2D< T >& r2 ) { if( !r1.W() || !r1.H() ) return r2; else if( !r2.W() || !r2.H() ) return r1; Rect2D< T > ret( r1 ); ret.SetX( std::min( r1.X(), r2.X() ) ); ret.AnchoredSetRight( std::max( r1.Right(), r2.Right() ) ); ret.SetY( std::min( r1.Y(), r2.Y() ) ); ret.AnchoredSetBottom( std::max( r1.Bottom(), r2.Bottom() ) ); return ret; } } } #endif // MATH_H