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/Rect.h"
00027 #include "cinder/Path2d.h"
00028 #include "cinder/MatrixAffine2.h"
00029
00030 #include <vector>
00031
00032 namespace cinder {
00033
00034 class Shape2d {
00035 public:
00036 void moveTo( const Vec2f &p );
00037 void moveTo( float x, float y ) { moveTo( Vec2f( x, y ) ); }
00038 void lineTo( const Vec2f &p );
00039 void lineTo( float x, float y ) { lineTo( Vec2f( x, y ) ); }
00040 void quadTo( const Vec2f &p1, const Vec2f &p2 );
00041 void quadTo( float x1, float y1, float x2, float y2 ) { quadTo( Vec2f( x1, y1 ), Vec2f( x2, y2 ) ); }
00042 void curveTo( const Vec2f &p1, const Vec2f &p2, const Vec2f &p3 );
00043 void curveTo( float x1, float y1, float x2, float y2, float x3, float y3 ) { curveTo( Vec2f( x1, y1 ), Vec2f( x2, y2 ), Vec2f( x3, y3 ) ); }
00044 void arc( const Vec2f ¢er, float radius, float startRadians, float endRadians, bool forward = true );
00045 void arc( float centerX, float centerY, float radius, float startRadians, float endRadians, bool forward = true ) { arc( Vec2f( centerX, centerY ), radius, startRadians, endRadians, forward ); }
00046 void arcTo( const Vec2f &p, const Vec2f &t, float radius );
00047 void arcTo( float x, float y, float tanX, float tanY, float radius) { arcTo( Vec2f( x, y ), Vec2f( tanX, tanY ), radius ); }
00048 void close();
00049
00050 bool empty() const { return mContours.empty(); }
00051 void clear() { mContours.clear(); }
00052 size_t getNumContours() const { return mContours.size(); }
00053
00054 const Path2d& getContour( size_t i ) const { return mContours[i]; }
00055 Path2d& getContour( size_t i ) { return mContours[i]; }
00056 const std::vector<Path2d>& getContours() const { return mContours; }
00057 std::vector<Path2d>& getContours() { return mContours; }
00058
00059 const Vec2f& getCurrentPoint() const { return mContours.back().getCurrentPoint(); }
00060
00062 void append( const Shape2d &shape );
00063 void appendContour( const Path2d &contour ) { mContours.push_back( contour ); }
00064 void removeContour( size_t i ) { mContours.erase( mContours.begin() + i ); }
00065
00067 void scale( const Vec2f &amount, Vec2f scaleCenter = Vec2f::zero() );
00068
00070 void transform( const MatrixAffine2f &matrix );
00072 Shape2d transformCopy( const MatrixAffine2f &matrix ) const;
00073
00075 Rectf calcBoundingBox() const;
00077 Rectf calcPreciseBoundingBox() const;
00078
00080 bool contains( const Vec2f &pt ) const;
00081
00083
00087 template<typename IT>
00088 void iterate( IT &it )
00089 {
00090 bool stop = false;
00091 for( std::vector<Path2d>::const_iterator contourIt = mContours.begin(); contourIt != mContours.end(); ++contourIt ) {
00092 size_t pt = 0;
00093 it( Path2d::MOVETO, &contourIt->mPoints[0], 0 );
00094 pt++;
00095 for( std::vector<Path2d::SegmentType>::const_iterator segIt = contourIt->mSegments.begin(); segIt != contourIt->mSegments.end(); ++segIt ) {
00096 if( *segIt == Path2d::CLOSE )
00097 it( *segIt, &contourIt->mPoints[0], &contourIt->mPoints[pt-1] );
00098 else if( ! it( *segIt, &contourIt->mPoints[pt], ( pt > 0 ) ? &contourIt->mPoints[pt-1] : 0 ) ) {
00099 stop = true;
00100 break;
00101 }
00102 pt += Path2d::sSegmentTypePointCounts[*segIt];
00103 }
00104 if( stop ) break;
00105
00106
00107
00108
00109 }
00110 }
00111
00112 private:
00113 std::vector<Path2d> mContours;
00114 };
00115
00116 }