Go to the documentation of this file.00001 #ifndef OPENTISSUE_CORE_GEOMETRY_SCAN_CONVERSION_SCAN_CONVERSION_RIDGE_ITERATOR_H
00002 #define OPENTISSUE_CORE_GEOMETRY_SCAN_CONVERSION_SCAN_CONVERSION_RIDGE_ITERATOR_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <boost/cast.hpp>
00013
00014 #include <cassert>
00015
00016 namespace OpenTissue
00017 {
00018 namespace scan_conversion
00019 {
00020 namespace detail
00021 {
00022 template<typename vector3_type>
00023 class RigdeIterator
00024 {
00025 protected:
00026
00027
00028 bool m_valid;
00029
00030
00031 bool m_has_multiple_edges;
00032 vector3_type m_next_vertex;
00033 vector3_type m_next_normal;
00034
00035
00036 vector3_type m_start_vertex;
00037 vector3_type m_end_vertex;
00038
00039 int m_start_x;
00040 int m_start_y;
00041
00042 int m_end_x;
00043 int m_end_y;
00044
00045 int m_current_x;
00046 int m_current_y;
00047
00048 int m_dx;
00049 int m_step_x;
00050
00051 int m_dy;
00052 int m_step_y;
00053
00054 int m_denominator;
00055 int m_accumulator;
00056
00057
00058 vector3_type m_start_normal;
00059 vector3_type m_end_normal;
00060 vector3_type m_current_normal;
00061
00062 public:
00063
00064 bool valid() const { return this->m_valid; }
00065 int x() const { return this->m_current_x; }
00066 int y() const { return this->m_current_y; }
00067 vector3_type normal() const { return this->m_current_normal; }
00068
00069 public:
00070
00071 RigdeIterator()
00072 : m_valid(false)
00073 {}
00074
00075 virtual ~RigdeIterator(){}
00076
00077 public:
00078
00079 RigdeIterator(
00080 vector3_type const & v1
00081 , vector3_type const & n1
00082 , vector3_type const & v2
00083 , vector3_type const & n2
00084 )
00085 : m_has_multiple_edges(false)
00086 {
00087 this->initialize(v1,n1,v2,n2);
00088 }
00089
00090 RigdeIterator(
00091 vector3_type const & v1
00092 , vector3_type const & n1
00093 , vector3_type const & v2
00094 , vector3_type const & n2
00095 , vector3_type const & v3
00096 , vector3_type const & n3
00097 )
00098 : m_has_multiple_edges(true)
00099 , m_next_vertex(v3)
00100 , m_next_normal(n3)
00101 {
00102 this->initialize(v1,n1,v2,n2);
00103 }
00104
00105 RigdeIterator(RigdeIterator const& iter)
00106 {
00107 (*this) = iter;
00108 }
00109
00110 RigdeIterator const & operator=(RigdeIterator const & iter)
00111 {
00112 this->m_valid = iter.m_valid;
00113 this->m_has_multiple_edges = iter.m_has_multiple_edges;
00114 this->m_next_vertex = iter.m_next_vertex;
00115 this->m_next_normal = iter.m_next_normal;
00116 this->m_start_vertex = iter.m_start_vertex;
00117 this->m_end_vertex = iter.m_end_vertex;
00118 this->m_start_x = iter.m_start_x;
00119 this->m_start_y = iter.m_start_y;
00120 this->m_end_x = iter.m_end_x;
00121 this->m_end_y = iter.m_end_y;
00122 this->m_current_x = iter.m_current_x;
00123 this->m_current_y = iter.m_current_y;
00124 this->m_dx = iter.m_dx;
00125 this->m_step_x = iter.m_step_x;
00126 this->m_dy = iter.m_dy;
00127 this->m_step_y = iter.m_step_y;
00128 this->m_denominator = iter.m_denominator;
00129 this->m_accumulator = iter.m_accumulator;
00130 this->m_start_normal = iter.m_start_normal;
00131 this->m_end_normal = iter.m_end_normal;
00132 this->m_current_normal = iter.m_current_normal;
00133 return *this;
00134 }
00135
00136 public:
00137
00138 bool operator()() const { return this->m_valid; }
00139
00140 bool operator++()
00141 {
00142 this->m_valid = this->update_vertex();
00143 if (this->m_valid)
00144 {
00145 this->m_valid = this->update_normal();
00146 }
00147 return this->m_valid;
00148 }
00149
00150 protected:
00151
00152 void initialize(
00153 vector3_type const & v1
00154 , vector3_type const & n1
00155 , vector3_type const & v2
00156 , vector3_type const & n2
00157 )
00158 {
00159 this->m_valid = true;
00160
00161 vector3_type V1( round( v1 ) );
00162 vector3_type V2( round( v2 ) );
00163
00164
00165
00166
00167 if (V1(1) <= V2(1))
00168 {
00169 this->m_start_vertex = V1;
00170 this->m_current_normal = n1;
00171 this->m_start_normal = n1;
00172 this->m_end_vertex = V2;
00173 this->m_end_normal = n2;
00174 }
00175 if (V1(1) > V2(1))
00176 {
00177 this->m_start_vertex = V2;
00178 this->m_current_normal = n2;
00179 this->m_start_normal = n2;
00180 this->m_end_vertex = V1;
00181 this->m_end_normal = n1;
00182 }
00183 if (V1(1) == V2(1))
00184 {
00185
00186
00187
00188 this->m_valid = false;
00189 }
00190
00191 this->m_start_x = boost::numeric_cast<int>( this->m_start_vertex(0) );
00192 this->m_start_y = boost::numeric_cast<int>( this->m_start_vertex(1) );
00193 this->m_end_x = boost::numeric_cast<int>( this->m_end_vertex(0) );
00194 this->m_end_y = boost::numeric_cast<int>( this->m_end_vertex(1) );
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206 this->m_dx = (this->m_end_x >= this->m_start_x) ? (this->m_end_x - this->m_start_x) : (this->m_start_x - this->m_end_x);
00207 this->m_step_x = (this->m_end_x >= this->m_start_x) ? 1 :-1;
00208
00209 this->m_dy = this->m_end_y - this->m_start_y;
00210 this->m_step_y = 1;
00211
00212
00213
00214
00215
00216
00217
00218 this->m_accumulator = (0 <= this->m_step_x) ? this->m_dy : 1;
00219 this->m_denominator = this->m_dy;
00220
00221 this->m_current_x = this->m_start_x;
00222 this->m_current_y = this->m_start_y;
00223
00224 this->m_valid = (this->m_start_y == this->m_end_y) ? false : true;
00225 }
00226
00227 bool update_vertex()
00228 {
00229 if (this->m_current_y >= this->m_end_y)
00230 {
00231 this->m_valid = false;
00232 }
00233 else
00234 {
00235 this->m_accumulator += this->m_dx;
00236 while (this->m_accumulator > this->m_denominator)
00237 {
00238 this->m_current_x += this->m_step_x;
00239 this->m_accumulator -= this->m_denominator;
00240 }
00241 this->m_current_y += this->m_step_y;
00242 }
00243 if (this->m_current_y >= this->m_end_y)
00244 {
00245 if (!this->m_has_multiple_edges)
00246 this->m_valid = false;
00247 else
00248 {
00249 this->initialize(
00250 this->m_end_vertex
00251 , this->m_end_normal
00252 , this->m_next_vertex
00253 , this->m_next_normal
00254 );
00255 this->m_has_multiple_edges = false;
00256 }
00257 }
00258 return this->m_valid;
00259 }
00260
00261 bool update_normal()
00262 {
00263
00264 int numerator = this->m_current_y - this->m_start_y;
00265 int denominator = this->m_end_y - this->m_start_y;
00266 this->m_current_normal = this->m_start_normal * (denominator - numerator) + this->m_end_normal * numerator;
00267 this->m_current_normal = unit(this->m_current_normal);
00268 return this->m_valid;
00269 }
00270
00271 };
00272
00273 }
00274 }
00275 }
00276
00277 #endif