1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/**
* @file Tools/ImageProcessing/BresenhamLineScan.h
* 
* Utility class which performs the Bresenham algorithm for line scanning.
* Some constructors set numberOfPixels which can be used as a termination condition to 
* prevent scans outside the image boundaries.
*
* @author <a href="mailto:timlaue@tzi.de">Tim Laue</a>
* @author <a href="mailto:walter.nistico@uni-dortmund.de">Walter Nistico</a>
* @author <a href="mailto:oberlies@sim.tu-darmstadt.de">Tobias Oberlies</a> (revised constructors and commenting) 
*/

#ifndef _BresenhamLineScan_h_
#define _BresenhamLineScan_h_

//#include "Tools/CameraGeometry.h"
//#include "Tools/Math/Common.h"
#include "Tools/Math/Line.h"
#include "Tools/Math/Vector2.h"
#include "Tools/Math/MVTools.h"

#include "Representations/Infrastructure/CameraInfo.h"

class BresenhamLineScan
{
public:

  /**
   * Constructs a scanline through the two points. numberOfPixels can be used.
   * Default Contructor for use in array and so on
   * @param start The start point of the line segment.
   * @param end The end point of the line segment.
   */
  BresenhamLineScan();

  /** 
   * Constructs a scanline through the two points. numberOfPixels can be used.
   * @param start The start point of the line segment.
   * @param end The end point of the line segment.
   */
  BresenhamLineScan(const Vector2i& start, const Vector2i& end);

  /**
   * Constructs a scanline with the given direction.
   * @param direction The direction vector of the scanline.
   */
  BresenhamLineScan(const Vector2d& direction);

  /**
   * Constructs a scanline with the given direction.
   * @param direction The direction (angle) of the line, expressed in radians.
   */
  BresenhamLineScan(const double& direction);

  /**
   * Constructs a scanline with the given direction starting at start and ending at the 
   * image boundary. numberOfPixels can be used.
   * @param start The start point of the line.
   * @param direction The direction (angle) of the line, expressed in radians.
   * @param cameraInfo The cameraInfo object of the camera that captured the image.
   */
  BresenhamLineScan(const Vector2i& start, const double& direction, const naoth::CameraInfo& cameraInfo);
  
  /** 
   * Constructs a scanline with the given direction starting at start and ending at the 
   * image boundary. numberOfPixels can be used.
   * @param start The start point of the ray
   * @param direction The vector pointing in the direction of scanning. Must not be a null 
   *        vector.
   * @param cameraInfo The cameraInfo object of the camera that captured the image.
   * @author Tobias Oberlies
   */
  BresenhamLineScan(const Vector2i& start, const Vector2d& direction, const naoth::CameraInfo& cameraInfo);

  BresenhamLineScan(const Math::Line& line, const naoth::CameraInfo& cameraInfo);
  
  void setup(const Vector2i& start, const Vector2i& end);
  void setup(const double& direction);
  void setup(const Vector2d& direction);
  void setup(const Vector2i& start, const double& direction, const naoth::CameraInfo& cameraInfo);
  void setup(const Vector2i& start, const Vector2d& direction, const naoth::CameraInfo& cameraInfo);
  void setup(const Math::Line& line, const naoth::CameraInfo& cameraInfo);


  /** Resets the error counter */
  inline void init()
  {
    error = baseError;
  }

  /**
   * Increments the coordinates to the next point on the line.
   * @param pos The position of the current pixel on the line, which is incremented by the
   * Bresenham algorithm
   */
  inline void getNext(Vector2i& pos)
  {
    pos += standardOffset;
    error += delta;
    if(error > 0)
    {
      pos += correctionOffset;
      error += resetError;
    }
    pixelCount++;
  }//end getNext

  inline bool getNextWithCheck(Vector2i& pos)
  {
    if (pixelCount >= 0 && pixelCount < numberOfPixels)
    {
      getNext(pos);
      return true;
    }
    return false;
  }//end getNextWithCheck

  /**
   * Increments the coordinates to the next point on the line.
   * @param pos The position of the current pixel on the line, which is incremented by the
   * Bresenham algorithm
   */
  inline bool getLast(Vector2i& pos)
  {
    bool valid = (pixelCount > 0 && pixelCount <= numberOfPixels);
    if(error - delta > 0)
    {
      pos -= correctionOffset;
      error -= resetError;
    }
    pos -= standardOffset;
    error -= delta;
    pixelCount--;
    return valid;
  }//end getNext

  /**
   * In conjuction with certain constructors (see above), this value can be used as a 
   * termination criterion for the scan. In those cases, getNext can be called 
   * numberOfPixels times without leaving the image boundaries.
   */
  int numberOfPixels;
  int pixelCount;

private:
  /** Increase x-values, if true. */
  bool alongX;
  /** The error per step. */
  int delta;
  /** The initial error value. */
  int baseError;
  /** Resets the error to a value less than zero. */
  int resetError;
  /** The standard offset per step. */
  Vector2i standardOffset;
  /** The additional offset, if the error is above zero. */
  Vector2i correctionOffset;
  /** The current error counter. */
  int error;

  /** Computes the Bresenham parameters. */
  void setup(const Vector2i& diff);

};


#endif //_BresenhamLineScan_h_