xref: /haiku/headers/libs/agg/agg_bezier_arc.h (revision e39da397f5ff79f2db9f9a3ddf1852b6710578af)
139241fe2SDarkWyrm //----------------------------------------------------------------------------
2*e39da397SStephan Aßmus // Anti-Grain Geometry - Version 2.4
3*e39da397SStephan Aßmus // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
439241fe2SDarkWyrm //
539241fe2SDarkWyrm // Permission to copy, use, modify, sell and distribute this software
639241fe2SDarkWyrm // is granted provided this copyright notice appears in all copies.
739241fe2SDarkWyrm // This software is provided "as is" without express or implied
839241fe2SDarkWyrm // warranty, and with no claim as to its suitability for any purpose.
939241fe2SDarkWyrm //
1039241fe2SDarkWyrm //----------------------------------------------------------------------------
1139241fe2SDarkWyrm // Contact: mcseem@antigrain.com
1239241fe2SDarkWyrm //          mcseemagg@yahoo.com
1339241fe2SDarkWyrm //          http://www.antigrain.com
1439241fe2SDarkWyrm //----------------------------------------------------------------------------
1539241fe2SDarkWyrm //
1639241fe2SDarkWyrm // Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e.,
1739241fe2SDarkWyrm // 4, 7, 10, or 13 vertices.
1839241fe2SDarkWyrm //
1939241fe2SDarkWyrm //----------------------------------------------------------------------------
2039241fe2SDarkWyrm 
2139241fe2SDarkWyrm #ifndef AGG_BEZIER_ARC_INCLUDED
2239241fe2SDarkWyrm #define AGG_BEZIER_ARC_INCLUDED
2339241fe2SDarkWyrm 
2439241fe2SDarkWyrm #include "agg_conv_transform.h"
2539241fe2SDarkWyrm 
2639241fe2SDarkWyrm namespace agg
2739241fe2SDarkWyrm {
2839241fe2SDarkWyrm 
2939241fe2SDarkWyrm     //-----------------------------------------------------------------------
3039241fe2SDarkWyrm     void arc_to_bezier(double cx, double cy, double rx, double ry,
3139241fe2SDarkWyrm                        double start_angle, double sweep_angle,
3239241fe2SDarkWyrm                        double* curve);
3339241fe2SDarkWyrm 
3439241fe2SDarkWyrm 
3539241fe2SDarkWyrm     //==============================================================bezier_arc
3639241fe2SDarkWyrm     //
3739241fe2SDarkWyrm     // See implemantaion agg_bezier_arc.cpp
3839241fe2SDarkWyrm     //
3939241fe2SDarkWyrm     class bezier_arc
4039241fe2SDarkWyrm     {
4139241fe2SDarkWyrm     public:
42abd00302SDarkWyrm         //--------------------------------------------------------------------
bezier_arc()43*e39da397SStephan Aßmus         bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {}
bezier_arc(double x,double y,double rx,double ry,double start_angle,double sweep_angle)4439241fe2SDarkWyrm         bezier_arc(double x,  double y,
4539241fe2SDarkWyrm                    double rx, double ry,
4639241fe2SDarkWyrm                    double start_angle,
4739241fe2SDarkWyrm                    double sweep_angle)
4839241fe2SDarkWyrm         {
4939241fe2SDarkWyrm             init(x, y, rx, ry, start_angle, sweep_angle);
5039241fe2SDarkWyrm         }
5139241fe2SDarkWyrm 
52abd00302SDarkWyrm         //--------------------------------------------------------------------
5339241fe2SDarkWyrm         void init(double x,  double y,
5439241fe2SDarkWyrm                   double rx, double ry,
5539241fe2SDarkWyrm                   double start_angle,
5639241fe2SDarkWyrm                   double sweep_angle);
5739241fe2SDarkWyrm 
5839241fe2SDarkWyrm         //--------------------------------------------------------------------
rewind(unsigned)5939241fe2SDarkWyrm         void rewind(unsigned)
6039241fe2SDarkWyrm         {
6139241fe2SDarkWyrm             m_vertex = 0;
6239241fe2SDarkWyrm         }
6339241fe2SDarkWyrm 
6439241fe2SDarkWyrm         //--------------------------------------------------------------------
vertex(double * x,double * y)6539241fe2SDarkWyrm         unsigned vertex(double* x, double* y)
6639241fe2SDarkWyrm         {
6739241fe2SDarkWyrm             if(m_vertex >= m_num_vertices) return path_cmd_stop;
6839241fe2SDarkWyrm             *x = m_vertices[m_vertex];
6939241fe2SDarkWyrm             *y = m_vertices[m_vertex + 1];
7039241fe2SDarkWyrm             m_vertex += 2;
71*e39da397SStephan Aßmus             return (m_vertex == 2) ? path_cmd_move_to : m_cmd;
7239241fe2SDarkWyrm         }
7339241fe2SDarkWyrm 
7439241fe2SDarkWyrm         // Supplemantary functions. num_vertices() actually returns doubled
7539241fe2SDarkWyrm         // number of vertices. That is, for 1 vertex it returns 2.
7639241fe2SDarkWyrm         //--------------------------------------------------------------------
num_vertices()7739241fe2SDarkWyrm         unsigned  num_vertices() const { return m_num_vertices; }
vertices()7839241fe2SDarkWyrm         const double* vertices() const { return m_vertices;     }
vertices()7939241fe2SDarkWyrm         double*       vertices()       { return m_vertices;     }
8039241fe2SDarkWyrm 
8139241fe2SDarkWyrm     private:
8239241fe2SDarkWyrm         unsigned m_vertex;
8339241fe2SDarkWyrm         unsigned m_num_vertices;
8439241fe2SDarkWyrm         double   m_vertices[26];
85*e39da397SStephan Aßmus         unsigned m_cmd;
8639241fe2SDarkWyrm     };
8739241fe2SDarkWyrm 
8839241fe2SDarkWyrm 
8939241fe2SDarkWyrm 
9039241fe2SDarkWyrm     //==========================================================bezier_arc_svg
9139241fe2SDarkWyrm     // Compute an SVG-style bezier arc.
9239241fe2SDarkWyrm     //
9339241fe2SDarkWyrm     // Computes an elliptical arc from (x1, y1) to (x2, y2). The size and
9439241fe2SDarkWyrm     // orientation of the ellipse are defined by two radii (rx, ry)
9539241fe2SDarkWyrm     // and an x-axis-rotation, which indicates how the ellipse as a whole
9639241fe2SDarkWyrm     // is rotated relative to the current coordinate system. The center
9739241fe2SDarkWyrm     // (cx, cy) of the ellipse is calculated automatically to satisfy the
9839241fe2SDarkWyrm     // constraints imposed by the other parameters.
9939241fe2SDarkWyrm     // large-arc-flag and sweep-flag contribute to the automatic calculations
10039241fe2SDarkWyrm     // and help determine how the arc is drawn.
10139241fe2SDarkWyrm     class bezier_arc_svg
10239241fe2SDarkWyrm     {
10339241fe2SDarkWyrm     public:
10439241fe2SDarkWyrm         //--------------------------------------------------------------------
bezier_arc_svg()10539241fe2SDarkWyrm         bezier_arc_svg() : m_arc(), m_radii_ok(false) {}
10639241fe2SDarkWyrm 
bezier_arc_svg(double x1,double y1,double rx,double ry,double angle,bool large_arc_flag,bool sweep_flag,double x2,double y2)10739241fe2SDarkWyrm         bezier_arc_svg(double x1, double y1,
10839241fe2SDarkWyrm                        double rx, double ry,
10939241fe2SDarkWyrm                        double angle,
11039241fe2SDarkWyrm                        bool large_arc_flag,
11139241fe2SDarkWyrm                        bool sweep_flag,
11239241fe2SDarkWyrm                        double x2, double y2) :
11339241fe2SDarkWyrm             m_arc(), m_radii_ok(false)
11439241fe2SDarkWyrm         {
11539241fe2SDarkWyrm             init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2);
11639241fe2SDarkWyrm         }
11739241fe2SDarkWyrm 
11839241fe2SDarkWyrm         //--------------------------------------------------------------------
11939241fe2SDarkWyrm         void init(double x1, double y1,
12039241fe2SDarkWyrm                   double rx, double ry,
12139241fe2SDarkWyrm                   double angle,
12239241fe2SDarkWyrm                   bool large_arc_flag,
12339241fe2SDarkWyrm                   bool sweep_flag,
12439241fe2SDarkWyrm                   double x2, double y2);
12539241fe2SDarkWyrm 
12639241fe2SDarkWyrm         //--------------------------------------------------------------------
radii_ok()12739241fe2SDarkWyrm         bool radii_ok() const { return m_radii_ok; }
12839241fe2SDarkWyrm 
12939241fe2SDarkWyrm         //--------------------------------------------------------------------
rewind(unsigned)13039241fe2SDarkWyrm         void rewind(unsigned)
13139241fe2SDarkWyrm         {
13239241fe2SDarkWyrm             m_arc.rewind(0);
13339241fe2SDarkWyrm         }
13439241fe2SDarkWyrm 
13539241fe2SDarkWyrm         //--------------------------------------------------------------------
vertex(double * x,double * y)13639241fe2SDarkWyrm         unsigned vertex(double* x, double* y)
13739241fe2SDarkWyrm         {
13839241fe2SDarkWyrm             return m_arc.vertex(x, y);
13939241fe2SDarkWyrm         }
14039241fe2SDarkWyrm 
14139241fe2SDarkWyrm         // Supplemantary functions. num_vertices() actually returns doubled
14239241fe2SDarkWyrm         // number of vertices. That is, for 1 vertex it returns 2.
14339241fe2SDarkWyrm         //--------------------------------------------------------------------
num_vertices()14439241fe2SDarkWyrm         unsigned  num_vertices() const { return m_arc.num_vertices(); }
vertices()14539241fe2SDarkWyrm         const double* vertices() const { return m_arc.vertices();     }
vertices()14639241fe2SDarkWyrm         double*       vertices()       { return m_arc.vertices();     }
14739241fe2SDarkWyrm 
14839241fe2SDarkWyrm     private:
14939241fe2SDarkWyrm         bezier_arc m_arc;
15039241fe2SDarkWyrm         bool       m_radii_ok;
15139241fe2SDarkWyrm     };
15239241fe2SDarkWyrm 
15339241fe2SDarkWyrm 
15439241fe2SDarkWyrm 
15539241fe2SDarkWyrm 
15639241fe2SDarkWyrm }
15739241fe2SDarkWyrm 
15839241fe2SDarkWyrm 
15939241fe2SDarkWyrm #endif
160