BALL  1.4.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
contourLine.h
Go to the documentation of this file.
1 // -*- Mode: C++; tab-width: 2; -*-
2 // vi: set ts=2:
3 //
4 
5 #ifndef BALL_DATATYPE_CONTOURLINE_H
6 #define BALL_DATATYPE_CONTOURLINE_H
7 
8 #ifndef BALL_COMMON_H
9 # include <BALL/common.h>
10 #endif
11 
12 #ifndef BALL_DATATYPE_REGULARDATA2D_H
14 #endif
15 
16 #include <vector>
17 
18 namespace BALL
19 {
20  // First I define some macros needed for the marching cube-algorithm.
21  // The names come from the number associated with the different corners of the square.
22  #define INTERPOL12 { \
23  vec = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x, act_cell_y)));\
24  d1 = from[act_cell_x + act_cell_y*(number_of_cells_x+1)];\
25  d2 = from[act_cell_x + 1 + act_cell_y*(number_of_cells_x+1)];\
26  vec2 = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x + 1, act_cell_y + 1)));\
27  slope = (d2 - d1) / (vec2.x - vec.x);\
28  vec.x += (threshold - d1)/slope;\
29  data_.push_back(vec);\
30  }
31 
32  #define INTERPOL18 { \
33  vec = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x, act_cell_y)));\
34  d1 = from[act_cell_x + act_cell_y*(number_of_cells_x+1)];\
35  d2 = from[act_cell_x + (act_cell_y+1)*(number_of_cells_x+1)];\
36  vec2 = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x, act_cell_y+1)));\
37  slope = (d2 - d1) / (vec2.y - vec.y);\
38  vec.y += (threshold - d1)/slope;\
39  data_.push_back(vec);\
40  }
41 
42  #define INTERPOL24 { \
43  vec = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x+1, act_cell_y)));\
44  d1 = from[act_cell_x+1 + act_cell_y*(number_of_cells_x+1)];\
45  d2 = from[act_cell_x+1 + (act_cell_y+1)*(number_of_cells_x+1)];\
46  vec2 = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x+1, act_cell_y+1)));\
47  slope = (d2 - d1) / (vec2.y - vec.y);\
48  vec.y += (threshold - d1)/slope;\
49  data_.push_back(vec);\
50  }
51 
52  // is it vec.x += or vec.y += ...?
53  #define INTERPOL48 { \
54  vec = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x+1, act_cell_y+1)));\
55  d1 = from[act_cell_x+1 + (act_cell_y+2)*(number_of_cells_x+1)];\
56  d2 = from[act_cell_x + (act_cell_y+1)*(number_of_cells_x+1)];\
57  vec2 = from.getCoordinates(from.getClosestIndex(Vector2(act_cell_x, act_cell_y+1)));\
58  slope = (d2 - d1) / (vec2.x - vec.x);\
59  vec.x += (threshold - d1)/slope;\
60  data_.push_back(vec);\
61  }
62 
63 
67  template <typename T>
69  {
70  public:
71 
75 
79  typedef Vector2 PointType;
80 
84  typedef std::vector<PointType> VectorType;
86 
90 
92  TContourLine(T height = 0);
93 
95  TContourLine(const TContourLine& copyTContourLine);
96 
98  virtual ~TContourLine();
100 
103 
105  void interpol12();
106  void interpol18();
107  void interpol24();
108  void interpol48();
109 
113 
115  const TContourLine& operator = (const TContourLine& assigTContourLine);
116 
118  virtual void clear();
120 
124 
126  bool operator == (const TContourLine& compTContourLine) const;
127 
129 
133 
136  bool getNextPoint(PointType &p);
137 
140  void resetCounter();
141 
143 
144  // private:
147  typename VectorType::iterator it_;
149  };
150 
154 
155  template <typename T>
157  : height_(height),
158  index_(0)
159  {
160  }
161 
162  template <typename T>
164  {
165  }
166 
167  template <typename T>
169  : height_(from.height_),
170  data_(from.data_),
171  it_(from.it_),
172  index_(from.index_)
173  {
174  }
175 
176  template <typename T>
178  {
179  data_.clear();
180  it_=data_.begin();
181  index_ = 0;
182  }
183 
184  template <typename T>
186  {
187  data_ = data.data_;
188  height_ = data.height_;
189  it_ = data.it_;
190  index_ = data.index_;
191 
192  return *this;
193  }
194 
195  template <typename T>
197  {
198  return ((height_ == data.height_)
199  && (data_ == data.data_)
200  && (it_ == data.it_)
201  && (index_ == data.index_));
202  }
203 
204  template <typename T>
206  {
207  // This function uses a "marching cubes"-style algorithm to determine the contour-lines.
208  //Size number_of_cells;
209  Size number_of_cells_x;
210  Size number_of_cells_y;
211  Position act_cell_x;
212  Position act_cell_y;
213  PointType vec, vec2;
214  double d1, d2, slope;
215  double threshold = height_;
216 
217  number_of_cells_x = (Size) from.getSize().x - 1;
218  number_of_cells_y = (Size) from.getSize().y - 1;
219 
220  for (act_cell_y = 0; act_cell_y < number_of_cells_y; act_cell_y++)
221  {
222  for (act_cell_x = 0; act_cell_x < number_of_cells_x; act_cell_x++)
223  {
224  // First we have to find out the topology of the actual square.
225  int topology = 0;
226 
227  if (from[act_cell_x + act_cell_y * (number_of_cells_x+1)] > threshold)
228  {
229  topology |= 1;
230  }
231  if (from[act_cell_x + 1 + act_cell_y * (number_of_cells_x+1)] > threshold)
232  {
233  topology |= 2;
234  }
235  if (from[act_cell_x + 1 + (act_cell_y + 1)*(number_of_cells_x + 1)] > threshold)
236  {
237  topology |= 4;
238  }
239  if (from[act_cell_x + (act_cell_y + 1) * (number_of_cells_x + 1)] > threshold)
240  {
241  topology |= 8;
242  }
243  // now we can use this information to compute the contour-line.
244  switch (topology)
245  {
246  // no cut of contour-line here
247  case 0 :
248  case 15 : break;
249 
250  // Line from upper left to lower right
251  case 1 :
252  case 14 : INTERPOL18
253  INTERPOL12
254  break;
255 
256  case 4 :
257  case 11 : INTERPOL48
258  INTERPOL24
259  break;
260 
261  // Line from upper right to lower left
262  case 2 :
263  case 13 : INTERPOL12
264  INTERPOL24
265  break;
266 
267  case 8 :
268  case 7 : INTERPOL18
269  INTERPOL48
270  break;
271 
272  // Line through the middle (upwards)
273  case 9 :
274  case 6 : INTERPOL12
275  INTERPOL48
276  break;
277 
278  // Line through the middle (left to right)
279  case 3 :
280  case 12 : INTERPOL18
281  INTERPOL24
282  break;
283 
284  // Two lines from upper right to lower left
285  case 10 : INTERPOL18
286  INTERPOL12
287  INTERPOL48
288  INTERPOL24
289  break;
290 
291  // Two lines from upper left to lower right
292  case 5 : INTERPOL12
293  INTERPOL24
294  INTERPOL18
295  INTERPOL48
296  break;
297  };
298  }
299  }
300  index_ = 0;
301  it_ = data_.begin();
302  }
303 
304  template <typename T>
306  {
307  if (index_ < data_.size())
308  {
309  p = *it_;
310  index_++;
311  it_++;
312  return true;
313  }
314  else
315  {
316  return false;
317  }
318  }
319 
320  template <typename T>
322  {
323  it_ = data_.begin();
324  index_ = 0;
325  }
326 }
327 #endif