blob: 97449169a9e0e61459c37fa013c1e92841fbec14 [file] [log] [blame]
// Boost.Polygon library polygon_segment_test.cpp file
// Copyright Andrii Sydorchuk 2012.
// Distributed under 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)
// See http://www.boost.org for updates, documentation, and revision history.
#define BOOST_TEST_MODULE POLYGON_SEGMENT_TEST
#include <boost/mpl/list.hpp>
#include <boost/test/test_case_template.hpp>
#include "boost/polygon/segment_concept.hpp"
#include "boost/polygon/segment_data.hpp"
#include "boost/polygon/segment_traits.hpp"
using namespace boost::polygon;
typedef boost::mpl::list<int> test_types;
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_data_test, T, test_types) {
typedef point_data<T> point_type;
typedef segment_data<T> segment_type;
point_type point1(1, 2);
point_type point2(3, 4);
segment_type segment1(point1, point2);
segment_type segment2;
segment2 = segment1;
BOOST_CHECK(segment1.low() == point1);
BOOST_CHECK(segment1.high() == point2);
BOOST_CHECK(segment1.get(LOW) == point1);
BOOST_CHECK(segment1.get(HIGH) == point2);
BOOST_CHECK(segment1 == segment2);
BOOST_CHECK(!(segment1 != segment2));
BOOST_CHECK(!(segment1 < segment2));
BOOST_CHECK(!(segment1 > segment1));
BOOST_CHECK(segment1 <= segment2);
BOOST_CHECK(segment1 >= segment2);
segment1.low(point2);
segment1.high(point1);
BOOST_CHECK(segment1.low() == point2);
BOOST_CHECK(segment1.high() == point1);
BOOST_CHECK(!(segment1 == segment2));
BOOST_CHECK(segment1 != segment2);
segment2.set(LOW, point2);
segment2.set(HIGH, point1);
BOOST_CHECK(segment1 == segment2);
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_traits_test, T, test_types) {
typedef point_data<T> point_type;
typedef segment_data<T> segment_type;
point_type point1(1, 2);
point_type point2(3, 4);
segment_type segment =
segment_mutable_traits<segment_type>::construct(point1, point2);
BOOST_CHECK(segment_traits<segment_type>::get(segment, LOW) == point1);
BOOST_CHECK(segment_traits<segment_type>::get(segment, HIGH) == point2);
segment_mutable_traits<segment_type>::set(segment, LOW, point2);
segment_mutable_traits<segment_type>::set(segment, HIGH, point1);
BOOST_CHECK(segment_traits<segment_type>::get(segment, LOW) == point2);
BOOST_CHECK(segment_traits<segment_type>::get(segment, HIGH) == point1);
}
template <typename T>
struct Segment {
typedef T coordinate_type;
typedef point_data<T> point_type;
point_type p0;
point_type p1;
};
namespace boost {
namespace polygon {
template <typename T>
struct geometry_concept< Segment<T> > {
typedef segment_concept type;
};
template <typename T>
struct segment_traits< Segment<T> > {
typedef T coordinate_type;
typedef point_data<T> point_type;
static point_type get(const Segment<T>& segment, direction_1d dir) {
return dir.to_int() ? segment.p1 : segment.p0;
}
};
template <typename T>
struct segment_mutable_traits< Segment<T> > {
typedef T coordinate_type;
typedef point_data<T> point_type;
static void set(
Segment<T>& segment, direction_1d dir, const point_type& point) {
dir.to_int() ? segment.p1 = point : segment.p0 = point;;
}
static Segment<T> construct(
const point_type& point1, const point_type& point2) {
Segment<T> segment;
segment.p0 = point1;
segment.p1 = point2;
return segment;
}
};
}
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test1, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
point_type point1(1, 2);
point_type point2(3, 4);
point_type point3(2, 3);
segment_type segment1 = construct<segment_type>(point1, point2);
BOOST_CHECK(segment1.p0 == point1);
BOOST_CHECK(segment1.p1 == point2);
BOOST_CHECK(get(segment1, LOW) == point1);
BOOST_CHECK(low(segment1) == point1);
BOOST_CHECK(get(segment1, HIGH) == point2);
BOOST_CHECK(high(segment1) == point2);
BOOST_CHECK(center(segment1) == point3);
set(segment1, LOW, point2);
set(segment1, HIGH, point1);
BOOST_CHECK(segment1.p0 == point2);
BOOST_CHECK(segment1.p1 == point1);
BOOST_CHECK(get(segment1, LOW) == point2);
BOOST_CHECK(get(segment1, HIGH) == point1);
low(segment1, point1);
high(segment1, point2);
BOOST_CHECK(segment1.p0 == point1);
BOOST_CHECK(segment1.p1 == point2);
segment_data<T> segment2 = copy_construct< segment_data<T> >(segment1);
BOOST_CHECK(segment1.p0 == segment2.low());
BOOST_CHECK(segment1.p1 == segment2.high());
BOOST_CHECK(equivalence(segment1, segment2));
segment_data<T> segment3 = construct< segment_data<T> >(point2, point1);
assign(segment1, segment3);
BOOST_CHECK(segment1.p0 == point2);
BOOST_CHECK(segment1.p1 == point1);
BOOST_CHECK(!equivalence(segment1, segment2));
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test2, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
point_type point1(1, 2);
point_type point2(2, 4);
point_type point3(0, 0);
point_type point4(5, 10);
point_type point5(1, 3);
point_type point6(2, 3);
point_type point7(100, 201);
point_type point8(100, 200);
point_type point9(100, 199);
segment_type segment1 = construct<segment_type>(point1, point2);
segment_type segment2 = construct<segment_type>(point2, point1);
segment_type segment3 = construct<segment_type>(point1, point5);
BOOST_CHECK(orientation(segment1, point1) == 0);
BOOST_CHECK(orientation(segment1, point2) == 0);
BOOST_CHECK(orientation(segment1, point3) == 0);
BOOST_CHECK(orientation(segment1, point4) == 0);
BOOST_CHECK(orientation(segment1, point5) == 1);
BOOST_CHECK(orientation(segment2, point5) == -1);
BOOST_CHECK(orientation(segment1, point6) == -1);
BOOST_CHECK(orientation(segment2, point6) == 1);
BOOST_CHECK(orientation(segment1, point7) == 1);
BOOST_CHECK(orientation(segment2, point7) == -1);
BOOST_CHECK(orientation(segment1, point8) == 0);
BOOST_CHECK(orientation(segment1, point9) == -1);
BOOST_CHECK(orientation(segment2, point9) == 1);
BOOST_CHECK(orientation(segment3, point6) == -1);
BOOST_CHECK(orientation(segment3, point3) == 1);
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test3, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
segment_type segment1 = construct<segment_type>(
point_type(0, 0), point_type(1, 2));
segment_type segment2 = construct<segment_type>(
point_type(0, 0), point_type(2, 4));
segment_type segment3 = construct<segment_type>(
point_type(0, 0), point_type(2, 3));
segment_type segment4 = construct<segment_type>(
point_type(0, 0), point_type(2, 5));
segment_type segment5 = construct<segment_type>(
point_type(0, 2), point_type(2, 0));
BOOST_CHECK(orientation(segment1, segment2) == 0);
BOOST_CHECK(orientation(segment1, segment3) == -1);
BOOST_CHECK(orientation(segment3, segment1) == 1);
BOOST_CHECK(orientation(segment1, segment4) == 1);
BOOST_CHECK(orientation(segment4, segment1) == -1);
BOOST_CHECK(orientation(segment1, segment5) == -1);
BOOST_CHECK(orientation(segment5, segment1) == 1);
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test4, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
point_type point1(1, 2);
point_type point2(3, 6);
point_type point3(2, 4);
point_type point4(4, 8);
point_type point5(0, 0);
segment_type segment = construct<segment_type>(point1, point2);
BOOST_CHECK(contains(segment, point1, true));
BOOST_CHECK(contains(segment, point2, true));
BOOST_CHECK(!contains(segment, point1, false));
BOOST_CHECK(!contains(segment, point2, false));
BOOST_CHECK(contains(segment, point3, false));
BOOST_CHECK(!contains(segment, point4, true));
BOOST_CHECK(!contains(segment, point5, true));
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test5, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
point_type point1(0, 0);
point_type point2(10, 0);
point_type point3(5, 0);
point_type point4(-1, 0);
point_type point5(11, 0);
segment_type segment = construct<segment_type>(point1, point2);
BOOST_CHECK(contains(segment, point1, true));
BOOST_CHECK(contains(segment, point2, true));
BOOST_CHECK(!contains(segment, point1, false));
BOOST_CHECK(!contains(segment, point2, false));
BOOST_CHECK(contains(segment, point3, false));
BOOST_CHECK(!contains(segment, point4, true));
BOOST_CHECK(!contains(segment, point5, true));
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test6, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
point_type point1(0, 0);
point_type point2(1, 2);
point_type point3(2, 4);
point_type point4(3, 6);
point_type point5(4, 8);
point_type point6(5, 10);
segment_type segment1 = construct<segment_type>(point2, point5);
segment_type segment2 = construct<segment_type>(point3, point4);
segment_type segment3 = construct<segment_type>(point1, point3);
segment_type segment4 = construct<segment_type>(point4, point6);
BOOST_CHECK(contains(segment1, segment2, false));
BOOST_CHECK(!contains(segment2, segment1, true));
BOOST_CHECK(!contains(segment1, segment3, true));
BOOST_CHECK(!contains(segment1, segment4, true));
BOOST_CHECK(contains(segment1, segment1, true));
BOOST_CHECK(!contains(segment1, segment1, false));
}
template<typename T>
struct Transformer {
void scale(T& x, T& y) const {
x *= 2;
y *= 2;
}
void transform(T& x, T& y) const {
T tmp = x;
x = y;
y = tmp;
}
};
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test7, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
point_type point1(1, 2);
point_type point2(4, 6);
segment_type segment1 = construct<segment_type>(point1, point2);
scale_up(segment1, 3);
BOOST_CHECK(low(segment1) == point_type(3, 6));
BOOST_CHECK(high(segment1) == point_type(12, 18));
scale_down(segment1, 3);
BOOST_CHECK(low(segment1) == point1);
BOOST_CHECK(high(segment1) == point2);
BOOST_CHECK(length(segment1) == 5);
move(segment1, HORIZONTAL, 1);
move(segment1, VERTICAL, 2);
BOOST_CHECK(low(segment1) == point_type(2, 4));
BOOST_CHECK(high(segment1) == point_type(5, 8));
BOOST_CHECK(length(segment1) == 5);
convolve(segment1, point_type(1, 2));
BOOST_CHECK(low(segment1) == point_type(3, 6));
BOOST_CHECK(high(segment1) == point_type(6, 10));
deconvolve(segment1, point_type(2, 4));
BOOST_CHECK(low(segment1) == point1);
BOOST_CHECK(high(segment1) == point2);
scale(segment1, Transformer<T>());
BOOST_CHECK(low(segment1) == point_type(2, 4));
BOOST_CHECK(high(segment1) == point_type(8, 12));
transform(segment1, Transformer<T>());
BOOST_CHECK(low(segment1) == point_type(4, 2));
BOOST_CHECK(high(segment1) == point_type(12, 8));
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test8, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
segment_type segment1 = construct<segment_type>(
point_type(0, 0), point_type(1, 2));
segment_type segment2 = construct<segment_type>(
point_type(1, 2), point_type(2, 4));
segment_type segment3 = construct<segment_type>(
point_type(2, 4), point_type(0, 4));
segment_type segment4 = construct<segment_type>(
point_type(0, 4), point_type(0, 0));
BOOST_CHECK(abuts(segment1, segment2, HIGH));
BOOST_CHECK(abuts(segment2, segment3, HIGH));
BOOST_CHECK(abuts(segment3, segment4, HIGH));
BOOST_CHECK(abuts(segment4, segment1, HIGH));
BOOST_CHECK(!abuts(segment1, segment2, LOW));
BOOST_CHECK(!abuts(segment2, segment3, LOW));
BOOST_CHECK(!abuts(segment3, segment4, LOW));
BOOST_CHECK(!abuts(segment4, segment1, LOW));
BOOST_CHECK(abuts(segment2, segment1));
BOOST_CHECK(abuts(segment3, segment2));
BOOST_CHECK(abuts(segment4, segment3));
BOOST_CHECK(abuts(segment1, segment4));
BOOST_CHECK(!abuts(segment1, segment3));
BOOST_CHECK(!abuts(segment2, segment4));
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test9, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
segment_type segment1 = construct<segment_type>(
point_type(0, 0), point_type(2, 2));
segment_type segment2 = construct<segment_type>(
point_type(1, 1), point_type(3, 3));
segment_type segment3 = construct<segment_type>(
point_type(2, 2), point_type(-1, -1));
segment_type segment4 = construct<segment_type>(
point_type(1, 3), point_type(3, 1));
segment_type segment5 = construct<segment_type>(
point_type(2, 2), point_type(1, 3));
BOOST_CHECK(intersects(segment1, segment2, false));
BOOST_CHECK(intersects(segment1, segment2, true));
BOOST_CHECK(intersects(segment1, segment3, false));
BOOST_CHECK(intersects(segment1, segment3, true));
BOOST_CHECK(intersects(segment2, segment3, false));
BOOST_CHECK(intersects(segment2, segment3, true));
BOOST_CHECK(intersects(segment4, segment3, false));
BOOST_CHECK(intersects(segment4, segment3, true));
BOOST_CHECK(intersects(segment4, segment2, false));
BOOST_CHECK(intersects(segment4, segment2, true));
BOOST_CHECK(!intersects(segment3, segment5, false));
BOOST_CHECK(intersects(segment3, segment5, true));
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test10, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
segment_type segment1 = construct<segment_type>(
point_type(0, 0), point_type(0, 2));
segment_type segment2 = construct<segment_type>(
point_type(0, 1), point_type(0, 3));
segment_type segment3 = construct<segment_type>(
point_type(0, 1), point_type(0, 2));
segment_type segment4 = construct<segment_type>(
point_type(0, 2), point_type(0, 3));
segment_type segment5 = construct<segment_type>(
point_type(0, 2), point_type(2, 2));
segment_type segment6 = construct<segment_type>(
point_type(0, 1), point_type(1, 1));
BOOST_CHECK(intersects(segment1, segment1, false));
BOOST_CHECK(intersects(segment1, segment1, true));
BOOST_CHECK(intersects(segment1, segment2, false));
BOOST_CHECK(intersects(segment1, segment2, true));
BOOST_CHECK(intersects(segment1, segment3, false));
BOOST_CHECK(intersects(segment1, segment3, true));
BOOST_CHECK(intersects(segment2, segment3, false));
BOOST_CHECK(intersects(segment2, segment3, true));
BOOST_CHECK(!intersects(segment1, segment4, false));
BOOST_CHECK(intersects(segment1, segment4, true));
BOOST_CHECK(!intersects(segment1, segment5, false));
BOOST_CHECK(intersects(segment1, segment5, true));
BOOST_CHECK(intersects(segment1, segment6, false));
BOOST_CHECK(intersects(segment1, segment6, true));
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test11, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
point_type point1(1, 2);
point_type point2(7, 10);
segment_type segment1 = construct<segment_type>(point1, point2);
BOOST_CHECK(euclidean_distance(segment1, point1) == 0.0);
BOOST_CHECK(euclidean_distance(segment1, point2) == 0.0);
BOOST_CHECK(euclidean_distance(segment1, point_type(10, 14)) == 5.0);
BOOST_CHECK(euclidean_distance(segment1, point_type(-3, -1)) == 5.0);
BOOST_CHECK(euclidean_distance(segment1, point_type(0, 9)) == 5.0);
BOOST_CHECK(euclidean_distance(segment1, point_type(8, 3)) == 5.0);
}
BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test12, T, test_types) {
typedef point_data<T> point_type;
typedef Segment<T> segment_type;
segment_type segment1 = construct<segment_type>(
point_type(0, 0), point_type(3, 4));
segment_type segment2 = construct<segment_type>(
point_type(2, 0), point_type(0, 2));
segment_type segment3 = construct<segment_type>(
point_type(1, -7), point_type(10, 5));
segment_type segment4 = construct<segment_type>(
point_type(7, 7), point_type(10, 11));
BOOST_CHECK(euclidean_distance(segment1, segment2) == 0.0);
BOOST_CHECK(euclidean_distance(segment1, segment3) == 5.0);
BOOST_CHECK(euclidean_distance(segment1, segment4) == 5.0);
}