⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 agg_path_storage.h

📁 windows ce 下的画各种b样条曲线
💻 H
📖 第 1 页 / 共 4 页
字号:

        void rewind(unsigned)
        {
            m_ptr = m_data;
            m_stop = false;
        }

        unsigned vertex(double* x, double* y)
        {
            if(m_ptr < m_end)
            {
                bool first = m_ptr == m_data;
                *x = *m_ptr++;
                *y = *m_ptr++;
                return first ? path_cmd_move_to : path_cmd_line_to;
            }
            *x = *y = 0.0;
            if(m_closed && !m_stop)
            {
                m_stop = true;
                return path_cmd_end_poly | path_flags_close;
            }
            return path_cmd_stop;
        }

    private:
        const T* m_data;
        const T* m_ptr;
        const T* m_end;
        bool     m_closed;
        bool     m_stop;
    };





    //-------------------------------------------------poly_container_adaptor
    template<class Container> class poly_container_adaptor
    {
    public:
        typedef typename Container::value_type vertex_type;

        poly_container_adaptor() : 
            m_container(0), 
            m_index(0),
            m_closed(false),
            m_stop(false)
        {}

        poly_container_adaptor(const Container& data, bool closed) :
            m_container(&data), 
            m_index(0),
            m_closed(closed),
            m_stop(false)
        {}

        void init(const Container& data, bool closed)
        {
            m_container = &data;
            m_index = 0;
            m_closed = closed;
            m_stop = false;
        }

        void rewind(unsigned)
        {
            m_index = 0;
            m_stop = false;
        }

        unsigned vertex(double* x, double* y)
        {
            if(m_index < m_container->size())
            {
                bool first = m_index == 0;
                const vertex_type& v = (*m_container)[m_index++];
                *x = v.x;
                *y = v.y;
                return first ? path_cmd_move_to : path_cmd_line_to;
            }
            *x = *y = 0.0;
            if(m_closed && !m_stop)
            {
                m_stop = true;
                return path_cmd_end_poly | path_flags_close;
            }
            return path_cmd_stop;
        }

    private:
        const Container* m_container;
        unsigned m_index;
        bool     m_closed;
        bool     m_stop;
    };



    //-----------------------------------------poly_container_reverse_adaptor
    template<class Container> class poly_container_reverse_adaptor
    {
    public:
        typedef typename Container::value_type vertex_type;

        poly_container_reverse_adaptor() : 
            m_container(0), 
            m_index(-1),
            m_closed(false),
            m_stop(false)
        {}

        poly_container_reverse_adaptor(const Container& data, bool closed) :
            m_container(&data), 
            m_index(-1),
            m_closed(closed),
            m_stop(false)
        {}

        void init(const Container& data, bool closed)
        {
            m_container = &data;
            m_index = m_container->size() - 1;
            m_closed = closed;
            m_stop = false;
        }

        void rewind(unsigned)
        {
            m_index = m_container->size() - 1;
            m_stop = false;
        }

        unsigned vertex(double* x, double* y)
        {
            if(m_index >= 0)
            {
                bool first = m_index == int(m_container->size() - 1);
                const vertex_type& v = (*m_container)[m_index--];
                *x = v.x;
                *y = v.y;
                return first ? path_cmd_move_to : path_cmd_line_to;
            }
            *x = *y = 0.0;
            if(m_closed && !m_stop)
            {
                m_stop = true;
                return path_cmd_end_poly | path_flags_close;
            }
            return path_cmd_stop;
        }

    private:
        const Container* m_container;
        int  m_index;
        bool m_closed;
        bool m_stop;
    };





    //--------------------------------------------------------line_adaptor
    class line_adaptor
    {
    public:
        typedef double value_type;

        line_adaptor() : m_line(m_coord, 2, false) {}
        line_adaptor(double x1, double y1, double x2, double y2) :
            m_line(m_coord, 2, false)
        {
            m_coord[0] = x1;
            m_coord[1] = y1;
            m_coord[2] = x2;
            m_coord[3] = y2;
        }
        
        void init(double x1, double y1, double x2, double y2)
        {
            m_coord[0] = x1;
            m_coord[1] = y1;
            m_coord[2] = x2;
            m_coord[3] = y2;
            m_line.rewind(0);
        }

        void rewind(unsigned)
        {
            m_line.rewind(0);
        }

        unsigned vertex(double* x, double* y)
        {
            return m_line.vertex(x, y);
        }

    private:
        double                     m_coord[4];
        poly_plain_adaptor<double> m_line;
    };













    //---------------------------------------------------------------path_base
    // A container to store vertices with their flags. 
    // A path consists of a number of contours separated with "move_to" 
    // commands. The path storage can keep and maintain more than one
    // path. 
    // To navigate to the beginning of a particular path, use rewind(path_id);
    // Where path_id is what start_new_path() returns. So, when you call
    // start_new_path() you need to store its return value somewhere else
    // to navigate to the path afterwards.
    //
    // See also: vertex_source concept
    //------------------------------------------------------------------------
    template<class VertexContainer> class path_base
    {
    public:
        typedef VertexContainer            container_type;
        typedef path_base<VertexContainer> self_type;

        //--------------------------------------------------------------------
        path_base() : m_vertices(), m_iterator(0) {}
        void remove_all() { m_vertices.remove_all(); m_iterator = 0; }
        void free_all()   { m_vertices.free_all();   m_iterator = 0; }

        // Make path functions
        //--------------------------------------------------------------------
        unsigned start_new_path();

        void move_to(double x, double y);
        void move_rel(double dx, double dy);

        void line_to(double x, double y);
        void line_rel(double dx, double dy);

        void hline_to(double x);
        void hline_rel(double dx);

        void vline_to(double y);
        void vline_rel(double dy);

        void arc_to(double rx, double ry,
                    double angle,
                    bool large_arc_flag,
                    bool sweep_flag,
                    double x, double y);

        void arc_rel(double rx, double ry,
                     double angle,
                     bool large_arc_flag,
                     bool sweep_flag,
                     double dx, double dy);

        void curve3(double x_ctrl, double y_ctrl, 
                    double x_to,   double y_to);

        void curve3_rel(double dx_ctrl, double dy_ctrl, 
                        double dx_to,   double dy_to);

        void curve3(double x_to, double y_to);

        void curve3_rel(double dx_to, double dy_to);

        void curve4(double x_ctrl1, double y_ctrl1, 
                    double x_ctrl2, double y_ctrl2, 
                    double x_to,    double y_to);

        void curve4_rel(double dx_ctrl1, double dy_ctrl1, 
                        double dx_ctrl2, double dy_ctrl2, 
                        double dx_to,    double dy_to);

        void curve4(double x_ctrl2, double y_ctrl2, 
                    double x_to,    double y_to);

        void curve4_rel(double x_ctrl2, double y_ctrl2, 
                        double x_to,    double y_to);


        void end_poly(unsigned flags = path_flags_close);
        void close_polygon(unsigned flags = path_flags_none);

        // Accessors
        //--------------------------------------------------------------------
        const container_type& vertices() const { return m_vertices; } 
              container_type& vertices()       { return m_vertices; } 

        unsigned total_vertices() const;

        void rel_to_abs(double* x, double* y) const;

        unsigned last_vertex(double* x, double* y) const;
        unsigned prev_vertex(double* x, double* y) const;

        double last_x() const;
        double last_y() const;

        unsigned vertex(unsigned idx, double* x, double* y) const;
        unsigned command(unsigned idx) const;

        void modify_vertex(unsigned idx, double x, double y);
        void modify_vertex(unsigned idx, double x, double y, unsigned cmd);
        void modify_command(unsigned idx, unsigned cmd);

        // VertexSource interface
        //--------------------------------------------------------------------
        void     rewind(unsigned path_id);
        unsigned vertex(double* x, double* y);

        // Arrange the orientation of a polygon, all polygons in a path, 
        // or in all paths. After calling arrange_orientations() or 
        // arrange_orientations_all_paths(), all the polygons will have 
        // the same orientation, i.e. path_flags_cw or path_flags_ccw
        //--------------------------------------------------------------------
        unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation);
        unsigned arrange_orientations(unsigned path_id, path_flags_e orientation);
        void     arrange_orientations_all_paths(path_flags_e orientation);
        void     invert_polygon(unsigned start);

        // Flip all vertices horizontally or vertically, 
        // between x1 and x2, or between y1 and y2 respectively
        //--------------------------------------------------------------------
        void flip_x(double x1, double x2);
        void flip_y(double y1, double y2);

        // Concatenate path. The path is added as is.
        //--------------------------------------------------------------------
        template<class VertexSource> 
        void concat_path(VertexSource& vs, unsigned path_id = 0)
        {
            double x, y;
            unsigned cmd;
            vs.rewind(path_id);
            while(!is_stop(cmd = vs.vertex(&x, &y)))
            {
                m_vertices.add_vertex(x, y, cmd);
            }
        }

        //--------------------------------------------------------------------
        // Join path. The path is joined with the existing one, that is, 
        // it behaves as if the pen of a plotter was always down (drawing)
        template<class VertexSource> 
        void join_path(VertexSource& vs, unsigned path_id = 0)
        {
            double x, y;
            unsigned cmd;
            vs.rewind(path_id);
            cmd = vs.vertex(&x, &y);
            if(!is_stop(cmd))
            {
                if(is_vertex(cmd))
                {
                    double x0, y0;
                    unsigned cmd0 = last_vertex(&x0, &y0);
                    if(is_vertex(cmd0))
                    {
                        if(calc_distance(x, y, x0, y0) > vertex_dist_epsilon)
                        {
                            if(is_move_to(cmd)) cmd = path_cmd_line_to;
                            m_vertices.add_vertex(x, y, cmd);
                        }
                    }
                    else
                    {
                        if(is_stop(cmd0))
                        {
                            cmd = path_cmd_move_to;
                        }
                        else
                        {
                            if(is_move_to(cmd)) cmd = path_cmd_line_to;
                        }
                        m_vertices.add_vertex(x, y, cmd);
                    }
                }
                while(!is_stop(cmd = vs.vertex(&x, &y)))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -