00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #pragma once
00024
00025 #include "cinder/Vector.h"
00026 #include "cinder/Area.h"
00027
00028 #include <vector>
00029
00030 namespace cinder {
00031
00032 template<typename T> class MatrixAffine2;
00033
00034 template<typename T>
00035 class RectT {
00036 public:
00037 RectT() {}
00039 RectT( const std::vector<Vec2<T> > &points );
00040 RectT( T aX1, T aY1, T aX2, T aY2 ) {
00041 set( aX1, aY1, aX2, aY2 );
00042 }
00043 RectT( const Vec2<T> &v1, const Vec2<T> &v2 ) {
00044 set( v1.x, v1.y, v2.x, v2.y );
00045 }
00046 RectT( const Area &area );
00047
00048 void set( T aX1, T aY1, T aX2, T aY2 );
00049
00050 T getWidth() const { return x2 - x1; }
00051 T getHeight() const { return y2 - y1; }
00052 T getAspectRatio() const { return getWidth() / getHeight(); }
00053 T calcArea() const { return getWidth() * getHeight(); }
00054
00055 void canonicalize();
00056 RectT canonicalized() const;
00057
00058 void clipBy( const RectT &clip );
00059 RectT getClipBy( const RectT &clip ) const;
00060 Area getInteriorArea() const;
00061 void offset( const Vec2<T> &offset );
00062 RectT getOffset( const Vec2<T> &off ) const { RectT result( *this ); result.offset( off ); return result; }
00063 void inflate( const Vec2<T> &amount );
00064 RectT inflated( const Vec2<T> &amount ) const;
00066 void offsetCenterTo( const Vec2<T> ¢er ) { offset( center - getCenter() ); }
00067 void scaleCentered( const Vec2<T> &scale );
00068 void scaleCentered( T scale );
00069 RectT scaledCentered( T scale ) const;
00070 void scale( T scale );
00071 RectT scaled( T scale ) const;
00072
00074 RectT transformCopy( const class MatrixAffine2<T> &matrix ) const;
00075
00077 template<typename Y>
00078 bool contains( const Vec2<Y> &pt ) const { return ( pt.x >= x1 ) && ( pt.x <= x2 ) && ( pt.y >= y1 ) && ( pt.y <= y2 ); }
00080 bool intersects( const RectT &rect ) const;
00081
00083 T distance( const Vec2<T> &pt ) const;
00085 T distanceSquared( const Vec2<T> &pt ) const;
00086
00088 Vec2<T> closestPoint( const Vec2<T> &pt ) const;
00089
00090 T getX1() const { return x1; }
00091 T getY1() const { return y1; }
00092 T getX2() const { return x2; }
00093 T getY2() const { return y2; }
00094
00095 Vec2<T> getUpperLeft() const { return Vec2<T>( x1, y1 ); };
00096 Vec2<T> getUpperRight() const { return Vec2<T>( x2, y1 ); };
00097 Vec2<T> getLowerRight() const { return Vec2<T>( x2, y2 ); };
00098 Vec2<T> getLowerLeft() const { return Vec2<T>( x1, y2 ); };
00099 Vec2<T> getCenter() const { return Vec2<T>( ( x1 + x2 ) / 2, ( y1 + y2 ) / 2 ); }
00100 Vec2<T> getSize() const { return Vec2<T>( x2 - x1, y2 - y1 ); }
00101
00103 RectT getCenteredFit( const RectT &other, bool expand ) const;
00104
00106 void include( const Vec2<T> &point );
00108 void include( const std::vector<Vec2<T> > &points );
00110 void include( const RectT &rect );
00111
00112 const RectT<T> operator+( const Vec2<T> &o ) const { return this->getOffset( o ); }
00113 const RectT<T> operator-( const Vec2<T> &o ) const { return this->getOffset( -o ); }
00114 const RectT<T> operator*( T s ) const { return this->scaled( s ); }
00115 const RectT<T> operator/( T s ) const { return this->scaled( ((T)1) / s ); }
00116
00117 const RectT<T> operator+( const RectT<T>& rhs ) const { return RectT<T>( x1 + rhs.x1, y1 + rhs.y1, x2 + rhs.x2, y2 + rhs.y2 ); }
00118 const RectT<T> operator-( const RectT<T>& rhs ) const { return RectT<T>( x1 - rhs.x1, y1 - rhs.y1, x2 - rhs.x2, y2 - rhs.y2 ); }
00119
00120 RectT<T>& operator+=( const Vec2<T> &o ) { offset( o ); return *this; }
00121 RectT<T>& operator-=( const Vec2<T> &o ) { offset( -o ); return *this; }
00122 RectT<T>& operator*=( T s ) { scale( s ); return *this; }
00123 RectT<T>& operator/=( T s ) { scale( ((T)1) / s ); return *this; }
00124
00125 T x1, y1, x2, y2;
00126
00127 friend std::ostream& operator<<( std::ostream &o, const RectT &rect )
00128 {
00129 return o << "(" << rect.x1 << ", " << rect.y1 << ")-(" << rect.x2 << ", " << rect.y2 << ")";
00130 }
00131
00132 };
00133
00134 typedef RectT<float> Rectf;
00135 typedef RectT<double> Rectd;
00136
00137
00138
00139 class RectMapping {
00140 public:
00141 RectMapping()
00142 : mSrcRect( 0, 0, 0, 0 ), mDstRect( 0, 0, 0, 0 ) {}
00143 RectMapping( const Rectf &aSrcRect, const Rectf &aDstRect )
00144 : mSrcRect( aSrcRect ), mDstRect( aDstRect ) {}
00145 RectMapping( const Rectf &aSrcRect, const Rectf &aDstRect, bool preserveSrcAspect );
00146
00147 Vec2f map( const Vec2f &srcPoint ) const;
00148 Rectf map( const Rectf &srcRect ) const;
00149
00150 private:
00151 Rectf mSrcRect, mDstRect;
00152 };
00153
00154 extern void getClippedScaledRects( const Area &srcSurfaceBounds, const Rectf &srcRect, const Area &dstSurfaceBounds, const Area &dstArea, Rectf *resultSrcRect, Area *resultDstRect );
00155
00156 }