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