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
|
//
// Copyright 2020 Olzhas Zhumabek <anonymous.from.applecity@gmail.com>
//
// Use, modification and distribution are subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/gil/point.hpp>
#include <boost/gil/extension/rasterization/circle.hpp>
#include <boost/core/lightweight_test.hpp>
#include <cmath>
#include <cstdint>
#include <vector>
namespace gil = boost::gil;
template <typename Rasterizer>
void test_rasterizer_follows_equation(Rasterizer rasterizer)
{
std::ptrdiff_t const radius = rasterizer.radius;
std::vector<gil::point_t> circle_points(rasterizer.point_count());
std::ptrdiff_t const r_squared = radius * radius;
rasterizer(circle_points.begin());
std::vector<gil::point_t> first_octant(rasterizer.point_count() / 8);
for (std::size_t i = 0, octant_index = 0; i < circle_points.size(); i += 8, ++octant_index)
{
first_octant[octant_index] = circle_points[i];
}
for (auto const& point : first_octant)
{
double const y_exact = std::sqrt(r_squared - point.x * point.x);
std::ptrdiff_t lower_result = static_cast<std::ptrdiff_t>(std::floor(y_exact));
std::ptrdiff_t upper_result = static_cast<std::ptrdiff_t>(std::ceil(y_exact));
BOOST_TEST(point.y >= lower_result && point.y <= upper_result);
}
}
template <typename Rasterizer>
void test_connectivity(Rasterizer rasterizer)
{
std::vector<gil::point_t> circle_points(rasterizer.point_count());
rasterizer(circle_points.begin());
for (std::size_t i = 0; i < 8; ++i)
{
std::vector<gil::point_t> octant(circle_points.size() / 8);
for (std::size_t octant_index = i, index = 0; octant_index < circle_points.size();
octant_index += 8, ++index)
{
octant[index] = circle_points[octant_index];
}
for (std::size_t index = 1; index < octant.size(); ++index)
{
const auto diff_x = std::abs(octant[index].x - octant[index - 1].x);
const auto diff_y = std::abs(octant[index].y - octant[index - 1].y);
BOOST_TEST_LE(diff_x, 1);
BOOST_TEST_LE(diff_y, 1);
}
}
}
int main()
{
for (std::ptrdiff_t radius = 5; radius <= 512; ++radius)
{
test_rasterizer_follows_equation(gil::midpoint_circle_rasterizer{{0, 0}, radius});
// TODO: find out a new testing procedure for trigonometric rasterizer
// test_equation_following(radius, gil::trigonometric_circle_rasterizer{});
test_connectivity(gil::midpoint_circle_rasterizer{{radius, radius}, radius});
test_connectivity(gil::trigonometric_circle_rasterizer{{radius, radius}, radius});
}
return boost::report_errors();
}
|