123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- #ifndef BOOST_GIL_EXTENSION_RASTERIZATION_LINE_HPP
- #define BOOST_GIL_EXTENSION_RASTERIZATION_LINE_HPP
- #include <boost/gil/extension/rasterization/apply_rasterizer.hpp>
- #include <boost/gil/point.hpp>
- #include <cmath>
- #include <cstddef>
- #include <iterator>
- #include <vector>
- namespace boost { namespace gil {
- struct line_rasterizer_t{};
- struct bresenham_line_rasterizer
- {
- using type = line_rasterizer_t;
- bresenham_line_rasterizer(point_t start, point_t end)
- : start_point(start), end_point(end)
- {}
- std::ptrdiff_t point_count() const noexcept
- {
- const auto abs_width = std::abs(end_point.x - start_point.x) + 1;
- const auto abs_height = std::abs(end_point.y - start_point.y) + 1;
- return abs_width > abs_height ? abs_width : abs_height;
- }
- template <typename OutputIterator>
- void operator()(OutputIterator d_first) const
- {
-
- point_t start = start_point;
- point_t end = end_point;
- if (start == end)
- {
-
-
- *d_first = start;
- return;
- }
- auto width = std::abs(end.x - start.x) + 1;
- auto height = std::abs(end.y - start.y) + 1;
- bool const needs_flip = width < height;
- if (needs_flip)
- {
-
- std::swap(width, height);
- std::swap(start.x, start.y);
- std::swap(end.x, end.y);
- }
- std::ptrdiff_t const x_increment = end.x >= start.x ? 1 : -1;
- std::ptrdiff_t const y_increment = end.y >= start.y ? 1 : -1;
- double const slope =
- height == 1 ? 0 : static_cast<double>(height) / static_cast<double>(width);
- std::ptrdiff_t y = start.y;
- double error_term = 0;
- for (std::ptrdiff_t x = start.x; x != end.x; x += x_increment)
- {
-
- *d_first++ = needs_flip ? point_t{y, x} : point_t{x, y};
- error_term += slope;
- if (error_term >= 0.5)
- {
- --error_term;
- y += y_increment;
- }
- }
- *d_first++ = needs_flip ? point_t{end.y, end.x} : end;
- }
- point_t start_point;
- point_t end_point;
- };
- namespace detail {
- template <typename View, typename Rasterizer, typename Pixel>
- struct apply_rasterizer_op<View, Rasterizer, Pixel, line_rasterizer_t>
- {
- void operator()(
- View const& view, Rasterizer const& rasterizer, Pixel const& pixel)
- {
- std::vector<point_t> trajectory(rasterizer.point_count());
- rasterizer(std::begin(trajectory));
- for (auto const& point : trajectory)
- {
- view(point) = pixel;
- }
- }
- };
- }
- }}
- #endif
|