mapnik/include/mapnik/adaptive_smooth.hpp
Mathis Logemann e7c3d04309 format dir include and src
format all files

Revert "format all files"

This reverts commit 95d5812e49e7f916b68e786596f5a8eb5bcac414.

Revert "format some files"

This reverts commit ed3c8762d4d828b2b28e7b18809fc33f4f8ccaf5.

format all files

fix formatting in dir include

fix formatting of debug macro
2022-01-27 00:12:08 +01:00

123 lines
3.6 KiB
C++

#ifndef MAPNIK_ADAPTIVE_SMOOTH_HPP
#define MAPNIK_ADAPTIVE_SMOOTH_HPP
#include <mapnik/util/math.hpp>
#include <mapnik/warning.hpp>
MAPNIK_DISABLE_WARNING_PUSH
#include <mapnik/warning_ignore_agg.hpp>
#include "agg_conv_smooth_poly1.h"
MAPNIK_DISABLE_WARNING_POP
namespace mapnik {
struct vcgen_smooth_calucate_adaptive
{
using result_type = std::pair<agg::point_d, agg::point_d>;
using vertex_type = agg::vertex_dist;
static result_type apply(vertex_type const& v0,
vertex_type const& v1,
vertex_type const& v2,
vertex_type const& v3,
double smooth_value)
{
double k1 = v0.dist / (v0.dist + v1.dist);
double k2 = v1.dist / (v1.dist + v2.dist);
double xm1 = v0.x + (v2.x - v0.x) * k1;
double ym1 = v0.y + (v2.y - v0.y) * k1;
double xm2 = v1.x + (v3.x - v1.x) * k2;
double ym2 = v1.y + (v3.y - v1.y) * k2;
double s1 = 0;
double s2 = 0;
if (v1.dist > 0.0)
{
if (v0.dist > 0.0)
{
double dot1 = (v0.x - v1.x) * (v2.x - v1.x) + (v0.y - v1.y) * (v2.y - v1.y);
double a1 = std::acos(dot1 / (v0.dist * v1.dist));
if (a1 >= util::pi * 0.5)
{
s1 = (a1 - util::pi * 0.5) / (util::pi * 0.5);
}
}
if (v2.dist > 0.0)
{
double dot2 = (v1.x - v2.x) * (v3.x - v2.x) + (v1.y - v2.y) * (v3.y - v2.y);
double a2 = std::acos(dot2 / (v1.dist * v2.dist));
if (a2 >= util::pi * 0.5)
{
s2 = (a2 - util::pi * 0.5) / (util::pi * 0.5);
}
}
}
return {{v1.x + s1 * smooth_value * (v2.x - xm1), v1.y + s1 * smooth_value * (v2.y - ym1)},
{v2.x + s2 * smooth_value * (v1.x - xm2), v2.y + s2 * smooth_value * (v1.y - ym2)}};
}
};
using vcgen_smooth_adaptive = agg::vcgen_smooth<vcgen_smooth_calucate_adaptive>;
template<class VertexSource>
using conv_smooth_adaptive = agg::conv_smooth_curve<VertexSource, vcgen_smooth_adaptive>;
template<typename Geometry>
class smooth_converter
{
Geometry geom_;
using basic_impl_type = typename agg::conv_smooth_poly1_curve<Geometry>;
using adaptive_impl_type = conv_smooth_adaptive<Geometry>;
using impl_type = util::variant<basic_impl_type, adaptive_impl_type>;
impl_type impl_;
impl_type init_impl(smooth_algorithm_enum algo, Geometry& geom) const
{
switch (algo)
{
case SMOOTH_ALGORITHM_ADAPTIVE:
return adaptive_impl_type(geom);
case SMOOTH_ALGORITHM_BASIC:
default:
break;
}
return basic_impl_type(geom);
}
public:
smooth_converter(Geometry& geom)
: geom_(geom)
, impl_(std::move(init_impl(SMOOTH_ALGORITHM_BASIC, geom)))
{}
void algorithm(smooth_algorithm_enum algo) { impl_ = init_impl(algo, geom_); }
void smooth_value(double v)
{
return util::apply_visitor([=](auto& impl) { impl.smooth_value(v); }, impl_);
}
void rewind(unsigned path_id)
{
return util::apply_visitor([=](auto& impl) { return impl.rewind(path_id); }, impl_);
}
unsigned vertex(double* x, double* y)
{
return util::apply_visitor([=](auto& impl) { return impl.vertex(x, y); }, impl_);
}
unsigned type() const
{
return util::apply_visitor([](auto const& impl) { return impl.type(); }, impl_);
}
};
} // namespace mapnik
#endif // MAPNIK_ADAPTIVE_SMOOTH_HPP