49 #ifndef _MIRA_BRESENHAM_H_ 50 #define _MIRA_BRESENHAM_H_ 87 template<
typename Visitor>
88 void bresenham(
int x0,
int y0,
int x1,
int y1, Visitor&& visitor);
102 template<
typename Visitor>
105 bresenham(p0[0], p0[1], p1[0], p1[1], visitor);
161 template<
typename Visitor>
175 template<
typename Visitor>
213 int xInc=1,
int yInc=1);
225 int x()
const {
return mX; }
228 int y()
const {
return mY; }
231 bool isMajorX()
const {
return (mDeltaX >= mDeltaY); }
237 int pos()
const {
return mI; }
250 int xInc1,
int xInc2,
int yInc1,
int yInc2,
251 int num,
int den,
int numInc,
252 int deltaX,
int deltaY);
257 int mXInc1, mXInc2, mYInc1, mYInc2, mNum, mDen, mNumInc;
258 int mDeltaX, mDeltaY;
287 template <
int Drive,
bool DrivenByLongestAxis = (Drive < 0)>
288 class GeneralBresenhamLineIteratorBase : public GeneralBresenhamLineIteratorCommonBase
291 inline
void checkForDrivingAxis(
int index, const
int64_t& dist,
int64_t& maxd)
296 mDrivingAxis = index;
372 template <
int D,
typename T = float,
int Drive = -1,
int Res = 1000>
380 struct Axis : public GeneralBresenhamLineIteratorCommonBase::AxisBase 382 T startExact, endExact; 392 GeneralBresenhamLineIterator(Point<T, D> start = Point<T, D>(), 393 Point<T, D> end = Point<T, D>()); 401 void init(Point<T, D> start = Point<T, D>(), 402 Point<T, D> end = Point<T, D>()); 405 inline bool hasNext() const 406 { return mAxes[this->drivingAxis()].current != mAxes[this->drivingAxis()].end; } 409 const GeneralBresenhamLineIterator& operator++(); 418 Point<int, D> pos() const; 424 inline const Axis& axis(uint32 d) const { return mAxes[d]; } 428 Axis mAxes[D]; ///< the axes variables 432 // implementation section: BresenhamLineIterator class implementation 435 inline BresenhamLineIterator::BresenhamLineIterator(int x0, int y0, 439 // prepare the bresenham algo 440 mDeltaX = std::abs(x1 - x0); 441 mDeltaY = std::abs(y1 - y0); 446 if (x1 >= x0) {mXInc1 = xInc; mXInc2 = xInc; } 447 else {mXInc1 = -xInc; mXInc2 = -xInc; } 449 if (y1 >= y0) {mYInc1 = yInc; mYInc2 = yInc; } 450 else {mYInc1 = -yInc; mYInc2 = -yInc; } 452 if (mDeltaX >= mDeltaY) { 471 inline BresenhamLineIterator::BresenhamLineIterator(int mx, int my, 472 int xInc1, int xInc2, 473 int yInc1, int yInc2, 474 int num, int den, int numInc, 475 int deltaX, int deltaY) : 478 mXInc1(xInc1), mXInc2(xInc2), mYInc1(yInc1), mYInc2(yInc2), 479 mNum(num), mDen(den), mNumInc(numInc), 480 mDeltaX(deltaX), mDeltaY(deltaY) 482 // this constructor is for internal use only 487 inline const BresenhamLineIterator& BresenhamLineIterator::operator++() 506 inline const BresenhamLineIterator& BresenhamLineIterator::operator--() 525 inline bool BresenhamLineIterator::hasNext() const 535 // normal line has tangent of dY/dX -> orthogonal line has tangent of -dX/dY. 536 // So we have to switch and negate the increments and switch the deltas. The 537 // line itself still starts at (mX,mY). 538 inline BresenhamLineIterator BresenhamLineIterator::orthogonal() 540 return BresenhamLineIterator(mX, mY, mYInc1, mYInc2, -mXInc1, -mXInc2, 541 mNum, mDen, mNumInc, mDeltaY, mDeltaX); 545 // interface implementation 547 template<typename Visitor> 548 inline void bresenham(int x0, int y0, int x1, int y1, Visitor&& visitor) 550 for(BresenhamLineIterator l(x0,y0,x1,y1); l.hasNext(); ++l) 551 visitor(l.x(), l.y()); 571 template<typename Visitor> 572 inline void bresenhamRunSlice(int x0, int y0, int x1, int y1, Visitor&& visitor) 574 // make sure we always go from top to bottom 587 int adjUp, adjDown, error; 588 int wholeStep, initialLength, finalLength, runLength; 590 // are we going from right to left ? 594 // special case: horizontal line 597 visitor(x0, y0, dx+1); 599 visitor(x1, y0, dx+1); 603 // use normal bresenham for lines with major y-axis 605 for(BresenhamLineIterator l(x0,y0,x1,y1); l.hasNext(); ++l) 606 visitor(l.x(), l.y(), 1); 610 // use run-slice algorithm for lines with major x-axis: 612 // minimum number of pixels in a run in this line 615 // Error term adjust each time Y steps by 1; used to tell when one 616 // extra pixel should be drawn as part of a run, to account for 617 // fractional steps along the X axis per 1-pixel steps along Y 618 adjUp = (dx % dy) * 2; 620 // Error term adjust when the error term turns over, used to factor 621 // out the X step made at that time 624 // Initial error term; reflects an initial step of 0.5 along the Y 626 error = (dx % dy) - (dy * 2); 628 // The initial and last runs are partial, because Y advances only 0.5 629 // for these runs, rather than 1. Divide one full run, plus the 630 // initial pixel, between the initial and last runs 631 initialLength = (wholeStep / 2) + 1; 632 finalLength = initialLength; 634 // If the basic run length is even and there's no fractional 635 // advance, we have one pixel that could go to either the initial 636 // or last partial run, which we'll arbitrarily allocate to the 638 if ((adjUp == 0) && ((wholeStep & 0x01) == 0)) { 642 // If there're an odd number of pixels per run, we have 1 pixel that can't 643 // be allocated to either the initial or last partial run, so we'll add 0.5 644 // to error term so this pixel will be handled by the normal full-run loop 645 if ((wholeStep & 0x01) != 0) { 650 // Draw the first, partial run of pixels 651 visitor(x, y, initialLength); 657 for (int i = 0; i < (dy - 1); i++) { 658 runLength = wholeStep; // run is at least this long 659 // advance the error term and add an extra pixel if the error 661 if ((error += adjUp) > 0) { 667 visitor(x, y, runLength); 672 // the final run of pixels 673 visitor(x, y, finalLength); 677 // Draw the first, partial run of pixels 679 visitor(x, y, initialLength); 685 for (int i = 0; i < (dy - 1); i++) { 686 runLength = wholeStep; // run is at least this long 687 // advance the error term and add an extra pixel if the error 689 if ((error += adjUp) > 0) { 696 visitor(x, y, runLength); 700 // the final run of pixels 702 visitor(x, y, finalLength); 707 // implementation section: GeneralBresenhamLineIterator class implementation 709 template <int D, typename T, int Drive, int Res> 710 inline GeneralBresenhamLineIterator<D, T, Drive, Res>:: 711 GeneralBresenhamLineIterator(Point<T, D> start, 717 template <int D, typename T, int Drive, int Res> 718 inline void GeneralBresenhamLineIterator<D, T, Drive, Res>:: 719 init(Point<T, D> start, Point<T, D> end) 723 for (int n = 0; n < D; ++n) 725 Axis& axis = mAxes[n]; 726 axis.startExact = start(n); 727 axis.endExact = end(n); 728 axis.distance = std::abs(Res * (axis.endExact - axis.startExact)); 729 axis.current = floor(axis.startExact); 730 axis.end = floor(axis.endExact); 731 axis.step = (axis.endExact >= axis.startExact) ? 1 : -1; 733 this->checkForDrivingAxis(n, axis.distance, maxd); 736 Axis& drive = mAxes[this->drivingAxis()]; 737 drive.distance = std::ceil(std::abs(Res * (drive.endExact - drive.startExact))); 739 T driveOffset = drive.startExact - drive.current; 741 driveOffset = 1 - driveOffset; 743 for (int n = 0; n < D; ++n) 745 Axis& axis = mAxes[n]; 747 if (n == this->drivingAxis()) 753 T axisOffset = axis.startExact - axis.current; 755 axisOffset = 1 - axisOffset; 757 axis.error = floor( axis.distance * (1 - driveOffset) 758 -drive.distance * (1 - axisOffset) ); 762 template <int D, typename T, int Drive, int Res> 763 inline const GeneralBresenhamLineIterator<D, T, Drive, Res>& 764 GeneralBresenhamLineIterator<D, T, Drive, Res>::operator++() 766 for (int n = 0; n < D; ++n) 768 Axis& axis = mAxes[n]; 770 if (n == this->drivingAxis()) 771 axis.current += axis.step; 773 this->step(axis, mAxes[this->drivingAxis()]); 779 template <int D, typename T, int Drive, int Res> 781 GeneralBresenhamLineIterator<D, T, Drive, Res>::pos() const 784 for (int n = 0; n < D; ++n) 785 p(n) = mAxes[n].current; const BresenhamLineIterator & operator--()
Moves iterator backward to the previous point/pixel.
Definition: Bresenham.h:506
int end
Definition: Bresenham.h:275
BresenhamLineIterator orthogonal()
Creates a new bresenham line iterator that is orthogonal to this line and starts in the current point...
Definition: Bresenham.h:538
Guaranteeing longest axis as drive axis allows some simplification/optimization in step...
Definition: Bresenham.h:288
void bresenham(int x0, int y0, int x1, int y1, Visitor &&visitor)
Rasterizes a Bresenham line point by point starting at coordinate (x0,y0) and ending in (x1...
Definition: Bresenham.h:548
int length() const
Returns the length of the line in points/pixels.
Definition: Bresenham.h:240
General point class template.
Definition: Point.h:133
specialize cv::DataType for our ImgPixel and inherit from cv::DataType<Vec>
Definition: IOService.h:67
int mDrivingAxis
driving axis dimension index
Definition: Bresenham.h:316
Class for 2D, 3D and N-dimensional points.
int y() const
Returns current y-coordinate.
Definition: Bresenham.h:228
int drivingAxis() const
Returns dimension index of the driving axis.
Definition: Bresenham.h:342
void bresenhamRunSlice(int x0, int y0, int x1, int y1, Visitor &&visitor)
Rasterizes a Bresenham line starting at coordinate (x0,y0) and ending in (x1,y1). ...
Definition: Bresenham.h:572
int drivingAxis() const
Returns dimension index of the driving axis.
Definition: Bresenham.h:313
int step
Definition: Bresenham.h:274
Data structure containing the numtype-independent relevant variables for one axis (dimension) of the ...
Definition: Bresenham.h:271
bool isMajorX() const
Returns true if the line mainly moves along the x-axis.
Definition: Bresenham.h:231
void step(AxisBase &axis, const AxisBase &drive)
Definition: Bresenham.h:300
void step(AxisBase &axis, const AxisBase &drive)
Definition: Bresenham.h:329
int64_t error
Definition: Bresenham.h:277
BresenhamLineIterator(int x0, int y0, int x1, int y1, int xInc=1, int yInc=1)
Creates a new bresenham iterator that iterates over a line starting at coordinate (x0...
Definition: Bresenham.h:435
int current
Definition: Bresenham.h:273
Implements an iterator that is able to iterate over a Bresenham line point by point using the prefix ...
Definition: Bresenham.h:199
This more general iterator basically follows the design of BresenhamLineIterator, but works on an arb...
Definition: Bresenham.h:373
const BresenhamLineIterator & operator++()
Advances the iterator to the next point/pixel.
Definition: Bresenham.h:487
Definition: Bresenham.h:264
int64_t distance
Definition: Bresenham.h:276
bool isMajorY() const
Returns true if the line mainly moves along the y-axis.
Definition: Bresenham.h:234
void checkForDrivingAxis(int index, const int64_t &dist, int64_t &maxd)
Definition: Bresenham.h:327
bool hasNext() const
Returns true, if there are more points/pixels to go.
Definition: Bresenham.h:525
int x() const
Returns current x-coordinate.
Definition: Bresenham.h:225
int pos() const
Returns the current position on the line.
Definition: Bresenham.h:237