35#ifndef TCOD_BRESENHAM_HPP_
36#define TCOD_BRESENHAM_HPP_
50 virtual bool putPoint(
int x,
int y) = 0;
71 static void init(
int xFrom,
int yFrom,
int xTo,
int yTo);
112 static bool step(
int *xCur,
int *yCur);
167 using Point2 = std::array<int, 2>;
168 using iterator_category = std::random_access_iterator_tag;
169 using value_type = Point2;
170 using difference_type = int;
171 using pointer = void;
172 using reference = value_type;
178 explicit BresenhamLine(Point2 begin, Point2 end) noexcept
182 index_end_{get_delta_x() + 1},
184 y_error_{-get_delta_x() / 2} {}
188 explicit BresenhamLine(Point2 begin, Point2 end,
int error) noexcept
192 index_end_{get_delta_x() + 1},
194 y_error_{error > 0 ? error % get_delta_x() - get_delta_x() : error % get_delta_x()} {}
196 inline BresenhamLine& operator++() noexcept {
200 inline BresenhamLine operator++(
int)
noexcept {
205 inline BresenhamLine& operator--() noexcept {
209 inline BresenhamLine operator--(
int)
noexcept {
222 inline value_type operator[](
int index)
noexcept {
return bresenham_get(index_ + index); }
226 inline value_type operator*() noexcept {
return (*
this)[0]; }
227 inline constexpr bool operator==(
const BresenhamLine& rhs)
const noexcept {
return index_ == rhs.index_; }
228 inline constexpr bool operator!=(
const BresenhamLine& rhs)
const noexcept {
return !(*
this == rhs); }
229 inline constexpr difference_type operator-(
const BresenhamLine& rhs)
const noexcept {
return index_ - rhs.index_; }
242 inline BresenhamLine adjust_range(
int shift_begin,
int shift_end)
const noexcept {
243 BresenhamLine new_data{*
this};
244 new_data.index_ += shift_begin;
245 new_data.index_end_ += shift_end;
246 new_data.index_end_ = std::max(new_data.index_, new_data.index_end_);
258 inline BresenhamLine without_start() const noexcept {
return adjust_range(1, 0); }
268 inline BresenhamLine without_end() const noexcept {
return adjust_range(0, -1); }
278 inline BresenhamLine without_endpoints() const noexcept {
return adjust_range(1, -1); }
282 inline BresenhamLine begin() const noexcept {
return {*
this}; }
286 inline BresenhamLine end() const noexcept {
287 return BresenhamLine{origin_, dest_, index_end_, index_end_, cursor_, y_error_};
298 inline Point2 transform(
const Point2& cursor)
const noexcept {
299 return {ax + cursor.at(0) * xx + cursor.at(1) * yx, ay + cursor.at(0) * xy + cursor.at(1) * yy};
311 inline Matrix get_matrix() const noexcept {
return get_matrix(origin_, dest_); }
312 static Matrix get_matrix(
const Point2& origin,
const Point2& dest)
noexcept {
313 const int delta_x = dest.at(0) - origin.at(0);
314 const int delta_y = dest.at(1) - origin.at(1);
323 if (delta_x < 0) matrix.xx = -1;
324 if (delta_y < 0) matrix.yy = -1;
325 if (std::abs(delta_y) > std::abs(delta_x)) {
326 std::swap(matrix.xx, matrix.yx);
327 std::swap(matrix.xy, matrix.yy);
331 explicit BresenhamLine(Point2 begin, Point2 end,
int index_begin,
int index_end, Point2 cursor,
int error) noexcept
332 : origin_{begin}, dest_{end}, index_{index_begin}, index_end_{index_end}, cursor_{cursor}, y_error_{error} {}
338 inline Point2 get_normalized_delta() const noexcept {
return get_normalized_delta(origin_, dest_); }
339 static Point2 get_normalized_delta(
const Point2& origin,
const Point2& dest)
noexcept {
340 return std::abs(dest.at(0) - origin.at(0)) > std::abs(dest.at(1) - origin.at(1))
341 ? Point2{std::abs(dest.at(0) - origin.at(0)), std::abs(dest.at(1) - origin.at(1))}
342 : Point2{std::abs(dest.at(1) - origin.at(1)), std::abs(dest.at(0) - origin.at(0))};
349 inline int get_delta_x() const noexcept {
return get_normalized_delta().at(0); }
353 inline BresenhamLine& bresenham_next() {
354 const Point2 delta = get_normalized_delta();
355 y_error_ += delta.at(1);
358 y_error_ -= delta.at(0);
366 inline BresenhamLine& bresenham_prev() {
367 const Point2 delta = get_normalized_delta();
368 y_error_ -= delta.at(1);
369 if (y_error_ <= -delta.at(0)) {
371 y_error_ += delta.at(0);
379 inline Point2 bresenham_get(
int index) {
380 while (cursor_.at(0) < index) bresenham_next();
381 while (cursor_.at(0) > index) bresenham_prev();
382 return get_matrix().transform(cursor_);
Definition bresenham.hpp:54
static void init(int xFrom, int yFrom, int xTo, int yTo)
First, you have to initialize the toolkit with your starting and ending coordinates.
static bool line(int xFrom, int yFrom, int xTo, int yTo, TCODLineListener *listener)
The function returns false if the line has been interrupted by the callback (it returned false before...
static bool step(int *xCur, int *yCur)
You can then step through each cell with this function.
Definition bresenham.hpp:48
The libtcod namespace.
Definition color.hpp:45