agg_vertex_sequence.h 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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. // vertex_sequence container and vertex_dist struct
  17. //
  18. //----------------------------------------------------------------------------
  19. #ifndef AGG_VERTEX_SEQUENCE_INCLUDED
  20. #define AGG_VERTEX_SEQUENCE_INCLUDED
  21. #include "agg_basics.h"
  22. #include "agg_array.h"
  23. #include "agg_math.h"
  24. namespace agg
  25. {
  26. //----------------------------------------------------------vertex_sequence
  27. // Modified agg::pod_bvector. The data is interpreted as a sequence
  28. // of vertices. It means that the type T must expose:
  29. //
  30. // bool T::operator() (const T& val)
  31. //
  32. // that is called every time new vertex is being added. The main purpose
  33. // of this operator is the possibility to calculate some values during
  34. // adding and to return true if the vertex fits some criteria or false if
  35. // it doesn't. In the last case the new vertex is not added.
  36. //
  37. // The simple example is filtering coinciding vertices with calculation
  38. // of the distance between the current and previous ones:
  39. //
  40. // struct vertex_dist
  41. // {
  42. // double x;
  43. // double y;
  44. // double dist;
  45. //
  46. // vertex_dist() {}
  47. // vertex_dist(double x_, double y_) :
  48. // x(x_),
  49. // y(y_),
  50. // dist(0.0)
  51. // {
  52. // }
  53. //
  54. // bool operator () (const vertex_dist& val)
  55. // {
  56. // return (dist = calc_distance(x, y, val.x, val.y)) > EPSILON;
  57. // }
  58. // };
  59. //
  60. // Function close() calls this operator and removes the last vertex if
  61. // necessary.
  62. //------------------------------------------------------------------------
  63. template<class T, unsigned S=6>
  64. class vertex_sequence : public pod_bvector<T, S>
  65. {
  66. public:
  67. typedef pod_bvector<T, S> base_type;
  68. void add(const T& val);
  69. void modify_last(const T& val);
  70. void close(bool remove_flag);
  71. };
  72. //------------------------------------------------------------------------
  73. template<class T, unsigned S>
  74. void vertex_sequence<T, S>::add(const T& val)
  75. {
  76. if(base_type::size() > 1)
  77. {
  78. if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1]))
  79. {
  80. base_type::remove_last();
  81. }
  82. }
  83. base_type::add(val);
  84. }
  85. //------------------------------------------------------------------------
  86. template<class T, unsigned S>
  87. void vertex_sequence<T, S>::modify_last(const T& val)
  88. {
  89. base_type::remove_last();
  90. add(val);
  91. }
  92. //------------------------------------------------------------------------
  93. template<class T, unsigned S>
  94. void vertex_sequence<T, S>::close(bool closed)
  95. {
  96. while(base_type::size() > 1)
  97. {
  98. if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) break;
  99. T t = (*this)[base_type::size() - 1];
  100. base_type::remove_last();
  101. modify_last(t);
  102. }
  103. if(closed)
  104. {
  105. while(base_type::size() > 1)
  106. {
  107. if((*this)[base_type::size() - 1]((*this)[0])) break;
  108. base_type::remove_last();
  109. }
  110. }
  111. }
  112. //-------------------------------------------------------------vertex_dist
  113. // Vertex (x, y) with the distance to the next one. The last vertex has
  114. // distance between the last and the first points if the polygon is closed
  115. // and 0.0 if it's a polyline.
  116. struct vertex_dist
  117. {
  118. double x;
  119. double y;
  120. double dist;
  121. vertex_dist() {}
  122. vertex_dist(double x_, double y_) :
  123. x(x_),
  124. y(y_),
  125. dist(0.0)
  126. {
  127. }
  128. bool operator () (const vertex_dist& val)
  129. {
  130. bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon;
  131. if(!ret) dist = 1.0 / vertex_dist_epsilon;
  132. return ret;
  133. }
  134. };
  135. //--------------------------------------------------------vertex_dist_cmd
  136. // Save as the above but with additional "command" value
  137. struct vertex_dist_cmd : public vertex_dist
  138. {
  139. unsigned cmd;
  140. vertex_dist_cmd() {}
  141. vertex_dist_cmd(double x_, double y_, unsigned cmd_) :
  142. vertex_dist(x_, y_),
  143. cmd(cmd_)
  144. {
  145. }
  146. };
  147. }
  148. #endif