Last active
August 29, 2015 14:23
-
-
Save maxtruxa/facc3cbcb32f06d63630 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "StdAfx.h" | |
#include <cmath> | |
bresenham_line::bresenham_line() | |
: _x{}, _y{}, _error{}, _first_iteration{} { } | |
void bresenham_line::initialize(point_t const& start, point_t const& end) | |
{ | |
this->initialize(start.X, start.Y, end.X, end.Y); | |
} | |
void bresenham_line::initialize(int start_x, int start_y, int end_x, int end_y) | |
{ | |
this->_x = this->initialize_direction(start_x, end_x); | |
this->_y = this->initialize_direction(start_y, end_y); | |
if (this->_x.delta >= this->_y.delta) { | |
this->_error = this->_y.delta - (this->_x.delta >> 1); | |
} else { | |
this->_error = this->_x.delta - (this->_y.delta >> 1); | |
} | |
this->_first_iteration = true; | |
} | |
bool bresenham_line::next_point(point_t& point) | |
{ | |
int x; | |
int y; | |
bool result = this->next_point(x, y); | |
point.X = x; | |
point.Y = y; | |
return result; | |
} | |
bool bresenham_line::next_point(int& x, int& y) | |
{ | |
if (this->_first_iteration) { | |
// First iteration; return the very first point (same as start point passed to initialize). | |
x = this->_x.current; | |
y = this->_y.current; | |
this->_first_iteration = false; | |
return true; | |
} | |
bool x_is_primary = this->_x.delta >= this->_y.delta; | |
directional_context_t& direction1 = x_is_primary ? this->_x : this->_y; | |
directional_context_t& direction2 = x_is_primary ? this->_y : this->_x; | |
if (direction1.current == direction1.end) { | |
// Already at end; just return the last point again. | |
x = this->_x.current; | |
y = this->_y.current; | |
return false; | |
} | |
if ((this->_error >= 0) && (this->_error || direction1.step > 0)) { | |
this->_error -= direction1.delta; | |
direction2.current += direction2.step; | |
} | |
this->_error += direction2.delta; | |
direction1.current += direction1.step; | |
x = this->_x.current; | |
y = this->_y.current; | |
return true; | |
} | |
bresenham_line::directional_context_t bresenham_line::initialize_direction(int start, int end) | |
{ | |
int delta = end - start; | |
// step == 0 if x == 0 | |
// step == 1 if x > 0 | |
// step == -1 if x < 0 | |
int step{static_cast<int>(delta > 0) - static_cast<int>(delta < 0)}; | |
delta = std::abs(delta) << 1; | |
return directional_context_t{start, end, delta, step}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
class bresenham_line | |
{ | |
public: | |
typedef COORD point_t; | |
bresenham_line(); | |
void initialize(point_t const& start, point_t const& end); | |
void initialize(int start_x, int start_y, int end_x, int end_y); | |
bool next_point(point_t& point); | |
bool next_point(int& x, int& y); | |
private: | |
struct directional_context_t | |
{ | |
int current; | |
int end; | |
int delta; | |
int step; | |
}; | |
directional_context_t initialize_direction(int start, int end); | |
directional_context_t _x; | |
directional_context_t _y; | |
int _error; | |
bool _first_iteration; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment