// Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. // Use, modification and distribution is 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) #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINE_LINE_INTERSECTION_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINE_LINE_INTERSECTION_HPP #include #include #include #include namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace buffer { // TODO: once change this to proper strategy // It is different from current segment intersection because these are not segments but lines // If we have the Line concept, we can create a strategy // Assumes a convex corner struct line_line_intersection { template static inline strategy::buffer::join_selector apply(Point const& pi, Point const& pj, Point const& qi, Point const& qj, Point& ip) { // See http://mathworld.wolfram.com/Line-LineIntersection.html typedef typename coordinate_type::type coordinate_type; coordinate_type const denominator = determinant(get<0>(pi) - get<0>(pj), get<1>(pi) - get<1>(pj), get<0>(qi) - get<0>(qj), get<1>(qi) - get<1>(qj)); // Even if the corner was checked before (so it is convex now), that // was done on the original geometry. This function runs on the buffered // geometries, where sides are generated and might be slightly off. In // Floating Point, that slightly might just exceed the limit and we have // to check it again. // For round joins, it will not be used at all. // For miter joints, there is a miter limit // If segments are parallel/collinear we must be distinguish two cases: // they continue each other, or they form a spike if (math::equals(denominator, coordinate_type())) { return parallel_continue(get<0>(qj) - get<0>(qi), get<1>(qj) - get<1>(qi), get<0>(pj) - get<0>(pi), get<1>(pj) - get<1>(pi)) ? strategy::buffer::join_continue : strategy::buffer::join_spike ; } coordinate_type d1 = determinant(get<0>(pi), get<1>(pi), get<0>(pj), get<1>(pj)); coordinate_type d2 = determinant(get<0>(qi), get<1>(qi), get<0>(qj), get<1>(qj)); double const multiplier = 1.0 / denominator; set<0>(ip, determinant(d1, get<0>(pi) - get<0>(pj), d2, get<0>(qi) - get<0>(qj)) * multiplier); set<1>(ip, determinant(d1, get<1>(pi) - get<1>(pj), d2, get<1>(qi) - get<1>(qj)) * multiplier); return strategy::buffer::join_convex; } }; }} // namespace detail::buffer #endif // DOXYGEN_NO_DETAIL }} // namespace boost::geometry #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_BUFFER_LINE_LINE_INTERSECTION_HPP