util/math: clamp, degrees, radians
Use common functions for degrees <-> radians conversions, except when dealing with agg, where it makes sense to use available deg2rad/rad2deg functions instead of including another header.
This commit is contained in:
parent
0a6e82e555
commit
a0a2c78950
9 changed files with 41 additions and 32 deletions
|
@ -28,6 +28,7 @@
|
||||||
#endif
|
#endif
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
|
#include <mapnik/util/math.hpp>
|
||||||
#include <mapnik/vertex.hpp>
|
#include <mapnik/vertex.hpp>
|
||||||
#include <mapnik/vertex_cache.hpp>
|
#include <mapnik/vertex_cache.hpp>
|
||||||
|
|
||||||
|
@ -572,14 +573,16 @@ private:
|
||||||
{
|
{
|
||||||
// inside turn (sharp/obtuse angle)
|
// inside turn (sharp/obtuse angle)
|
||||||
MAPNIK_LOG_DEBUG(ctrans) << "offset_converter:"
|
MAPNIK_LOG_DEBUG(ctrans) << "offset_converter:"
|
||||||
<< " Sharp joint [<< inside turn " << int(joint_angle*180/M_PI)
|
<< " Sharp joint [<< inside turn "
|
||||||
|
<< static_cast<int>(util::degrees(joint_angle))
|
||||||
<< " degrees >>]";
|
<< " degrees >>]";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// outside turn (reflex angle)
|
// outside turn (reflex angle)
|
||||||
MAPNIK_LOG_DEBUG(ctrans) << "offset_converter:"
|
MAPNIK_LOG_DEBUG(ctrans) << "offset_converter:"
|
||||||
<< " Bulge joint >)) outside turn " << int(joint_angle*180/M_PI)
|
<< " Bulge joint >)) outside turn "
|
||||||
|
<< static_cast<int>(util::degrees(joint_angle))
|
||||||
<< " degrees ((< with " << bulge_steps << " segments";
|
<< " degrees ((< with " << bulge_steps << " segments";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#define MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP
|
#define MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP
|
||||||
|
|
||||||
#include <mapnik/svg/svg_path_parser.hpp>
|
#include <mapnik/svg/svg_path_parser.hpp>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/home/x3.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
|
@ -44,8 +45,6 @@ using svg_parse_context_type = x3::context<relative_tag, std::reference_wrapper<
|
||||||
x3::context<svg_path_tag,std::reference_wrapper<svg_converter_type> const,
|
x3::context<svg_path_tag,std::reference_wrapper<svg_converter_type> const,
|
||||||
phrase_parse_context_type>>;
|
phrase_parse_context_type>>;
|
||||||
|
|
||||||
inline double deg2rad(double deg) {return (M_PI * deg) / 180.0;}
|
|
||||||
|
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
#endif // MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP
|
#endif // MAPNIK_SVG_GRAMMAR_CONFIG_X3_HPP
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
#define MAPNIK_SVG_PATH_COMMANDS_HPP
|
#define MAPNIK_SVG_PATH_COMMANDS_HPP
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/global.hpp>
|
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
|
#include <mapnik/util/math.hpp>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
@ -35,12 +35,6 @@
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
namespace svg {
|
namespace svg {
|
||||||
|
|
||||||
|
|
||||||
inline double deg2rad(double deg)
|
|
||||||
{
|
|
||||||
return (M_PI * deg) / 180.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct move_to
|
struct move_to
|
||||||
{
|
{
|
||||||
using result_type = void;
|
using result_type = void;
|
||||||
|
@ -137,7 +131,7 @@ struct arc_to
|
||||||
void operator()(PathType& path, T0 const& rv, T1 const& angle, T2 large_arc_flag, T3 sweep_flag, T4 const& v, T5 rel) const
|
void operator()(PathType& path, T0 const& rv, T1 const& angle, T2 large_arc_flag, T3 sweep_flag, T4 const& v, T5 rel) const
|
||||||
{
|
{
|
||||||
path.arc_to(boost::fusion::at_c<0>(rv), boost::fusion::at_c<1>(rv),
|
path.arc_to(boost::fusion::at_c<0>(rv), boost::fusion::at_c<1>(rv),
|
||||||
deg2rad(angle), large_arc_flag, sweep_flag,
|
util::radians(angle), large_arc_flag, sweep_flag,
|
||||||
boost::fusion::at_c<0>(v), boost::fusion::at_c<1>(v),
|
boost::fusion::at_c<0>(v), boost::fusion::at_c<1>(v),
|
||||||
rel);
|
rel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,10 @@
|
||||||
#define MAPNIK_SVG_PATH_GRAMMAR_X3_DEF_HPP
|
#define MAPNIK_SVG_PATH_GRAMMAR_X3_DEF_HPP
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/global.hpp>
|
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/svg/svg_path_grammar_x3.hpp>
|
#include <mapnik/svg/svg_path_grammar_x3.hpp>
|
||||||
|
#include <mapnik/util/math.hpp>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/fusion/adapted/std_tuple.hpp>
|
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||||
|
@ -112,7 +113,8 @@ auto const arc_to = [] (auto & ctx)
|
||||||
int sweep_flag = boost::fusion::at_c<3>(attr);
|
int sweep_flag = boost::fusion::at_c<3>(attr);
|
||||||
auto const& v = boost::fusion::at_c<4>(attr);
|
auto const& v = boost::fusion::at_c<4>(attr);
|
||||||
x3::get<svg_path_tag>(ctx).get().arc_to(std::get<0>(p),std::get<1>(p),
|
x3::get<svg_path_tag>(ctx).get().arc_to(std::get<0>(p),std::get<1>(p),
|
||||||
deg2rad(angle), large_arc_flag, sweep_flag,
|
util::radians(angle),
|
||||||
|
large_arc_flag, sweep_flag,
|
||||||
std::get<0>(v),std::get<1>(v),
|
std::get<0>(v),std::get<1>(v),
|
||||||
x3::get<relative_tag>(ctx));
|
x3::get<relative_tag>(ctx));
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/svg/svg_transform_grammar_x3.hpp>
|
#include <mapnik/svg/svg_transform_grammar_x3.hpp>
|
||||||
|
|
||||||
// boost::fusion
|
// boost::fusion
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
@ -66,12 +67,12 @@ auto const rotate_action = [] (auto const& ctx)
|
||||||
auto cy = boost::fusion::at_c<2>(attr) ? *boost::fusion::at_c<2>(attr) : 0.0;
|
auto cy = boost::fusion::at_c<2>(attr) ? *boost::fusion::at_c<2>(attr) : 0.0;
|
||||||
if (cx == 0.0 && cy == 0.0)
|
if (cx == 0.0 && cy == 0.0)
|
||||||
{
|
{
|
||||||
tr = agg::trans_affine_rotation(deg2rad(a)) * tr;
|
tr = agg::trans_affine_rotation(agg::deg2rad(a)) * tr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
agg::trans_affine t = agg::trans_affine_translation(-cx, -cy);
|
agg::trans_affine t = agg::trans_affine_translation(-cx, -cy);
|
||||||
t *= agg::trans_affine_rotation(deg2rad(a));
|
t *= agg::trans_affine_rotation(agg::deg2rad(a));
|
||||||
t *= agg::trans_affine_translation(cx, cy);
|
t *= agg::trans_affine_translation(cx, cy);
|
||||||
tr = t * tr;
|
tr = t * tr;
|
||||||
}
|
}
|
||||||
|
@ -101,14 +102,14 @@ auto const skewX_action = [] (auto const& ctx)
|
||||||
{
|
{
|
||||||
auto & tr = x3::get<svg_transform_tag>(ctx).get();
|
auto & tr = x3::get<svg_transform_tag>(ctx).get();
|
||||||
auto skew_x = _attr(ctx);
|
auto skew_x = _attr(ctx);
|
||||||
tr = agg::trans_affine_skewing(deg2rad(skew_x), 0.0) * tr;
|
tr = agg::trans_affine_skewing(agg::deg2rad(skew_x), 0.0) * tr;
|
||||||
};
|
};
|
||||||
|
|
||||||
auto const skewY_action = [] (auto const& ctx)
|
auto const skewY_action = [] (auto const& ctx)
|
||||||
{
|
{
|
||||||
auto & tr = x3::get<svg_transform_tag>(ctx).get();
|
auto & tr = x3::get<svg_transform_tag>(ctx).get();
|
||||||
auto skew_y= _attr(ctx);
|
auto skew_y= _attr(ctx);
|
||||||
tr = agg::trans_affine_skewing(0.0, deg2rad(skew_y)) * tr;
|
tr = agg::trans_affine_skewing(0.0, agg::deg2rad(skew_y)) * tr;
|
||||||
};
|
};
|
||||||
|
|
||||||
//exported rule
|
//exported rule
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <mapnik/value.hpp>
|
#include <mapnik/value.hpp>
|
||||||
#include <mapnik/transform/transform_expression.hpp>
|
#include <mapnik/transform/transform_expression.hpp>
|
||||||
#include <mapnik/expression_evaluator.hpp>
|
#include <mapnik/expression_evaluator.hpp>
|
||||||
|
#include <mapnik/util/math.hpp>
|
||||||
#include <mapnik/util/variant.hpp>
|
#include <mapnik/util/variant.hpp>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
@ -145,7 +146,7 @@ struct transform_processor
|
||||||
|
|
||||||
void operator() (rotate_node const& node) const
|
void operator() (rotate_node const& node) const
|
||||||
{
|
{
|
||||||
double angle = deg2rad(eval(node.angle_));
|
double angle = agg::deg2rad(eval(node.angle_));
|
||||||
double cx = eval(node.cx_, 0.0);
|
double cx = eval(node.cx_, 0.0);
|
||||||
double cy = eval(node.cy_, 0.0);
|
double cy = eval(node.cy_, 0.0);
|
||||||
transform_.translate(-cx, -cy);
|
transform_.translate(-cx, -cy);
|
||||||
|
@ -156,28 +157,19 @@ struct transform_processor
|
||||||
void operator() (skewX_node const& node) const
|
void operator() (skewX_node const& node) const
|
||||||
{
|
{
|
||||||
auto degrees = std::fmod(eval(node.angle_),90.0);
|
auto degrees = std::fmod(eval(node.angle_),90.0);
|
||||||
if (degrees < -89.0) degrees = -89.0;
|
auto angle = agg::deg2rad(util::clamp(degrees, -89.0, 89.0));
|
||||||
else if (degrees > 89.0) degrees = 89.0;
|
|
||||||
auto angle = deg2rad(degrees);
|
|
||||||
transform_.multiply(agg::trans_affine_skewing(angle, 0.0));
|
transform_.multiply(agg::trans_affine_skewing(angle, 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator() (skewY_node const& node) const
|
void operator() (skewY_node const& node) const
|
||||||
{
|
{
|
||||||
auto degrees = std::fmod(eval(node.angle_),90.0);
|
auto degrees = std::fmod(eval(node.angle_),90.0);
|
||||||
if (degrees < -89.0) degrees = -89.0;
|
auto angle = agg::deg2rad(util::clamp(degrees, -89.0, 89.0));
|
||||||
else if (degrees > 89.0) degrees = 89.0;
|
|
||||||
auto angle = deg2rad(degrees);
|
|
||||||
transform_.multiply(agg::trans_affine_skewing(0.0, angle));
|
transform_.multiply(agg::trans_affine_skewing(0.0, angle));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static double deg2rad(double d)
|
|
||||||
{
|
|
||||||
return d * M_PI / 180.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
double eval(expr_node const& x) const
|
double eval(expr_node const& x) const
|
||||||
{
|
{
|
||||||
mapnik::evaluate<feature_type, value_type, variable_type> e(feature_,vars_);
|
mapnik::evaluate<feature_type, value_type, variable_type> e(feature_,vars_);
|
||||||
|
|
|
@ -30,6 +30,22 @@ namespace mapnik { namespace util {
|
||||||
constexpr double pi = 3.1415926535897932384626433832795;
|
constexpr double pi = 3.1415926535897932384626433832795;
|
||||||
constexpr double tau = 6.283185307179586476925286766559;
|
constexpr double tau = 6.283185307179586476925286766559;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
constexpr T const& clamp(T const& v, T const& lo, T const& hi)
|
||||||
|
{
|
||||||
|
return v < lo ? lo : hi < v ? hi : v;
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr double degrees(double rad)
|
||||||
|
{
|
||||||
|
return rad * (360 / tau);
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr double radians(double deg)
|
||||||
|
{
|
||||||
|
return deg * (tau / 360);
|
||||||
|
}
|
||||||
|
|
||||||
MAPNIK_DECL double normalize_angle(double angle);
|
MAPNIK_DECL double normalize_angle(double angle);
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
#include <mapnik/symbolizer.hpp>
|
#include <mapnik/symbolizer.hpp>
|
||||||
#include <mapnik/text/harfbuzz_shaper.hpp>
|
#include <mapnik/text/harfbuzz_shaper.hpp>
|
||||||
|
#include <mapnik/util/math.hpp>
|
||||||
#include <mapnik/make_unique.hpp>
|
#include <mapnik/make_unique.hpp>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
|
@ -117,7 +118,7 @@ text_layout::text_layout(face_manager_freetype & font_manager,
|
||||||
if (!wrap_str.empty()) wrap_char_ = wrap_str[0];
|
if (!wrap_str.empty()) wrap_char_ = wrap_str[0];
|
||||||
wrap_width_ = util::apply_visitor(extract_value<value_double>(feature,attrs), layout_properties_.wrap_width);
|
wrap_width_ = util::apply_visitor(extract_value<value_double>(feature,attrs), layout_properties_.wrap_width);
|
||||||
double angle = util::apply_visitor(extract_value<value_double>(feature,attrs), layout_properties_.orientation);
|
double angle = util::apply_visitor(extract_value<value_double>(feature,attrs), layout_properties_.orientation);
|
||||||
orientation_.init(angle * M_PI/ 180.0);
|
orientation_.init(util::radians(angle));
|
||||||
wrap_before_ = util::apply_visitor(extract_value<value_bool>(feature,attrs), layout_properties_.wrap_before);
|
wrap_before_ = util::apply_visitor(extract_value<value_bool>(feature,attrs), layout_properties_.wrap_before);
|
||||||
repeat_wrap_char_ = util::apply_visitor(extract_value<value_bool>(feature,attrs), layout_properties_.repeat_wrap_char);
|
repeat_wrap_char_ = util::apply_visitor(extract_value<value_bool>(feature,attrs), layout_properties_.repeat_wrap_char);
|
||||||
rotate_displacement_ = util::apply_visitor(extract_value<value_bool>(feature,attrs), layout_properties_.rotate_displacement);
|
rotate_displacement_ = util::apply_visitor(extract_value<value_bool>(feature,attrs), layout_properties_.rotate_displacement);
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/text/text_properties.hpp>
|
#include <mapnik/text/text_properties.hpp>
|
||||||
#include <mapnik/text/text_layout.hpp>
|
#include <mapnik/text/text_layout.hpp>
|
||||||
|
#include <mapnik/util/math.hpp>
|
||||||
#include <mapnik/debug.hpp>
|
#include <mapnik/debug.hpp>
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
#include <mapnik/symbolizer.hpp>
|
#include <mapnik/symbolizer.hpp>
|
||||||
|
@ -59,7 +60,7 @@ evaluated_text_properties_ptr evaluate_text_properties(text_symbolizer_propertie
|
||||||
prop->minimum_distance = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.minimum_distance);
|
prop->minimum_distance = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.minimum_distance);
|
||||||
prop->minimum_padding = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.minimum_padding);
|
prop->minimum_padding = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.minimum_padding);
|
||||||
prop->minimum_path_length = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.minimum_path_length);
|
prop->minimum_path_length = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.minimum_path_length);
|
||||||
prop->max_char_angle_delta = util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.max_char_angle_delta) * M_PI/180;
|
prop->max_char_angle_delta = util::radians(util::apply_visitor(extract_value<value_double>(feature,attrs), text_prop.expressions.max_char_angle_delta));
|
||||||
prop->allow_overlap = util::apply_visitor(extract_value<value_bool>(feature,attrs), text_prop.expressions.allow_overlap);
|
prop->allow_overlap = util::apply_visitor(extract_value<value_bool>(feature,attrs), text_prop.expressions.allow_overlap);
|
||||||
prop->largest_bbox_only = util::apply_visitor(extract_value<value_bool>(feature,attrs), text_prop.expressions.largest_bbox_only);
|
prop->largest_bbox_only = util::apply_visitor(extract_value<value_bool>(feature,attrs), text_prop.expressions.largest_bbox_only);
|
||||||
prop->upright = util::apply_visitor(extract_value<text_upright_enum>(feature,attrs), text_prop.expressions.upright);
|
prop->upright = util::apply_visitor(extract_value<text_upright_enum>(feature,attrs), text_prop.expressions.upright);
|
||||||
|
|
Loading…
Add table
Reference in a new issue