Anti-Grain Geometry Tutorial
agg_span_gouraud.h
1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Permission to copy, use, modify, sell and distribute this software
6 // is granted provided this copyright notice appears in all copies.
7 // This software is provided "as is" without express or implied
8 // warranty, and with no claim as to its suitability for any purpose.
9 //
10 //----------------------------------------------------------------------------
11 // Contact: mcseem@antigrain.com
12 // mcseemagg@yahoo.com
13 // http://www.antigrain.com
14 //----------------------------------------------------------------------------
15 
16 #ifndef AGG_SPAN_GOURAUD_INCLUDED
17 #define AGG_SPAN_GOURAUD_INCLUDED
18 
19 #include "agg_basics.h"
20 #include "agg_math.h"
21 
22 namespace agg
23 {
24 
25  //============================================================span_gouraud
26  template<class ColorT> class span_gouraud
27  {
28  public:
29  typedef ColorT color_type;
30 
31  struct coord_type
32  {
33  double x;
34  double y;
35  color_type color;
36  };
37 
38  //--------------------------------------------------------------------
39  span_gouraud() :
40  m_vertex(0)
41  {
42  m_cmd[0] = path_cmd_stop;
43  }
44 
45  //--------------------------------------------------------------------
46  span_gouraud(const color_type& c1,
47  const color_type& c2,
48  const color_type& c3,
49  double x1, double y1,
50  double x2, double y2,
51  double x3, double y3,
52  double d) :
53  m_vertex(0)
54  {
55  colors(c1, c2, c3);
56  triangle(x1, y1, x2, y2, x3, y3, d);
57  }
58 
59  //--------------------------------------------------------------------
60  void colors(ColorT c1, ColorT c2, ColorT c3)
61  {
62  m_coord[0].color = c1;
63  m_coord[1].color = c2;
64  m_coord[2].color = c3;
65  }
66 
67  //--------------------------------------------------------------------
68  // Sets the triangle and dilates it if needed.
69  // The trick here is to calculate beveled joins in the vertices of the
70  // triangle and render it as a 6-vertex polygon.
71  // It's necessary to achieve numerical stability.
72  // However, the coordinates to interpolate colors are calculated
73  // as miter joins (calc_intersection).
74  void triangle(double x1, double y1,
75  double x2, double y2,
76  double x3, double y3,
77  double d)
78  {
79  m_coord[0].x = m_x[0] = x1;
80  m_coord[0].y = m_y[0] = y1;
81  m_coord[1].x = m_x[1] = x2;
82  m_coord[1].y = m_y[1] = y2;
83  m_coord[2].x = m_x[2] = x3;
84  m_coord[2].y = m_y[2] = y3;
85  m_cmd[0] = path_cmd_move_to;
86  m_cmd[1] = path_cmd_line_to;
87  m_cmd[2] = path_cmd_line_to;
88  m_cmd[3] = path_cmd_stop;
89 
90  if(d != 0.0)
91  {
92  dilate_triangle(m_coord[0].x, m_coord[0].y,
93  m_coord[1].x, m_coord[1].y,
94  m_coord[2].x, m_coord[2].y,
95  m_x, m_y, d);
96 
97  calc_intersection(m_x[4], m_y[4], m_x[5], m_y[5],
98  m_x[0], m_y[0], m_x[1], m_y[1],
99  &m_coord[0].x, &m_coord[0].y);
100 
101  calc_intersection(m_x[0], m_y[0], m_x[1], m_y[1],
102  m_x[2], m_y[2], m_x[3], m_y[3],
103  &m_coord[1].x, &m_coord[1].y);
104 
105  calc_intersection(m_x[2], m_y[2], m_x[3], m_y[3],
106  m_x[4], m_y[4], m_x[5], m_y[5],
107  &m_coord[2].x, &m_coord[2].y);
108  m_cmd[3] = path_cmd_line_to;
109  m_cmd[4] = path_cmd_line_to;
110  m_cmd[5] = path_cmd_line_to;
111  m_cmd[6] = path_cmd_stop;
112  }
113  }
114 
115  //--------------------------------------------------------------------
116  // Vertex Source Interface to feed the coordinates to the rasterizer
117  void rewind(unsigned)
118  {
119  m_vertex = 0;
120  }
121 
122  //--------------------------------------------------------------------
123  unsigned vertex(double* x, double* y)
124  {
125  *x = m_x[m_vertex];
126  *y = m_y[m_vertex];
127  return m_cmd[m_vertex++];
128  }
129 
130  protected:
131  //--------------------------------------------------------------------
132  void arrange_vertices(coord_type* coord) const
133  {
134  coord[0] = m_coord[0];
135  coord[1] = m_coord[1];
136  coord[2] = m_coord[2];
137 
138  if(m_coord[0].y > m_coord[2].y)
139  {
140  coord[0] = m_coord[2];
141  coord[2] = m_coord[0];
142  }
143 
144  coord_type tmp;
145  if(coord[0].y > coord[1].y)
146  {
147  tmp = coord[1];
148  coord[1] = coord[0];
149  coord[0] = tmp;
150  }
151 
152  if(coord[1].y > coord[2].y)
153  {
154  tmp = coord[2];
155  coord[2] = coord[1];
156  coord[1] = tmp;
157  }
158  }
159 
160  private:
161  //--------------------------------------------------------------------
162  coord_type m_coord[3];
163  double m_x[8];
164  double m_y[8];
165  unsigned m_cmd[8];
166  unsigned m_vertex;
167  };
168 
169 }
170 
171 #endif
172 
Definition: agg_arc.cpp:24