Anti-Grain Geometry - AGG (libagg)  2.5
agg-2.5/include/agg_vertex_sequence.h
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------
00002 // Anti-Grain Geometry (AGG) - Version 2.5
00003 // A high quality rendering engine for C++
00004 // Copyright (C) 2002-2006 Maxim Shemanarev
00005 // Contact: mcseem@antigrain.com
00006 //          mcseemagg@yahoo.com
00007 //          http://antigrain.com
00008 // 
00009 // AGG is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU General Public License
00011 // as published by the Free Software Foundation; either version 2
00012 // of the License, or (at your option) any later version.
00013 // 
00014 // AGG is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 // 
00019 // You should have received a copy of the GNU General Public License
00020 // along with AGG; if not, write to the Free Software
00021 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
00022 // MA 02110-1301, USA.
00023 //----------------------------------------------------------------------------
00024 
00025 #ifndef AGG_VERTEX_SEQUENCE_INCLUDED
00026 #define AGG_VERTEX_SEQUENCE_INCLUDED
00027 
00028 #include "agg_basics.h"
00029 #include "agg_array.h"
00030 #include "agg_math.h"
00031 
00032 namespace agg
00033 {
00034 
00035     //----------------------------------------------------------vertex_sequence
00036     // Modified agg::pod_bvector. The data is interpreted as a sequence 
00037     // of vertices. It means that the type T must expose:
00038     //
00039     // bool T::operator() (const T& val)
00040     // 
00041     // that is called every time new vertex is being added. The main purpose
00042     // of this operator is the possibility to calculate some values during 
00043     // adding and to return true if the vertex fits some criteria or false if
00044     // it doesn't. In the last case the new vertex is not added. 
00045     // 
00046     // The simple example is filtering coinciding vertices with calculation 
00047     // of the distance between the current and previous ones:
00048     //
00049     //    struct vertex_dist
00050     //    {
00051     //        double   x;
00052     //        double   y;
00053     //        double   dist;
00054     //
00055     //        vertex_dist() {}
00056     //        vertex_dist(double x_, double y_) :
00057     //            x(x_),
00058     //            y(y_),
00059     //            dist(0.0)
00060     //        {
00061     //        }
00062     //
00063     //        bool operator () (const vertex_dist& val)
00064     //        {
00065     //            return (dist = calc_distance(x, y, val.x, val.y)) > EPSILON;
00066     //        }
00067     //    };
00068     //
00069     // Function close() calls this operator and removes the last vertex if 
00070     // necessary.
00071     //------------------------------------------------------------------------
00072     template<class T, unsigned S=6> 
00073     class vertex_sequence : public pod_bvector<T, S>
00074     {
00075     public:
00076         typedef pod_bvector<T, S> base_type;
00077 
00078         void add(const T& val);
00079         void modify_last(const T& val);
00080         void close(bool remove_flag);
00081     };
00082 
00083 
00084 
00085     //------------------------------------------------------------------------
00086     template<class T, unsigned S> 
00087     void vertex_sequence<T, S>::add(const T& val)
00088     {
00089         if(base_type::size() > 1)
00090         {
00091             if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) 
00092             {
00093                 base_type::remove_last();
00094             }
00095         }
00096         base_type::add(val);
00097     }
00098 
00099 
00100     //------------------------------------------------------------------------
00101     template<class T, unsigned S> 
00102     void vertex_sequence<T, S>::modify_last(const T& val)
00103     {
00104         base_type::remove_last();
00105         add(val);
00106     }
00107 
00108 
00109 
00110     //------------------------------------------------------------------------
00111     template<class T, unsigned S> 
00112     void vertex_sequence<T, S>::close(bool closed)
00113     {
00114         while(base_type::size() > 1)
00115         {
00116             if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) break;
00117             T t = (*this)[base_type::size() - 1];
00118             base_type::remove_last();
00119             modify_last(t);
00120         }
00121 
00122         if(closed)
00123         {
00124             while(base_type::size() > 1)
00125             {
00126                 if((*this)[base_type::size() - 1]((*this)[0])) break;
00127                 base_type::remove_last();
00128             }
00129         }
00130     }
00131 
00132 
00133     //-------------------------------------------------------------vertex_dist
00134     // Vertex (x, y) with the distance to the next one. The last vertex has 
00135     // distance between the last and the first points if the polygon is closed
00136     // and 0.0 if it's a polyline.
00137     struct vertex_dist
00138     {
00139         double   x;
00140         double   y;
00141         double   dist;
00142 
00143         vertex_dist() {}
00144         vertex_dist(double x_, double y_) :
00145             x(x_),
00146             y(y_),
00147             dist(0.0)
00148         {
00149         }
00150 
00151         bool operator () (const vertex_dist& val)
00152         {
00153             bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon;
00154             if(!ret) dist = 1.0 / vertex_dist_epsilon;
00155             return ret;
00156         }
00157     };
00158 
00159 
00160 
00161     //--------------------------------------------------------vertex_dist_cmd
00162     // Save as the above but with additional "command" value
00163     struct vertex_dist_cmd : public vertex_dist
00164     {
00165         unsigned cmd;
00166 
00167         vertex_dist_cmd() {}
00168         vertex_dist_cmd(double x_, double y_, unsigned cmd_) :
00169             vertex_dist(x_, y_),
00170             cmd(cmd_)
00171         {
00172         }
00173     };
00174 
00175 
00176 }
00177 
00178 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines