annotate DEPENDENCIES/generic/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 // Boost.Geometry (aka GGL, Generic Geometry Library)
Chris@16 2
Chris@101 3 // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
Chris@101 4 // Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
Chris@101 5 // Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
Chris@101 6
Chris@101 7 // This file was modified by Oracle on 2015.
Chris@101 8 // Modifications copyright (c) 2015, Oracle and/or its affiliates.
Chris@101 9
Chris@101 10 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
Chris@16 11
Chris@16 12 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
Chris@16 13 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
Chris@16 14
Chris@16 15 // Use, modification and distribution is subject to the Boost Software License,
Chris@16 16 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 17 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 18
Chris@16 19 #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
Chris@16 20 #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP
Chris@16 21
Chris@16 22 #include <boost/mpl/if.hpp>
Chris@16 23 #include <boost/type_traits.hpp>
Chris@16 24
Chris@16 25 #include <boost/geometry/arithmetic/determinant.hpp>
Chris@16 26 #include <boost/geometry/core/access.hpp>
Chris@16 27 #include <boost/geometry/util/select_coordinate_type.hpp>
Chris@16 28 #include <boost/geometry/strategies/side.hpp>
Chris@16 29
Chris@101 30 #include <boost/geometry/algorithms/detail/relate/less.hpp>
Chris@101 31 #include <boost/geometry/algorithms/detail/equals/point_point.hpp>
Chris@101 32
Chris@16 33
Chris@16 34 namespace boost { namespace geometry
Chris@16 35 {
Chris@16 36
Chris@16 37 namespace strategy { namespace side
Chris@16 38 {
Chris@16 39
Chris@16 40 /*!
Chris@16 41 \brief Check at which side of a segment a point lies:
Chris@16 42 left of segment (> 0), right of segment (< 0), on segment (0)
Chris@16 43 \ingroup strategies
Chris@16 44 \tparam CalculationType \tparam_calculation
Chris@16 45 */
Chris@16 46 template <typename CalculationType = void>
Chris@16 47 class side_by_triangle
Chris@16 48 {
Chris@101 49 template <typename Policy>
Chris@101 50 struct eps_policy
Chris@101 51 {
Chris@101 52 eps_policy() {}
Chris@101 53 template <typename Type>
Chris@101 54 eps_policy(Type const& a, Type const& b, Type const& c, Type const& d)
Chris@101 55 : policy(a, b, c, d)
Chris@101 56 {}
Chris@101 57 Policy policy;
Chris@101 58 };
Chris@101 59
Chris@101 60 struct eps_empty
Chris@101 61 {
Chris@101 62 eps_empty() {}
Chris@101 63 template <typename Type>
Chris@101 64 eps_empty(Type const&, Type const&, Type const&, Type const&) {}
Chris@101 65 };
Chris@101 66
Chris@16 67 public :
Chris@16 68
Chris@16 69 // Template member function, because it is not always trivial
Chris@16 70 // or convenient to explicitly mention the typenames in the
Chris@16 71 // strategy-struct itself.
Chris@16 72
Chris@16 73 // Types can be all three different. Therefore it is
Chris@16 74 // not implemented (anymore) as "segment"
Chris@16 75
Chris@101 76 template
Chris@101 77 <
Chris@101 78 typename CoordinateType,
Chris@101 79 typename PromotedType,
Chris@101 80 typename P1,
Chris@101 81 typename P2,
Chris@101 82 typename P,
Chris@101 83 typename EpsPolicy
Chris@101 84 >
Chris@101 85 static inline
Chris@101 86 PromotedType side_value(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & eps_policy)
Chris@101 87 {
Chris@101 88 CoordinateType const x = get<0>(p);
Chris@101 89 CoordinateType const y = get<1>(p);
Chris@101 90
Chris@101 91 CoordinateType const sx1 = get<0>(p1);
Chris@101 92 CoordinateType const sy1 = get<1>(p1);
Chris@101 93 CoordinateType const sx2 = get<0>(p2);
Chris@101 94 CoordinateType const sy2 = get<1>(p2);
Chris@101 95
Chris@101 96 PromotedType const dx = sx2 - sx1;
Chris@101 97 PromotedType const dy = sy2 - sy1;
Chris@101 98 PromotedType const dpx = x - sx1;
Chris@101 99 PromotedType const dpy = y - sy1;
Chris@101 100
Chris@101 101 eps_policy = EpsPolicy(dx, dy, dpx, dpy);
Chris@101 102
Chris@101 103 return geometry::detail::determinant<PromotedType>
Chris@101 104 (
Chris@101 105 dx, dy,
Chris@101 106 dpx, dpy
Chris@101 107 );
Chris@101 108
Chris@101 109 }
Chris@101 110
Chris@101 111 template
Chris@101 112 <
Chris@101 113 typename CoordinateType,
Chris@101 114 typename PromotedType,
Chris@101 115 typename P1,
Chris@101 116 typename P2,
Chris@101 117 typename P
Chris@101 118 >
Chris@101 119 static inline
Chris@101 120 PromotedType side_value(P1 const& p1, P2 const& p2, P const& p)
Chris@101 121 {
Chris@101 122 eps_empty dummy;
Chris@101 123 return side_value<CoordinateType, PromotedType>(p1, p2, p, dummy);
Chris@101 124 }
Chris@101 125
Chris@101 126
Chris@101 127 template
Chris@101 128 <
Chris@101 129 typename CoordinateType,
Chris@101 130 typename PromotedType,
Chris@101 131 bool AreAllIntegralCoordinates
Chris@101 132 >
Chris@101 133 struct compute_side_value
Chris@101 134 {
Chris@101 135 template <typename P1, typename P2, typename P, typename EpsPolicy>
Chris@101 136 static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
Chris@101 137 {
Chris@101 138 return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
Chris@101 139 }
Chris@101 140 };
Chris@101 141
Chris@101 142 template <typename CoordinateType, typename PromotedType>
Chris@101 143 struct compute_side_value<CoordinateType, PromotedType, false>
Chris@101 144 {
Chris@101 145 template <typename P1, typename P2, typename P, typename EpsPolicy>
Chris@101 146 static inline PromotedType apply(P1 const& p1, P2 const& p2, P const& p, EpsPolicy & epsp)
Chris@101 147 {
Chris@101 148 // For robustness purposes, first check if any two points are
Chris@101 149 // the same; in this case simply return that the points are
Chris@101 150 // collinear
Chris@101 151 if (geometry::detail::equals::equals_point_point(p1, p2)
Chris@101 152 || geometry::detail::equals::equals_point_point(p1, p)
Chris@101 153 || geometry::detail::equals::equals_point_point(p2, p))
Chris@101 154 {
Chris@101 155 return PromotedType(0);
Chris@101 156 }
Chris@101 157
Chris@101 158 // The side_by_triangle strategy computes the signed area of
Chris@101 159 // the point triplet (p1, p2, p); as such it is (in theory)
Chris@101 160 // invariant under cyclic permutations of its three arguments.
Chris@101 161 //
Chris@101 162 // In the context of numerical errors that arise in
Chris@101 163 // floating-point computations, and in order to make the strategy
Chris@101 164 // consistent with respect to cyclic permutations of its three
Chris@101 165 // arguments, we cyclically permute them so that the first
Chris@101 166 // argument is always the lexicographically smallest point.
Chris@101 167
Chris@101 168 geometry::detail::relate::less less;
Chris@101 169 if (less(p, p1))
Chris@101 170 {
Chris@101 171 if (less(p, p2))
Chris@101 172 {
Chris@101 173 // p is the lexicographically smallest
Chris@101 174 return side_value<CoordinateType, PromotedType>(p, p1, p2, epsp);
Chris@101 175 }
Chris@101 176 else
Chris@101 177 {
Chris@101 178 // p2 is the lexicographically smallest
Chris@101 179 return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
Chris@101 180 }
Chris@101 181 }
Chris@101 182
Chris@101 183 if (less(p1, p2))
Chris@101 184 {
Chris@101 185 // p1 is the lexicographically smallest
Chris@101 186 return side_value<CoordinateType, PromotedType>(p1, p2, p, epsp);
Chris@101 187 }
Chris@101 188 else
Chris@101 189 {
Chris@101 190 // p2 is the lexicographically smallest
Chris@101 191 return side_value<CoordinateType, PromotedType>(p2, p, p1, epsp);
Chris@101 192 }
Chris@101 193 }
Chris@101 194 };
Chris@101 195
Chris@101 196
Chris@16 197 template <typename P1, typename P2, typename P>
Chris@16 198 static inline int apply(P1 const& p1, P2 const& p2, P const& p)
Chris@16 199 {
Chris@101 200 typedef typename coordinate_type<P1>::type coordinate_type1;
Chris@101 201 typedef typename coordinate_type<P2>::type coordinate_type2;
Chris@101 202 typedef typename coordinate_type<P>::type coordinate_type3;
Chris@101 203
Chris@16 204 typedef typename boost::mpl::if_c
Chris@16 205 <
Chris@16 206 boost::is_void<CalculationType>::type::value,
Chris@16 207 typename select_most_precise
Chris@16 208 <
Chris@16 209 typename select_most_precise
Chris@16 210 <
Chris@101 211 coordinate_type1, coordinate_type2
Chris@16 212 >::type,
Chris@101 213 coordinate_type3
Chris@16 214 >::type,
Chris@16 215 CalculationType
Chris@16 216 >::type coordinate_type;
Chris@16 217
Chris@16 218 // Promote float->double, small int->int
Chris@16 219 typedef typename select_most_precise
Chris@16 220 <
Chris@16 221 coordinate_type,
Chris@16 222 double
Chris@16 223 >::type promoted_type;
Chris@16 224
Chris@101 225 bool const are_all_integral_coordinates =
Chris@101 226 boost::is_integral<coordinate_type1>::value
Chris@101 227 && boost::is_integral<coordinate_type2>::value
Chris@101 228 && boost::is_integral<coordinate_type3>::value;
Chris@16 229
Chris@101 230 eps_policy< math::detail::equals_factor_policy<promoted_type> > epsp;
Chris@101 231 promoted_type s = compute_side_value
Chris@101 232 <
Chris@101 233 coordinate_type, promoted_type, are_all_integral_coordinates
Chris@101 234 >::apply(p1, p2, p, epsp);
Chris@16 235
Chris@16 236 promoted_type const zero = promoted_type();
Chris@101 237 return math::detail::equals_by_policy(s, zero, epsp.policy) ? 0
Chris@101 238 : s > zero ? 1
Chris@16 239 : -1;
Chris@16 240 }
Chris@101 241
Chris@16 242 };
Chris@16 243
Chris@16 244
Chris@16 245 #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
Chris@16 246 namespace services
Chris@16 247 {
Chris@16 248
Chris@16 249 template <typename CalculationType>
Chris@16 250 struct default_strategy<cartesian_tag, CalculationType>
Chris@16 251 {
Chris@16 252 typedef side_by_triangle<CalculationType> type;
Chris@16 253 };
Chris@16 254
Chris@16 255 }
Chris@16 256 #endif
Chris@16 257
Chris@16 258 }} // namespace strategy::side
Chris@16 259
Chris@16 260 }} // namespace boost::geometry
Chris@16 261
Chris@16 262
Chris@16 263 #endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_SIDE_BY_TRIANGLE_HPP