📄 agg_path_storage.h
字号:
{
return m_vertices.last_y();
}
//------------------------------------------------------------------------
template<class VC>
inline unsigned path_base<VC>::vertex(unsigned idx, double* x, double* y) const
{
return m_vertices.vertex(idx, x, y);
}
//------------------------------------------------------------------------
template<class VC>
inline unsigned path_base<VC>::command(unsigned idx) const
{
return m_vertices.command(idx);
}
//------------------------------------------------------------------------
template<class VC>
void path_base<VC>::modify_vertex(unsigned idx, double x, double y)
{
m_vertices.modify_vertex(idx, x, y);
}
//------------------------------------------------------------------------
template<class VC>
void path_base<VC>::modify_vertex(unsigned idx, double x, double y, unsigned cmd)
{
m_vertices.modify_vertex(idx, x, y, cmd);
}
//------------------------------------------------------------------------
template<class VC>
void path_base<VC>::modify_command(unsigned idx, unsigned cmd)
{
m_vertices.modify_command(idx, cmd);
}
//------------------------------------------------------------------------
template<class VC>
inline void path_base<VC>::rewind(unsigned path_id)
{
m_iterator = path_id;
}
//------------------------------------------------------------------------
template<class VC>
inline unsigned path_base<VC>::vertex(double* x, double* y)
{
if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop;
return m_vertices.vertex(m_iterator++, x, y);
}
//------------------------------------------------------------------------
template<class VC>
unsigned path_base<VC>::perceive_polygon_orientation(unsigned start,
unsigned end)
{
// Calculate signed area (double area to be exact)
//---------------------
unsigned np = end - start;
double area = 0.0;
unsigned i;
for(i = 0; i < np; i++)
{
double x1, y1, x2, y2;
m_vertices.vertex(start + i, &x1, &y1);
m_vertices.vertex(start + (i + 1) % np, &x2, &y2);
area += x1 * y2 - y1 * x2;
}
return (area < 0.0) ? path_flags_cw : path_flags_ccw;
}
//------------------------------------------------------------------------
template<class VC>
void path_base<VC>::invert_polygon(unsigned start, unsigned end)
{
unsigned i;
unsigned tmp_cmd = m_vertices.command(start);
--end; // Make "end" inclusive
// Shift all commands to one position
for(i = start; i < end; i++)
{
m_vertices.modify_command(i, m_vertices.command(i + 1));
}
// Assign starting command to the ending command
m_vertices.modify_command(end, tmp_cmd);
// Reverse the polygon
while(end > start)
{
m_vertices.swap_vertices(start++, end--);
}
}
//------------------------------------------------------------------------
template<class VC>
void path_base<VC>::invert_polygon(unsigned start)
{
// Skip all non-vertices at the beginning
while(start < m_vertices.total_vertices() &&
!is_vertex(m_vertices.command(start))) ++start;
// Skip all insignificant move_to
while(start+1 < m_vertices.total_vertices() &&
is_move_to(m_vertices.command(start)) &&
is_move_to(m_vertices.command(start+1))) ++start;
// Find the last vertex
unsigned end = start + 1;
while(end < m_vertices.total_vertices() &&
!is_next_poly(m_vertices.command(end))) ++end;
invert_polygon(start, end);
}
//------------------------------------------------------------------------
template<class VC>
unsigned path_base<VC>::arrange_polygon_orientation(unsigned start,
path_flags_e orientation)
{
if(orientation == path_flags_none) return start;
// Skip all non-vertices at the beginning
while(start < m_vertices.total_vertices() &&
!is_vertex(m_vertices.command(start))) ++start;
// Skip all insignificant move_to
while(start+1 < m_vertices.total_vertices() &&
is_move_to(m_vertices.command(start)) &&
is_move_to(m_vertices.command(start+1))) ++start;
// Find the last vertex
unsigned end = start + 1;
while(end < m_vertices.total_vertices() &&
!is_next_poly(m_vertices.command(end))) ++end;
if(end - start > 2)
{
if(perceive_polygon_orientation(start, end) != unsigned(orientation))
{
// Invert polygon, set orientation flag, and skip all end_poly
invert_polygon(start, end);
unsigned cmd;
while(end < m_vertices.total_vertices() &&
is_end_poly(cmd = m_vertices.command(end)))
{
m_vertices.modify_command(end++, set_orientation(cmd, orientation));
}
}
}
return end;
}
//------------------------------------------------------------------------
template<class VC>
unsigned path_base<VC>::arrange_orientations(unsigned start,
path_flags_e orientation)
{
if(orientation != path_flags_none)
{
while(start < m_vertices.total_vertices())
{
start = arrange_polygon_orientation(start, orientation);
if(is_stop(m_vertices.command(start)))
{
++start;
break;
}
}
}
return start;
}
//------------------------------------------------------------------------
template<class VC>
void path_base<VC>::arrange_orientations_all_paths(path_flags_e orientation)
{
if(orientation != path_flags_none)
{
unsigned start = 0;
while(start < m_vertices.total_vertices())
{
start = arrange_orientations(start, orientation);
}
}
}
//------------------------------------------------------------------------
template<class VC>
void path_base<VC>::flip_x(double x1, double x2)
{
unsigned i;
double x, y;
for(i = 0; i < m_vertices.total_vertices(); i++)
{
unsigned cmd = m_vertices.vertex(i, &x, &y);
if(is_vertex(cmd))
{
m_vertices.modify_vertex(i, x2 - x + x1, y);
}
}
}
//------------------------------------------------------------------------
template<class VC>
void path_base<VC>::flip_y(double y1, double y2)
{
unsigned i;
double x, y;
for(i = 0; i < m_vertices.total_vertices(); i++)
{
unsigned cmd = m_vertices.vertex(i, &x, &y);
if(is_vertex(cmd))
{
m_vertices.modify_vertex(i, x, y2 - y + y1);
}
}
}
//------------------------------------------------------------------------
template<class VC>
void path_base<VC>::translate(double dx, double dy, unsigned path_id)
{
unsigned num_ver = m_vertices.total_vertices();
for(; path_id < num_ver; path_id++)
{
double x, y;
unsigned cmd = m_vertices.vertex(path_id, &x, &y);
if(is_stop(cmd)) break;
if(is_vertex(cmd))
{
x += dx;
y += dy;
m_vertices.modify_vertex(path_id, x, y);
}
}
}
//------------------------------------------------------------------------
template<class VC>
void path_base<VC>::translate_all_paths(double dx, double dy)
{
unsigned idx;
unsigned num_ver = m_vertices.total_vertices();
for(idx = 0; idx < num_ver; idx++)
{
double x, y;
if(is_vertex(m_vertices.vertex(idx, &x, &y)))
{
x += dx;
y += dy;
m_vertices.modify_vertex(idx, x, y);
}
}
}
//-----------------------------------------------------vertex_stl_storage
template<class Container> class vertex_stl_storage
{
public:
typedef typename Container::value_type vertex_type;
typedef typename vertex_type::value_type value_type;
void remove_all() { m_vertices.clear(); }
void free_all() { m_vertices.clear(); }
void add_vertex(double x, double y, unsigned cmd)
{
m_vertices.push_back(vertex_type(value_type(x),
value_type(y),
int8u(cmd)));
}
void modify_vertex(unsigned idx, double x, double y)
{
vertex_type& v = m_vertices[idx];
v.x = value_type(x);
v.y = value_type(y);
}
void modify_vertex(unsigned idx, double x, double y, unsigned cmd)
{
vertex_type& v = m_vertices[idx];
v.x = value_type(x);
v.y = value_type(y);
v.cmd = int8u(cmd);
}
void modify_command(unsigned idx, unsigned cmd)
{
m_vertices[idx].cmd = int8u(cmd);
}
void swap_vertices(unsigned v1, unsigned v2)
{
vertex_type t = m_vertices[v1];
m_vertices[v1] = m_vertices[v2];
m_vertices[v2] = t;
}
unsigned last_command() const
{
return m_vertices.size() ?
m_vertices[m_vertices.size() - 1].cmd :
path_cmd_stop;
}
unsigned last_vertex(double* x, double* y) const
{
if(m_vertices.size() == 0)
{
*x = *y = 0.0;
return path_cmd_stop;
}
return vertex(m_vertices.size() - 1, x, y);
}
unsigned prev_vertex(double* x, double* y) const
{
if(m_vertices.size() < 2)
{
*x = *y = 0.0;
return path_cmd_stop;
}
return vertex(m_vertices.size() - 2, x, y);
}
double last_x() const
{
return m_vertices.size() ? m_vertices[m_vertices.size() - 1].x : 0.0;
}
double last_y() const
{
return m_vertices.size() ? m_vertices[m_vertices.size() - 1].y : 0.0;
}
unsigned total_vertices() const
{
return m_vertices.size();
}
unsigned vertex(unsigned idx, double* x, double* y) const
{
const vertex_type& v = m_vertices[idx];
*x = v.x;
*y = v.y;
return v.cmd;
}
unsigned command(unsigned idx) const
{
return m_vertices[idx].cmd;
}
private:
Container m_vertices;
};
//-----------------------------------------------------------path_storage
typedef path_base<vertex_block_storage<double> > path_storage;
// Example of declarations path_storage with pod_bvector as a container
//-----------------------------------------------------------------------
//typedef path_base<vertex_stl_storage<pod_bvector<vertex_d> > > path_storage;
}
// Example of declarations path_storage with std::vector as a container
//---------------------------------------------------------------------------
//#include <vector>
//namespace agg
//{
// typedef path_base<vertex_stl_storage<std::vector<vertex_d> > > stl_path_storage;
//}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -