1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2018-2019 Barend Gehrels, Amsterdam, the Netherlands.
6 // This file was modified by Oracle on 2019.
7 // Modifications copyright (c) 2019, Oracle and/or its affiliates.
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 // Use, modification and distribution is subject to the Boost Software License,
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
12 // http://www.boost.org/LICENSE_1_0.txt)
14 #include <geometry_test_common.hpp>
16 #include <boost/geometry/arithmetic/infinite_line_functions.hpp>
17 #include <boost/geometry/geometries/infinite_line.hpp>
18 #include <boost/geometry/algorithms/detail/make/make.hpp>
19 #include <boost/geometry/geometries/point.hpp>
20 #include <boost/geometry/io/wkt/wkt.hpp>
24 // Boost.Test does not support BOOST_CHECK_CLOSE for integral types
26 bool is_small(T const& value)
28 static long double const epsilon = 1.0e-5;
29 return bg::math::abs(value) < epsilon;
33 template <typename T, typename C>
34 void verify_point_on_line(bg::model::infinite_line<T> const& line,
35 C const& x, C const& y)
37 BOOST_CHECK_MESSAGE(is_small(line.a * x + line.b * y + line.c),
38 "Point is not located on the line");
42 void test_side_value()
44 typedef bg::model::infinite_line<T> line_type;
46 // Horizontal line going right
47 line_type line = bg::detail::make::make_infinite_line<T>(0, 0, 10, 0);
49 // Point above (= on left side)
50 T d = bg::arithmetic::side_value(line, 5, 5);
51 BOOST_CHECK_MESSAGE(d > 0, "point not on left side");
53 // Point below (= on right side)
54 d = bg::arithmetic::side_value(line, 5, -5);
55 BOOST_CHECK_MESSAGE(d < 0, "point not on right side");
57 // Diagonal not through origin, from right (down) to left (up)
58 line = bg::detail::make::make_infinite_line<T>(5, 2, -7, 10);
59 d = bg::arithmetic::side_value(line, 5, 2);
60 BOOST_CHECK_MESSAGE(is_small(d), "point not on line");
61 d = bg::arithmetic::side_value(line, -7, 10);
62 BOOST_CHECK_MESSAGE(is_small(d), "point not on line");
64 // vector is (-12, 8), move (-3,2) on the line from (5,2)
65 d = bg::arithmetic::side_value(line, 2, 4);
66 BOOST_CHECK_MESSAGE(is_small(d), "point not on line");
68 // Go perpendicular (2,3) from (2,4) up, so right of the line (negative)
69 d = bg::arithmetic::side_value(line, 4, 7);
70 BOOST_CHECK_MESSAGE(d < 0, "point not on right side");
72 // Go perpendicular (2,3) from (2,4) down, so left of the line (positive)
73 d = bg::arithmetic::side_value(line, 0, 1);
74 BOOST_CHECK_MESSAGE(d > 0, "point not on left side");
79 void test_get_intersection()
81 typedef bg::model::infinite_line<T> line_type;
83 // Diagonal lines (first is same as in distance measure,
84 // second is perpendicular and used there for distance measures)
85 line_type p = bg::detail::make::make_infinite_line<T>(5, 2, -7, 10);
86 line_type q = bg::detail::make::make_infinite_line<T>(4, 7, 0, 1);
88 typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
90 BOOST_CHECK(bg::arithmetic::intersection_point(p, q, ip));
92 BOOST_CHECK_MESSAGE(is_small(bg::get<0>(ip) - 2), "x-coordinate wrong");
93 BOOST_CHECK_MESSAGE(is_small(bg::get<1>(ip) - 4), "y-coordinate wrong");
95 verify_point_on_line(p, bg::get<0>(ip), bg::get<1>(ip));
96 verify_point_on_line(q, bg::get<0>(ip), bg::get<1>(ip));
100 void test_same_direction()
102 bg::model::infinite_line<T> p, q;
104 // Exactly opposite, diagonal
105 p = bg::detail::make::make_infinite_line<T>(2, 1, 12, 11);
106 q = bg::detail::make::make_infinite_line<T>(12, 11, 2, 1);
107 BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
109 // Exactly opposite, horizontal
110 p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 0);
111 q = bg::detail::make::make_infinite_line<T>(10, 0, 0, 0);
112 BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
114 // Exactly opposite, vertical
115 p = bg::detail::make::make_infinite_line<T>(0, 0, 0, 10);
116 q = bg::detail::make::make_infinite_line<T>(0, 10, 0, 0);
117 BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
119 // Exactly equal, diagonal
120 p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
121 q = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
122 BOOST_CHECK(bg::arithmetic::similar_direction(p, q));
124 // Exactly equal, horizontal
125 p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 0);
126 q = bg::detail::make::make_infinite_line<T>(0, 0, 10, 0);
127 BOOST_CHECK(bg::arithmetic::similar_direction(p, q));
129 // Exactly equal, vertical
130 p = bg::detail::make::make_infinite_line<T>(0, 0, 0, 10);
131 q = bg::detail::make::make_infinite_line<T>(0, 0, 0, 10);
132 BOOST_CHECK(bg::arithmetic::similar_direction(p, q));
134 // Coming together, diagonal
135 p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
136 q = bg::detail::make::make_infinite_line<T>(20, 20, 10, 10);
137 BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
139 // Leaving from common point, diagonal
140 p = bg::detail::make::make_infinite_line<T>(10, 10, 0, 0);
141 q = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
142 BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
144 // Continuing each other, diagonal
145 p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
146 q = bg::detail::make::make_infinite_line<T>(10, 10, 20, 20);
147 BOOST_CHECK(bg::arithmetic::similar_direction(p, q));
149 // (Nearly) perpendicular
150 p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
151 q = bg::detail::make::make_infinite_line<T>(0, 0, -10, 10);
152 BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
155 p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
156 q = bg::detail::make::make_infinite_line<T>(0, 0, 0, 10);
157 BOOST_CHECK(bg::arithmetic::similar_direction(p, q));
159 // a bit more than 45 deg
160 p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
161 q = bg::detail::make::make_infinite_line<T>(0, 0, -1, 10);
162 BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
165 p = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
166 q = bg::detail::make::make_infinite_line<T>(0, 0, -10, 0);
167 BOOST_CHECK(! bg::arithmetic::similar_direction(p, q));
170 template <typename T>
171 void test_degenerate()
173 typedef bg::model::infinite_line<T> line_type;
175 line_type line = bg::detail::make::make_infinite_line<T>(0, 0, 10, 0);
176 BOOST_CHECK(! bg::arithmetic::is_degenerate(line));
178 line = bg::detail::make::make_infinite_line<T>(0, 0, 0, 10);
179 BOOST_CHECK(! bg::arithmetic::is_degenerate(line));
181 line = bg::detail::make::make_infinite_line<T>(0, 0, 10, 10);
182 BOOST_CHECK(! bg::arithmetic::is_degenerate(line));
184 line = bg::detail::make::make_infinite_line<T>(0, 0, 0, 0);
185 BOOST_CHECK(bg::arithmetic::is_degenerate(line));
189 template <typename T>
192 test_side_value<T>();
193 test_get_intersection<T>();
194 test_same_direction<T>();
195 test_degenerate<T>();
198 int test_main(int, char* [])
201 test_all<long double>();