File: infinite_line_functions.cpp

package info (click to toggle)
boost1.74 1.74.0%2Bds1-21
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 463,588 kB
  • sloc: cpp: 3,338,117; xml: 131,293; python: 33,088; ansic: 14,292; asm: 4,038; sh: 3,353; makefile: 1,193; perl: 1,036; yacc: 478; php: 212; ruby: 102; lisp: 24; sql: 13; csh: 6
file content (133 lines) | stat: -rwxr-xr-x 4,442 bytes parent folder | download | duplicates (13)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Unit Test

// Copyright (c) 2018-2019 Barend Gehrels, Amsterdam, the Netherlands.

// This file was modified by Oracle on 2019, 2020.
// Modifications copyright (c) 2019, 2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle

// 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/arithmetic/infinite_line_functions.hpp>
#include <boost/geometry/geometries/infinite_line.hpp>
#include <boost/geometry/algorithms/detail/make/make.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>

namespace
{
    // Boost.Test does not support BOOST_CHECK_CLOSE for integral types
    template <typename T>
    bool is_small(T const& value)
    {
        static long double const epsilon = 1.0e-5;
        return bg::math::abs(value) < epsilon;
    }
}

template <typename T, typename C>
void verify_point_on_line(bg::model::infinite_line<T> const& line,
                          C const& x, C const& y)
{
    BOOST_CHECK_MESSAGE(is_small(line.a * x + line.b * y + line.c),
                        "Point is not located on the line");
}

template <typename T>
void test_side_value()
{
    typedef bg::model::infinite_line<T> line_type;

    // Horizontal line going right
    line_type line = bg::detail::make::make_infinite_line<T>(0, 0, 10, 0);

    // Point above (= on left side)
    T d = bg::arithmetic::side_value(line, 5, 5);
    BOOST_CHECK_MESSAGE(d > 0, "point not on left side");

    // Point below (= on right side)
    d = bg::arithmetic::side_value(line, 5, -5);
    BOOST_CHECK_MESSAGE(d < 0, "point not on right side");

    // Diagonal not through origin, from right (down) to left (up)
    line = bg::detail::make::make_infinite_line<T>(5, 2, -7, 10);
    d = bg::arithmetic::side_value(line, 5, 2);
    BOOST_CHECK_MESSAGE(is_small(d), "point not on line");
    d = bg::arithmetic::side_value(line, -7, 10);
    BOOST_CHECK_MESSAGE(is_small(d), "point not on line");

    // vector is (-12, 8), move (-3,2) on the line from (5,2)
    d = bg::arithmetic::side_value(line, 2, 4);
    BOOST_CHECK_MESSAGE(is_small(d), "point not on line");

    // Go perpendicular (2,3) from (2,4) up, so right of the line (negative)
    d = bg::arithmetic::side_value(line, 4, 7);
    BOOST_CHECK_MESSAGE(d < 0, "point not on right side");

    // Go perpendicular (2,3) from (2,4) down, so left of the line (positive)
    d = bg::arithmetic::side_value(line, 0, 1);
    BOOST_CHECK_MESSAGE(d > 0, "point not on left side");
}


template <typename T>
void test_get_intersection()
{
    typedef bg::model::infinite_line<T> line_type;

    // Diagonal lines (first is same as in distance measure,
    // second is perpendicular and used there for distance measures)
    line_type p = bg::detail::make::make_infinite_line<T>(5, 2, -7, 10);
    line_type q = bg::detail::make::make_infinite_line<T>(4, 7, 0, 1);

    typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
    point_type ip;
    BOOST_CHECK(bg::arithmetic::intersection_point(p, q, ip));

    BOOST_CHECK_MESSAGE(is_small(bg::get<0>(ip) - 2), "x-coordinate wrong");
    BOOST_CHECK_MESSAGE(is_small(bg::get<1>(ip) - 4), "y-coordinate wrong");

    verify_point_on_line(p, bg::get<0>(ip), bg::get<1>(ip));
    verify_point_on_line(q, bg::get<0>(ip), bg::get<1>(ip));
}

template <typename T>
void test_degenerate()
{
    typedef bg::model::infinite_line<T> line_type;

    line_type line = bg::detail::make::make_infinite_line<T>(0, 0, 10, 0);
    BOOST_CHECK(! bg::arithmetic::is_degenerate(line));

    line = bg::detail::make::make_infinite_line<T>(0, 0, 0, 10);
    BOOST_CHECK(! bg::arithmetic::is_degenerate(line));

    line = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
    BOOST_CHECK(! bg::arithmetic::is_degenerate(line));

    line = bg::detail::make::make_infinite_line<T>(0, 0, 0, 0);
    BOOST_CHECK(bg::arithmetic::is_degenerate(line));
}


template <typename T>
void test_all()
{
    test_side_value<T>();
    test_get_intersection<T>();
    test_degenerate<T>();
}

int test_main(int, char* [])
{
    test_all<double>();
    test_all<long double>();
    test_all<float>();
    test_all<int>();
    return 0;
}