// Boost.Geometry (aka GGL, Generic Geometry Library) // // Copyright (c) 2007-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) #define BOOST_GEOMETRY_DEFINE_STREAM_OPERATOR_SEGMENT_RATIO #include #include #include #include #include #include #include #include #include #if defined(TEST_WITH_SVG) # include #endif template void test_one(std::string const& caseid, T pi_x, T pi_y, T pj_x, T pj_y, // line p to intersect T qi_x, T qi_y, T qj_x, T qj_y, // line q to intersect T si_x, T si_y, T sj_x, T sj_y, // subject line to find side on of IP p/q int expected_side) { typedef bg::detail::no_rescale_policy robust_policy_type; robust_policy_type robust_policy; Point pi = bg::make(pi_x, pi_y); Point pj = bg::make(pj_x, pj_y); Point qi = bg::make(qi_x, qi_y); Point qj = bg::make(qj_x, qj_y); Point si = bg::make(si_x, si_y); Point sj = bg::make(sj_x, sj_y); typedef bg::model::referring_segment segment_type; segment_type p(pi, pj); segment_type q(qi, qj); segment_type s(si, sj); int detected_side = bg::detail::intersection_side::intersection_side(pi, pj, qi, qj, si, sj, robust_policy); BOOST_CHECK_EQUAL(expected_side, detected_side); #if defined(TEST_WITH_SVG) { std::ostringstream filename; filename << "intersection_side_" << caseid << "_" << string_from_type::type>::name() << ".svg"; std::ofstream svg(filename.str().c_str()); bg::svg_mapper mapper(svg, 500, 500); mapper.add(p); mapper.add(q); mapper.add(s); mapper.map(p, "opacity:0.7;stroke:rgb(0,192,0);stroke-width:3"); mapper.map(q, "opacity:0.7;stroke:rgb(0,0,255);stroke-width:3"); mapper.map(s, "opacity:0.7;stroke:rgb(255,0,0);stroke-width:2"); std::string style = ";font-family='Verdana';font-weight:bold"; std::string align = ";text-anchor:end;text-align:end"; int offset = 8; mapper.text(pi, "pi", "fill:rgb(0,192,0)" + style, offset, offset); mapper.text(pj, "pj", "fill:rgb(0,192,0)" + style, offset, offset); mapper.text(qi, "qi", "fill:rgb(0,0,255)" + style + align, -offset, offset); mapper.text(qj, "qj", "fill:rgb(0,0,255)" + style + align, -offset, offset); mapper.text(si, "si", "fill:rgb(255,0,0)" + style + align, -offset, offset); mapper.text(sj, "sj", "fill:rgb(255,0,0)" + style + align, -offset, offset); // Map the intersection point on the SVG { typedef typename bg::segment_ratio_type < Point, robust_policy_type >::type segment_ratio_type; // Get the intersection point (or two points) bg::segment_intersection_points is = bg::strategy::intersection::relate_cartesian_segments < bg::policies::relate::segments_intersection_points < bg::segment_intersection_points > >::apply(p, q, robust_policy); bg::fraction_type rs = bg::strategy::intersection::relate_cartesian_segments < bg::policies::relate::segments_intersection_ratios < bg::fraction_type > >::apply(p, q, robust_policy); for (int i = 0; i < is.count; i++) { mapper.map(is.intersections[i], "opacity:0.8;stroke:rgb(255,128,0);stroke-width:3", 3); std::ostringstream out; out << detected_side << " " << is.fractions[i].robust_ra << " / " << is.fractions[i].robust_rb << std::endl << rs.robust_ra << " / " << rs.robust_rb; mapper.text(is.intersections[i], out.str(), "fill:rgb(255,128,0)" + style + align, -2 * offset, offset); } } } #endif } template void test_all() { test_one("simplex_left", 0, 0, 4, 4, // p -1, 4, 3, 0, // q 2, 0, 2, 4, // subject 1); test_one("simplex_right", 0, 0, 4, 4, // p 1, 4, 5, 0, // q 2, 0, 2, 4, // subject -1); test_one("simplex_collinear", 0, 0, 4, 4, // p 0, 4, 4, 0, // q 2, 0, 2, 4, // subject 0); test_one("p_left", 0, 0, 0, 4, // p 1, 4, 5, 0, // q 2, 0, 2, 4, // subject 1); test_one("p_right", 4, 0, 4, 4, // p 1, 4, 5, 0, // q 2, 0, 2, 4, // subject -1); test_one("p_left", 1, 0, 1, 4, // p 1, 4, 5, 0, // q 2, 0, 2, 4, // subject 1); test_one("p_collinear", 2, -1, 2, 5, // p 1, 4, 5, 0, // q 2, 0, 2, 4, // subject 0); test_one("q_left", 0, 0, 4, 4, // p 1, 4, 1, 0, // q 2, 0, 2, 4, // subject 1); test_one("q_right", 0, 0, 4, 4, // p 3, 4, 3, 0, // q 2, 0, 2, 4, // subject -1); test_one("q_collinear", 0, 0, 4, 4, // p 2, 1, 2, 3, // q 2, 0, 2, 4, // subject 0); } int test_main( int , char* [] ) { test_all >(); return 0; }