mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-22 03:22:14 +00:00
[buffer] Fix direction code for some new cases.
The similar_direction function could be erroneous for corner cases, refactored it out. This also makes it a bit less dependent on infinite_line (cartesian)
This commit is contained in:
@@ -281,6 +281,19 @@ static std::string const rt_u12
|
||||
static std::string const rt_u13
|
||||
= "MULTIPOLYGON(((6 4,6 5,7 5,6 4)),((3 2,3 3,4 3,3 2)),((7 8,7 9,8 9,8 8,7 8)),((4 9,4 10,5 10,4 9)),((7 7,7 8,8 7,7 7)),((2 6,2 7,3 7,2 6)),((0 1,1 2,1 1,0 1)),((3 1,4 2,4 1,3 1)),((2 5,2 6,3 6,2 5)),((3 5,4 4,3 4,2 4,3 5)),((4 1,5 2,5 1,4 1)),((2 0,2 1,3 1,2 0)),((5 7,5 8,6 7,5 7)),((0 2,0 3,1 3,0 2)),((9 8,9 9,10 9,10 8,9 8)),((7 5,7 6,8 5,7 5)),((5 6,5 7,6 6,5 6)),((0 6,0 7,1 7,1 6,0 6)),((5 0,5 1,6 1,5 0)),((8 7,8 8,9 8,8 7)),((4.5 4.5,5 4,4 4,4 5,5 5,4.5 4.5)),((6 2,5 2,5 3,6 3,7 3,8 2,7 2,6 2)),((8 6,8 7,9 7,9 6,9 5,8 5,8 6)),((8 1,9 0,8 0,7 0,8 1)))";
|
||||
|
||||
static std::string const rt_v1
|
||||
= "MULTIPOLYGON(((2 8,2 9,3 9,2 8)),((3 6,3 7,4 7,3 6)),((9 9,9 10,10 10,10 9,9 9)),((0 7,1 8,1 7,0 7)))";
|
||||
|
||||
static std::string const rt_v2
|
||||
= "MULTIPOLYGON(((8 4,8 5,9 5,9 4,8 4)),((2 5,2 6,3 5,2 5)),((9 7,9 8,10 8,10 7,9 7)),((2 2,2 3,3 2,2 2)),((6 6,7 5,6 5,6 6)),((6 6,6 7,7 7,7 6,6 6)),((8 9,9 9,8 8,8 9)),((8 9,7 9,8 10,8 9)))";
|
||||
|
||||
static std::string const rt_v3
|
||||
= "MULTIPOLYGON(((7 0,7 1,8 1,8 0,7 0)),((6 2,6 3,7 2,6 2)),((9 3,8 3,8 4,9 3)),((9 3,9 4,10 3,9 3)))";
|
||||
|
||||
static std::string const rt_v4
|
||||
= "MULTIPOLYGON(((5 4,5 5,6 5,6 4,5 4)),((7 1,6 1,7 2,7 1)),((7 1,8 1,8 0,7 0,7 1)),((6 1,5 1,5 2,6 1)))";
|
||||
|
||||
|
||||
static std::string const neighbouring
|
||||
= "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((10 10,10 20,20 20,20 10,10 10)))";
|
||||
|
||||
@@ -502,6 +515,11 @@ void test_all()
|
||||
test_one<multi_polygon_type, polygon_type>("rt_u12", rt_u12, join_miter, end_flat, 142.1348, 1.0);
|
||||
test_one<multi_polygon_type, polygon_type>("rt_u13", rt_u13, join_miter, end_flat, 115.4853, 1.0);
|
||||
|
||||
test_one<multi_polygon_type, polygon_type>("rt_v1", rt_v1, join_round32, end_flat, 26.9994, 1.0);
|
||||
test_one<multi_polygon_type, polygon_type>("rt_v2", rt_v2, join_round32, end_flat, 47.3510, 1.0);
|
||||
test_one<multi_polygon_type, polygon_type>("rt_v3", rt_v3, join_round32, end_flat, 22.9158, 1.0);
|
||||
test_one<multi_polygon_type, polygon_type>("rt_v4", rt_v4, join_round32, end_flat, 23.4146, 1.0);
|
||||
|
||||
test_one<multi_polygon_type, polygon_type>("neighbouring_small",
|
||||
neighbouring,
|
||||
join_round32, end_round32, 128.0, -1.0);
|
||||
|
||||
@@ -157,9 +157,8 @@ private :
|
||||
<< "/" << it->operations[1].enriched.get_next_turn_index()
|
||||
//<< " frac " << it->operations[0].fraction
|
||||
|
||||
// If you want to see (robust)point coordinates (e.g. to find duplicates)
|
||||
// If you want to see point coordinates (e.g. to find duplicates)
|
||||
<< std::endl << std::setprecision(16) << bg::wkt(it->point)
|
||||
<< std::endl << bg::wkt(it->robust_point)
|
||||
|
||||
<< std::endl;
|
||||
out << " " << bg::method_char(it->method)
|
||||
|
||||
@@ -96,77 +96,6 @@ void test_get_intersection()
|
||||
verify_point_on_line(q, bg::get<0>(ip), bg::get<1>(ip));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_same_direction()
|
||||
{
|
||||
bg::model::infinite_line<T> p, q;
|
||||
|
||||
// Exactly opposite, diagonal
|
||||
p = bg::detail::make::make_infinite_line<T>(2, 1, 12, 11);
|
||||
q = bg::detail::make::make_infinite_line<T>(12, 11, 2, 1);
|
||||
BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// Exactly opposite, horizontal
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 0);
|
||||
q = bg::detail::make::make_infinite_line<T>(10, 0, 0, 0);
|
||||
BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// Exactly opposite, vertical
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 0, 10);
|
||||
q = bg::detail::make::make_infinite_line<T>(0, 10, 0, 0);
|
||||
BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// Exactly equal, diagonal
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
|
||||
q = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
|
||||
BOOST_CHECK(bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// Exactly equal, horizontal
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 0);
|
||||
q = bg::detail::make::make_infinite_line<T>(0, 0, 10, 0);
|
||||
BOOST_CHECK(bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// Exactly equal, vertical
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 0, 10);
|
||||
q = bg::detail::make::make_infinite_line<T>(0, 0, 0, 10);
|
||||
BOOST_CHECK(bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// Coming together, diagonal
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
|
||||
q = bg::detail::make::make_infinite_line<T>(20, 20, 10, 10);
|
||||
BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// Leaving from common point, diagonal
|
||||
p = bg::detail::make::make_infinite_line<T>(10, 10, 0, 0);
|
||||
q = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
|
||||
BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// Continuing each other, diagonal
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
|
||||
q = bg::detail::make::make_infinite_line<T>(10, 10, 20, 20);
|
||||
BOOST_CHECK(bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// (Nearly) perpendicular
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
|
||||
q = bg::detail::make::make_infinite_line<T>(0, 0, -10, 10);
|
||||
BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// 45 deg
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
|
||||
q = bg::detail::make::make_infinite_line<T>(0, 0, 0, 10);
|
||||
BOOST_CHECK(bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// a bit more than 45 deg
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
|
||||
q = bg::detail::make::make_infinite_line<T>(0, 0, -1, 10);
|
||||
BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
|
||||
|
||||
// 135 deg
|
||||
p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
|
||||
q = bg::detail::make::make_infinite_line<T>(0, 0, -10, 0);
|
||||
BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void test_degenerate()
|
||||
{
|
||||
|
||||
@@ -35,7 +35,6 @@ test-suite boost-geometry-strategies
|
||||
[ run segment_intersection_collinear.cpp : : : : strategies_segment_intersection_collinear ]
|
||||
[ run segment_intersection_geo.cpp : : : : strategies_segment_intersection_geo ]
|
||||
[ run segment_intersection_sph.cpp : : : : strategies_segment_intersection_sph ]
|
||||
# [ run side_of_intersection.cpp : : : : strategies_side_of_intersection ]
|
||||
[ run spherical_side.cpp : : : : strategies_spherical_side ]
|
||||
[ run thomas.cpp : : : : strategies_thomas ]
|
||||
[ run transform_cs.cpp : : : : strategies_transform_cs ]
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2011-2015 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)
|
||||
|
||||
|
||||
#include <geometry_test_common.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/cartesian/side_of_intersection.hpp>
|
||||
#include <boost/geometry/geometries/point_xy.hpp>
|
||||
#include <boost/geometry/geometries/segment.hpp>
|
||||
|
||||
|
||||
namespace bg = boost::geometry;
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
typedef bg::model::d2::point_xy<boost::long_long_type> point;
|
||||
typedef bg::model::segment<point> segment;
|
||||
|
||||
typedef bg::strategy::side::side_of_intersection side;
|
||||
|
||||
point no_fb(-99, -99);
|
||||
|
||||
segment a(point(20, 10), point(10, 20));
|
||||
|
||||
segment b1(point(11, 16), point(20, 14)); // IP with a: (14.857, 15.143)
|
||||
segment b2(point(10, 16), point(20, 14)); // IP with a: (15, 15)
|
||||
|
||||
segment c1(point(15, 16), point(13, 8));
|
||||
segment c2(point(15, 16), point(14, 8));
|
||||
segment c3(point(15, 16), point(15, 8));
|
||||
|
||||
|
||||
BOOST_CHECK_EQUAL( 1, side::apply(a, b1, c1, no_fb));
|
||||
BOOST_CHECK_EQUAL(-1, side::apply(a, b1, c2, no_fb));
|
||||
BOOST_CHECK_EQUAL(-1, side::apply(a, b1, c3, no_fb));
|
||||
|
||||
BOOST_CHECK_EQUAL( 1, side::apply(a, b2, c1, no_fb));
|
||||
BOOST_CHECK_EQUAL( 1, side::apply(a, b2, c2, no_fb));
|
||||
BOOST_CHECK_EQUAL( 0, side::apply(a, b2, c3, no_fb));
|
||||
|
||||
// Collinear cases
|
||||
// 1: segments intersecting are collinear (with a fallback point):
|
||||
{
|
||||
point fb(5, 5);
|
||||
segment col1(point(0, 5), point(5, 5));
|
||||
segment col2(point(5, 5), point(10, 5)); // One IP with col1 at (5,5)
|
||||
segment col3(point(5, 0), point(5, 5));
|
||||
BOOST_CHECK_EQUAL( 0, side::apply(col1, col2, col3, fb));
|
||||
}
|
||||
// 2: segment of side calculation collinear with one of the segments
|
||||
{
|
||||
point fb(5, 5);
|
||||
segment col1(point(0, 5), point(10, 5));
|
||||
segment col2(point(5, 5), point(5, 12)); // IP with col1 at (5,5)
|
||||
segment col3(point(5, 1), point(5, 5)); // collinear with col2
|
||||
BOOST_CHECK_EQUAL( 0, side::apply(col1, col2, col3, fb));
|
||||
}
|
||||
{
|
||||
point fb(5, 5);
|
||||
segment col1(point(10, 5), point(0, 5));
|
||||
segment col2(point(5, 5), point(5, 12)); // IP with col1 at (5,5)
|
||||
segment col3(point(5, 1), point(5, 5)); // collinear with col2
|
||||
BOOST_CHECK_EQUAL( 0, side::apply(col1, col2, col3, fb));
|
||||
}
|
||||
{
|
||||
point fb(5, 5);
|
||||
segment col1(point(0, 5), point(10, 5));
|
||||
segment col2(point(5, 12), point(5, 5)); // IP with col1 at (5,5)
|
||||
segment col3(point(5, 1), point(5, 5)); // collinear with col2
|
||||
BOOST_CHECK_EQUAL( 0, side::apply(col1, col2, col3, fb));
|
||||
}
|
||||
|
||||
{
|
||||
point fb(517248, -517236);
|
||||
segment col1(point(-172408, -517236), point(862076, -517236));
|
||||
segment col2(point(517248, -862064), point(517248, -172408));
|
||||
segment col3(point(517248, -172408), point(517248, -517236));
|
||||
BOOST_CHECK_EQUAL( 0, side::apply(col1, col2, col3, fb));
|
||||
}
|
||||
{
|
||||
point fb(-221647, -830336);
|
||||
segment col1(point(-153817, -837972), point(-222457, -830244));
|
||||
segment col2(point(-221139, -833615), point(-290654, -384388));
|
||||
segment col3(point(-255266, -814663), point(-264389, -811197));
|
||||
BOOST_CHECK_EQUAL(1, side::apply(col1, col2, col3, fb)); // Left of segment...
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
point fb(27671131, 30809240);
|
||||
segment col1(point(27671116, 30809247), point(27675474, 30807351));
|
||||
segment col2(point(27666779, 30811130), point(27671139, 30809237));
|
||||
segment col3(point(27671122, 30809244), point(27675480, 30807348));
|
||||
BOOST_CHECK_EQUAL(1, side::apply(col1, col2, col3, fb)); // Left of segment...
|
||||
}
|
||||
|
||||
// TODO: we might add a check calculating the IP, determining the side
|
||||
// with the normal side strategy, and verify the results are equal
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user