00001
00002
00003
00004
00005
00006
00007 #ifndef BALL_DATATYPE_CONTOURLINE_H
00008 #define BALL_DATATYPE_CONTOURLINE_H
00009
00010 #ifndef BALL_COMMON_H
00011 # include <BALL/common.h>
00012 #endif
00013
00014 #ifndef BALL_DATATYPE_REGULARDATA2D_H
00015 # include <BALL/DATATYPE/regularData2D.h>
00016 #endif
00017
00018 #include <vector>
00019
00020 namespace BALL
00021 {
00022
00023
00024 #define INTERPOL12 { \
00025 vec = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x, act_cell_y)));\
00026 d1 = from[act_cell_x + act_cell_y*(number_of_cells_x+1)];\
00027 d2 = from[act_cell_x + 1 + act_cell_y*(number_of_cells_x+1)];\
00028 vec2 = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x + 1, act_cell_y + 1)));\
00029 slope = (d2 - d1) / (vec2.x - vec.x);\
00030 vec.x += (threshold - d1)/slope;\
00031 data_.push_back(vec);\
00032 }
00033
00034 #define INTERPOL18 { \
00035 vec = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x, act_cell_y)));\
00036 d1 = from[act_cell_x + act_cell_y*(number_of_cells_x+1)];\
00037 d2 = from[act_cell_x + (act_cell_y+1)*(number_of_cells_x+1)];\
00038 vec2 = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x, act_cell_y+1)));\
00039 slope = (d2 - d1) / (vec2.y - vec.y);\
00040 vec.y += (threshold - d1)/slope;\
00041 data_.push_back(vec);\
00042 }
00043
00044 #define INTERPOL24 { \
00045 vec = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x+1, act_cell_y)));\
00046 d1 = from[act_cell_x+1 + act_cell_y*(number_of_cells_x+1)];\
00047 d2 = from[act_cell_x+1 + (act_cell_y+1)*(number_of_cells_x+1)];\
00048 vec2 = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x+1, act_cell_y+1)));\
00049 slope = (d2 - d1) / (vec2.y - vec.y);\
00050 vec.y += (threshold - d1)/slope;\
00051 data_.push_back(vec);\
00052 }
00053
00054
00055 #define INTERPOL48 { \
00056 vec = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x+1, act_cell_y+1)));\
00057 d1 = from[act_cell_x+1 + (act_cell_y+2)*(number_of_cells_x+1)];\
00058 d2 = from[act_cell_x + (act_cell_y+1)*(number_of_cells_x+1)];\
00059 vec2 = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x, act_cell_y+1)));\
00060 slope = (d2 - d1) / (vec2.x - vec.x);\
00061 vec.x += (threshold - d1)/slope;\
00062 data_.push_back(vec);\
00063 }
00064
00065
00069 template <typename T>
00070 class TContourLine
00071 {
00072 public:
00073
00077
00081 typedef Vector2 PointType;
00082
00086 typedef std::vector<PointType> VectorType;
00088
00092
00094 TContourLine(T height = 0);
00095
00097 TContourLine(const TContourLine& copyTContourLine);
00098
00100 virtual ~TContourLine();
00102
00104 void createContourLine(TRegularData2D<T>& from);
00105
00107 void interpol12();
00108 void interpol18();
00109 void interpol24();
00110 void interpol48();
00111
00115
00117 const TContourLine& operator = (const TContourLine& assigTContourLine);
00118
00120 virtual void clear();
00122
00126
00128 bool operator == (const TContourLine& compTContourLine) const;
00129
00131
00135
00138 bool getNextPoint(PointType &p);
00139
00142 void resetCounter();
00143
00145
00146
00147 T height_;
00148 VectorType data_;
00149 typename VectorType::iterator it_;
00150 Position index_;
00151 };
00152
00155 typedef TContourLine<float> ContourLine;
00156
00157 template <typename T>
00158 TContourLine<T>::TContourLine(T height)
00159 : height_(height),
00160 index_(0)
00161 {
00162 }
00163
00164 template <typename T>
00165 TContourLine<T>::~TContourLine()
00166 {
00167 }
00168
00169 template <typename T>
00170 TContourLine<T>::TContourLine(const TContourLine<T>& from)
00171 : height_(from.height_),
00172 data_(from.data_),
00173 it_(from.it_),
00174 index_(from.index_)
00175 {
00176 }
00177
00178 template <typename T>
00179 void TContourLine<T>::clear()
00180 {
00181 data_.clear();
00182 it_=data_.begin();
00183 index_ = 0;
00184 }
00185
00186 template <typename T>
00187 const TContourLine<T>& TContourLine<T>::operator = (const TContourLine<T>& data)
00188 {
00189 data_ = data.data_;
00190 height_ = data.height_;
00191 it_ = data.it_;
00192 index_ = data.index_;
00193
00194 return *this;
00195 }
00196
00197 template <typename T>
00198 bool TContourLine<T>:: operator == (const TContourLine<T>& data) const
00199 {
00200 return ((height_ == data.height_)
00201 && (data_ == data.data_)
00202 && (it_ == data.it_)
00203 && (index_ == data.index_));
00204 }
00205
00206 template <typename T>
00207 void TContourLine<T>::createContourLine(TRegularData2D<T>& from)
00208 {
00209
00210
00211 Size number_of_cells_x;
00212 Size number_of_cells_y;
00213 Position act_cell_x;
00214 Position act_cell_y;
00215 PointType vec, vec2;
00216 double d1, d2, slope;
00217 double threshold = height_;
00218
00219 number_of_cells_x = (Size) from.getSize().x - 1;
00220 number_of_cells_y = (Size) from.getSize().y - 1;
00221
00222 for (act_cell_y = 0; act_cell_y < number_of_cells_y; act_cell_y++)
00223 {
00224 for (act_cell_x = 0; act_cell_x < number_of_cells_x; act_cell_x++)
00225 {
00226
00227 int topology = 0;
00228
00229 if (from[act_cell_x + act_cell_y * (number_of_cells_x+1)] > threshold)
00230 {
00231 topology |= 1;
00232 }
00233 if (from[act_cell_x + 1 + act_cell_y * (number_of_cells_x+1)] > threshold)
00234 {
00235 topology |= 2;
00236 }
00237 if (from[act_cell_x + 1 + (act_cell_y + 1)*(number_of_cells_x + 1)] > threshold)
00238 {
00239 topology |= 4;
00240 }
00241 if (from[act_cell_x + (act_cell_y + 1) * (number_of_cells_x + 1)] > threshold)
00242 {
00243 topology |= 8;
00244 }
00245
00246 switch (topology)
00247 {
00248
00249 case 0 :
00250 case 15 : break;
00251
00252
00253 case 1 :
00254 case 14 : INTERPOL18
00255 INTERPOL12
00256 break;
00257
00258 case 4 :
00259 case 11 : INTERPOL48
00260 INTERPOL24
00261 break;
00262
00263
00264 case 2 :
00265 case 13 : INTERPOL12
00266 INTERPOL24
00267 break;
00268
00269 case 8 :
00270 case 7 : INTERPOL18
00271 INTERPOL48
00272 break;
00273
00274
00275 case 9 :
00276 case 6 : INTERPOL12
00277 INTERPOL48
00278 break;
00279
00280
00281 case 3 :
00282 case 12 : INTERPOL18
00283 INTERPOL24
00284 break;
00285
00286
00287 case 10 : INTERPOL18
00288 INTERPOL12
00289 INTERPOL48
00290 INTERPOL24
00291 break;
00292
00293
00294 case 5 : INTERPOL12
00295 INTERPOL24
00296 INTERPOL18
00297 INTERPOL48
00298 break;
00299 };
00300 }
00301 }
00302 index_ = 0;
00303 it_ = data_.begin();
00304 }
00305
00306 template <typename T>
00307 bool TContourLine<T>::getNextPoint(typename TContourLine<T>::PointType &p)
00308 {
00309 if (index_ < data_.size())
00310 {
00311 p = *it_;
00312 index_++;
00313 it_++;
00314 return true;
00315 }
00316 else
00317 {
00318 return false;
00319 }
00320 }
00321
00322 template <typename T>
00323 void TContourLine<T>::resetCounter()
00324 {
00325 it_ = data_.begin();
00326 index_ = 0;
00327 }
00328 }
00329 #endif