|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r78258 - in sandbox/gtl: boost/polygon doc libs/polygon/test
From: sydorchuk.andriy_at_[hidden]
Date: 2012-04-29 16:53:21
Author: asydorchuk
Date: 2012-04-29 16:53:15 EDT (Sun, 29 Apr 2012)
New Revision: 78258
URL: http://svn.boost.org/trac/boost/changeset/78258
Log:
Adding segment traits/data/concept tests.
Fixing segments distance methods.
Updating documentation.
Added:
sandbox/gtl/libs/polygon/test/polygon_segment_test.cpp (contents, props changed)
Text files modified:
sandbox/gtl/boost/polygon/segment_concept.hpp | 299 ++++++++++++++++++++-------------------
sandbox/gtl/boost/polygon/segment_data.hpp | 3
sandbox/gtl/boost/polygon/segment_traits.hpp | 17 -
sandbox/gtl/doc/gtl_segment_concept.htm | 33 +--
sandbox/gtl/libs/polygon/test/Jamfile.v2 | 1
5 files changed, 173 insertions(+), 180 deletions(-)
Modified: sandbox/gtl/boost/polygon/segment_concept.hpp
==============================================================================
--- sandbox/gtl/boost/polygon/segment_concept.hpp (original)
+++ sandbox/gtl/boost/polygon/segment_concept.hpp 2012-04-29 16:53:15 EDT (Sun, 29 Apr 2012)
@@ -207,83 +207,6 @@
get(segment1, HIGH) == get(segment2, HIGH);
}
- struct y_s_on_above_or_below : gtl_yes {};
-
- //-1 for below, 0 for on and 1 for above
- template <typename Segment, typename Point>
- typename enable_if<
- typename gtl_and_3<
- y_s_on_above_or_below,
- typename is_segment_concept<
- typename geometry_concept<Segment>::type
- >::type,
- typename is_point_concept<
- typename geometry_concept<Point>::type
- >::type
- >::type,
- bool
- >::type
- on_above_or_below(const Segment& segment, const Point& point) {
- typedef polygon_arbitrary_formation<
- typename segment_coordinate_type<Segment>::type
- > paf;
- typename paf::Point pt, l, h;
- assign(pt, point);
- assign(l, low(segment));
- assign(h, high(segment));
- return paf::on_above_or_below(pt, typename paf::half_edge(l, h));
- }
-
- struct y_s_contains : gtl_yes {};
-
- template <typename Segment, typename Point>
- typename enable_if<
- typename gtl_and_3<
- y_s_contains,
- typename is_segment_concept<
- typename geometry_concept<Segment>::type
- >::type,
- typename is_point_concept<
- typename geometry_concept<Point>::type
- >::type
- >::type,
- bool
- >::type
- contains(const Segment& segment, const Point& point, bool consider_touch = true ) {
- if (!on_above_or_below(segment, point)) {
- rectangle_data<typename segment_coordinate_type<Segment>::type> rect;
- set_points(rect, low(segment), high(segment));
- if (area(rect) == 0.0) {
- if (!consider_touch) {
- return !equivalence(point, low(segment)) &&
- !equivalence(point, high(segment));
- }
- }
- return contains(rect, point, consider_touch);
- }
- return false;
- }
-
- struct y_s_contains2 : gtl_yes {};
-
- template <typename Segment1, typename Segment2>
- typename enable_if<
- typename gtl_and_3<
- y_s_contains2,
- typename is_segment_concept<
- typename geometry_concept<Segment1>::type
- >::type,
- typename is_segment_concept<
- typename geometry_concept<Segment2>::type
- >::type
- >::type,
- bool
- >::type
- contains(const Segment1& segment1, const Segment2& segment2, bool consider_touch = true) {
- return contains(segment1, get(segment2, LOW), consider_touch) &&
- contains(segment1, get(segment2, HIGH), consider_touch);
- }
-
struct y_s_low : gtl_yes {};
template <typename Segment>
@@ -329,7 +252,7 @@
typename segment_point_type<Segment>::type
>::type
center(const Segment& segment) {
- return construct<typename segment_coordinate_type<Segment>::type>(
+ return construct<typename segment_point_type<Segment>::type>(
(x(high(segment)) + x(low(segment)))/2,
(y(high(segment)) + y(low(segment)))/2);
}
@@ -372,6 +295,83 @@
set(segment, HIGH, point);
}
+ struct y_s_on_above_or_below : gtl_yes {};
+
+ // -1 for below, 0 for on and 1 for above
+ template <typename Segment, typename Point>
+ typename enable_if<
+ typename gtl_and_3<
+ y_s_on_above_or_below,
+ typename is_segment_concept<
+ typename geometry_concept<Segment>::type
+ >::type,
+ typename is_point_concept<
+ typename geometry_concept<Point>::type
+ >::type
+ >::type,
+ int
+ >::type
+ on_above_or_below(const Segment& segment, const Point& point) {
+ typedef polygon_arbitrary_formation<
+ typename segment_coordinate_type<Segment>::type
+ > paf;
+ typename paf::Point pt, l, h;
+ assign(pt, point);
+ assign(l, low(segment));
+ assign(h, high(segment));
+ return paf::on_above_or_below(pt, typename paf::half_edge(l, h));
+ }
+
+ struct y_s_contains : gtl_yes {};
+
+ template <typename Segment, typename Point>
+ typename enable_if<
+ typename gtl_and_3<
+ y_s_contains,
+ typename is_segment_concept<
+ typename geometry_concept<Segment>::type
+ >::type,
+ typename is_point_concept<
+ typename geometry_concept<Point>::type
+ >::type
+ >::type,
+ bool
+ >::type
+ contains(const Segment& segment, const Point& point, bool consider_touch = true ) {
+ if (!on_above_or_below(segment, point)) {
+ rectangle_data<typename segment_coordinate_type<Segment>::type> rect;
+ set_points(rect, low(segment), high(segment));
+ if (area(rect) == 0.0) {
+ if (!consider_touch) {
+ return !equivalence(point, low(segment)) &&
+ !equivalence(point, high(segment));
+ }
+ }
+ return contains(rect, point, consider_touch);
+ }
+ return false;
+ }
+
+ struct y_s_contains2 : gtl_yes {};
+
+ template <typename Segment1, typename Segment2>
+ typename enable_if<
+ typename gtl_and_3<
+ y_s_contains2,
+ typename is_segment_concept<
+ typename geometry_concept<Segment1>::type
+ >::type,
+ typename is_segment_concept<
+ typename geometry_concept<Segment2>::type
+ >::type
+ >::type,
+ bool
+ >::type
+ contains(const Segment1& segment1, const Segment2& segment2, bool consider_touch = true) {
+ return contains(segment1, get(segment2, LOW), consider_touch) &&
+ contains(segment1, get(segment2, HIGH), consider_touch);
+ }
+
struct y_s_length : gtl_yes {};
template <typename Segment>
@@ -434,7 +434,7 @@
struct y_s_scale : gtl_yes {};
- template <typename Segment, typename scaling_type>
+ template <typename Segment, typename Scale>
typename enable_if<
typename gtl_and<
y_s_scale,
@@ -444,14 +444,13 @@
>::type,
Segment
>::type &
- scale(Segment& segment, scaling_type factor) {
+ scale(Segment& segment, const Scale& sc) {
typename segment_point_type<Segment>::type l = low(segment), h = high(segment);
- low(segment, scale(l, factor));
- high(segment, scale(h, factor));
+ low(segment, scale(l, sc));
+ high(segment, scale(h, sc));
return segment;
}
-
struct y_s_transform : gtl_yes {};
template <typename Segment, typename Transform>
@@ -464,10 +463,10 @@
>::type,
Segment
>::type &
- transform(Segment& segment, const Transform& val) {
+ transform(Segment& segment, const Transform& tr) {
typename segment_point_type<Segment>::type l = low(segment), h = high(segment);
- low(segment, transform(l, val));
- high(segment, transform(h, val));
+ low(segment, transform(l, tr));
+ high(segment, transform(h, tr));
return segment;
}
@@ -535,6 +534,40 @@
return segment;
}
+struct y_s_e_intersects : gtl_yes {};
+
+ template <typename Segment1, typename Segment2>
+ typename enable_if<
+ typename gtl_and_3<
+ y_s_e_intersects,
+ typename is_segment_concept<
+ typename geometry_concept<Segment1>::type
+ >::type,
+ typename is_segment_concept<
+ typename geometry_concept<Segment2>::type
+ >::type
+ >::type,
+ bool
+ >::type
+ intersects(const Segment1& segment1, const Segment2& segment2,
+ bool consider_touch = true) {
+ if (consider_touch) {
+ if (low(segment1) == low(segment2) || low(segment1) == high(segment2) ||
+ high(segment1) == low(segment2) || high(segment1) == high(segment2))
+ return true;
+ }
+ typedef polygon_arbitrary_formation<
+ typename segment_coordinate_type<Segment1>::type
+ > paf;
+ typename paf::Point l1, h1, l2, h2;
+ assign(l1, low(segment1));
+ assign(h1, high(segment1));
+ assign(l2, low(segment2));
+ assign(h2, high(segment2));
+ return paf::intersects(typename paf::half_edge(l1, h1),
+ typename paf::half_edge(l2, h2));
+ }
+
struct y_s_e_dist : gtl_yes {};
template <typename Segment, typename Point>
@@ -562,20 +595,18 @@
Unit B = Y - y1;
Unit C = x2 - x1;
Unit D = y2 - y1;
+ Unit param = (A * C + B * D);
Unit length_sq = C * C + D * D;
- Unit param = (A * C + B * D)/length_sq;
- if (param > 1.0) {
+ if (param > length_sq) {
return euclidean_distance(high(segment), point);
} else if (param < 0.0) {
return euclidean_distance(low(segment), point);
}
- Unit denom = sqrt(length_sq);
- if (denom == 0.0)
+ if (length_sq == 0.0)
return 0.0;
+ Unit denom = sqrt(length_sq);
Unit result = (A * D - C * B) / denom;
- if (result < 0.0)
- result *= -1;
- return result;
+ return (result < 0.0) ? -result : result;
}
struct y_s_e_dist2 : gtl_yes {};
@@ -594,53 +625,25 @@
typename segment_distance_type<Segment1>::type
>::type
euclidean_distance(const Segment1& segment1, const Segment2& segment2) {
+ if (intersects(segment1, segment2))
+ return 0.0;
typename segment_distance_type<Segment1>::type
result1 = euclidean_distance(segment1, low(segment2)),
- result2 = euclidean_distance(segment1, high(segment2));
- if (result2 < result1) return result2;
- return result1;
- }
-
- struct y_s_e_intersects : gtl_yes {};
-
- template <typename Segment1, typename Segment2>
- typename enable_if<
- typename gtl_and_3<
- y_s_e_intersects,
- typename is_segment_concept<
- typename geometry_concept<Segment1>::type
- >::type,
- typename is_segment_concept<
- typename geometry_concept<Segment2>::type
- >::type
- >::type,
- bool
- >::type
- intersects(const Segment1& segment1, const Segment2& segment2,
- bool consider_touch = true) {
- if (consider_touch) {
- if (low(segment1) == low(segment2) || low(segment1) == high(segment2) ||
- high(segment1) == low(segment2) || high(segment1) == high(segment2))
- return true;
- }
- typedef polygon_arbitrary_formation<
- typename segment_coordinate_type<Segment1>::type
- > paf;
- typename paf::Point l1, h1, l2, h2;
- assign(l1, low(segment1));
- assign(h1, high(segment1));
- assign(l2, low(segment2));
- assign(h2, high(segment2));
- return paf::intersects(typename paf::half_edge(l1, h1),
- typename paf::half_edge(l2, h2));
+ result2 = euclidean_distance(segment1, high(segment2)),
+ result3 = euclidean_distance(segment2, low(segment1)),
+ result4 = euclidean_distance(segment2, high(segment1));
+ typename segment_distance_type<Segment1>::type
+ subres1 = (result1 < result2) ? result1 : result2,
+ subres2 = (result3 < result4) ? result3 : result4;
+ return (subres1 < subres2) ? subres1 : subres2;
}
- struct y_s_e_bintersect : gtl_yes {};
+ struct y_s_abuts1 : gtl_yes {};
template <typename Segment1, typename Segment2>
typename enable_if<
typename gtl_and_3<
- y_s_e_bintersect,
+ y_s_abuts1,
typename is_segment_concept<
typename geometry_concept<Segment1>::type
>::type,
@@ -650,20 +653,17 @@
>::type,
bool
>::type
- boundaries_intersect(const Segment1& segment1, const Segment2& segment2,
- bool consider_touch = true) {
- return (contains(segment1, low(segment2), consider_touch) ||
- contains(segment1, high(segment2), consider_touch)) &&
- (contains(segment2, low(segment1), consider_touch) ||
- contains(segment2, high(segment1), consider_touch));
+ abuts(const Segment1& segment1, const Segment2& segment2, direction_1d dir) {
+ return dir.to_int() ? equivalence(low(segment2) , high(segment1)) :
+ equivalence(low(segment1) , high(segment2));
}
- struct y_s_abuts1 : gtl_yes {};
+ struct y_s_abuts2 : gtl_yes {};
template <typename Segment1, typename Segment2>
typename enable_if<
typename gtl_and_3<
- y_s_abuts1,
+ y_s_abuts2,
typename is_segment_concept<
typename geometry_concept<Segment1>::type
>::type,
@@ -673,17 +673,16 @@
>::type,
bool
>::type
- abuts(const Segment1& segment1, const Segment2& segment2, direction_1d dir) {
- return dir.to_int() ? equivalence(low(segment2) , high(segment1)) :
- equivalence(low(segment1) , high(segment2));
+ abuts(const Segment1& segment1, const Segment2& segment2) {
+ return abuts(segment1, segment2, HIGH) || abuts(segment1, segment2, LOW);
}
- struct y_s_abuts2 : gtl_yes {};
+ struct y_s_e_bintersect : gtl_yes {};
template <typename Segment1, typename Segment2>
typename enable_if<
typename gtl_and_3<
- y_s_abuts2,
+ y_s_e_bintersect,
typename is_segment_concept<
typename geometry_concept<Segment1>::type
>::type,
@@ -693,13 +692,17 @@
>::type,
bool
>::type
- abuts(const Segment1& segment1, const Segment2& segment2) {
- return abuts(segment1, segment2, HIGH) || abuts(segment1, segment2, LOW);
+ boundaries_intersect(const Segment1& segment1, const Segment2& segment2,
+ bool consider_touch = true) {
+ return (contains(segment1, low(segment2), consider_touch) ||
+ contains(segment1, high(segment2), consider_touch)) &&
+ (contains(segment2, low(segment1), consider_touch) ||
+ contains(segment2, high(segment1), consider_touch));
}
struct y_s_intersect : gtl_yes {};
- // set point to the intersection of segment and b
+ // Set point to the intersection of segment and b
template <typename Point, typename Segment1, typename Segment2>
typename enable_if<
typename gtl_and_4<
Modified: sandbox/gtl/boost/polygon/segment_data.hpp
==============================================================================
--- sandbox/gtl/boost/polygon/segment_data.hpp (original)
+++ sandbox/gtl/boost/polygon/segment_data.hpp 2012-04-29 16:53:15 EDT (Sun, 29 Apr 2012)
@@ -9,7 +9,6 @@
#define BOOST_POLYGON_SEGMENT_DATA_HPP
#include "isotropy.hpp"
-#include "point_data.hpp"
namespace boost { namespace polygon{
template <typename T>
@@ -60,7 +59,7 @@
inline point_type low() const { return points_[0]; }
inline segment_data& low(const point_type& point) {
- points_[0] = low;
+ points_[0] = point;
return *this;
}
Modified: sandbox/gtl/boost/polygon/segment_traits.hpp
==============================================================================
--- sandbox/gtl/boost/polygon/segment_traits.hpp (original)
+++ sandbox/gtl/boost/polygon/segment_traits.hpp 2012-04-29 16:53:15 EDT (Sun, 29 Apr 2012)
@@ -20,19 +20,14 @@
template <typename Segment>
struct segment_mutable_traits {
- template <typename Point>
- static inline void set(Segment& segment, direction_1d dir, const Point& value) {
- typename segment_traits<Segment>::point_type p1;
- assign(p1, value);
- segment.set(dir, p1);
+ typedef typename segment_traits<Segment>::point_type point_type;
+
+ static inline void set(Segment& segment, direction_1d dir, const point_type& point) {
+ segment.set(dir, point);
}
- template <typename Point1, typename Point2>
- static inline Segment construct(const Point1& low_value, const Point2& high_value) {
- typename segment_traits<Segment>::point_type p1, p2;
- assign(p1, low_value);
- assign(p2, high_value);
- return Segment(p1, p2);
+ static inline Segment construct(const point_type& low, const point_type& high) {
+ return Segment(low, high);
}
};
}
Modified: sandbox/gtl/doc/gtl_segment_concept.htm
==============================================================================
--- sandbox/gtl/doc/gtl_segment_concept.htm (original)
+++ sandbox/gtl/doc/gtl_segment_concept.htm 2012-04-29 16:53:15 EDT (Sun, 29 Apr 2012)
@@ -1,6 +1,5 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:(null)1="http://www.w3.org/TR/REC-html40" lang="en"><head>
-<!--
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:(null)1="http://www.w3.org/TR/REC-html40" lang="en"><head><!--
Copyright 2009-2010 Intel Corporation
license banner
--><title>Boost Polygon Library: Segment Concept</title>
@@ -8,6 +7,8 @@
+
+
@@ -119,24 +120,20 @@
<span style="font-family: Courier New,Courier,monospace;"> }</span><br style="font-family: Courier New,Courier,monospace;" />
<span style="font-family: Courier New,Courier,monospace;">};</span><br />
<br /><span style="font-family: Courier New,Courier,monospace;">template <typename Segment><br />
-struct segment_mutable_traits {<br />
- template <typename Point><br />
- static inline void set(Segment& segment, direction_1d dir, const Point& value) {<br />
- typename segment_traits<Segment>::point_type p1;<br />
- assign(p1, value);<br />
- segment.set(dir, p1);<br />
+struct segment_mutable_traits {</span></span></p>
+ <p><span style="font-family: Courier New,Courier,monospace;"><span style="font-family: Courier New,Courier,monospace;"> typedef typename segment_traits<Segment>::point_type point_type;<br />
+<br />
+ static inline void set(Segment& segment, direction_1d dir, const point_type& point) {<br />
+ segment.set(dir, p);<br />
}<br />
<br />
- template <typename Point1, typename Point2><br />
- static inline Segment construct(const Point1& low_value, const Point2& high_value) {<br />
- typename segment_traits<Segment>::point_type p1, p2;<br />
- assign(p1, low_value);<br />
- assign(p2, high_value);<br />
- return Segment(p1, p2);<br />
+ static inline Segment construct(const point_type& low, const point_type& high) {<br />
+ return Segment(low, high);<br />
}<br />
};<br />
</span><span style="font-family: Courier New,Courier,monospace;" /></span></p>
+
<p> Example code custom_segment.cpp
demonstrates how to map a user defined segment class to the library segment_concept.</p>
<h2>Functions</h2>
@@ -263,9 +260,8 @@
</tr>
<tr>
<td width="586"><font face="Courier New">template
-<typename </font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">, typename scaling_type><br />
- </font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">& <b>scale</b>(</font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">& </font><font face="Courier New">segment</font><font face="Courier New">,<br />
- const scaling_type& factor) </font></td>
+<typename </font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">, typename Scale><br />
+ </font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">& <b>scale</b>(</font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">& </font><font face="Courier New">segment</font><font face="Courier New">, const Scale& sc) </font></td>
<td>Calls
the scale member function of the scaling type on the low and high endpoint of
an object that is a model of segment and updates the segment with the
@@ -273,8 +269,7 @@
</tr>
<tr>
<td width="586"><font face="Courier New">template
-<typename </font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">, typename Transform><br /></font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">& <b>transform</b>(</font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">& segment,<br />
- const </font><font face="Courier New">Transform</font><font face="Courier New">& transform) </font></td>
+<typename </font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">, typename Transform><br /></font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">& <b>transform</b>(</font><span style="font-family: Courier New,Courier,monospace;">Segment</span><font face="Courier New">& segment, const </font><font face="Courier New">Transform</font><font face="Courier New">& tr) </font></td>
<td>Calls the transform member function of transform type
on the low and high endpoints of an object that is a model of segment and updates the segment with the transformed endpoints.</td>
</tr>
Modified: sandbox/gtl/libs/polygon/test/Jamfile.v2
==============================================================================
--- sandbox/gtl/libs/polygon/test/Jamfile.v2 (original)
+++ sandbox/gtl/libs/polygon/test/Jamfile.v2 2012-04-29 16:53:15 EDT (Sun, 29 Apr 2012)
@@ -18,6 +18,7 @@
alias "polygon-unit"
:
+ [ run polygon_segment_test.cpp ]
[ run gtl_boost_unit_test.cpp ]
;
Added: sandbox/gtl/libs/polygon/test/polygon_segment_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/gtl/libs/polygon/test/polygon_segment_test.cpp 2012-04-29 16:53:15 EDT (Sun, 29 Apr 2012)
@@ -0,0 +1,336 @@
+// 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/polygon.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 = 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 {
+ point_data<T> p0;
+ point_data<T> 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 point_data<T> point_type;
+
+ static inline void set(Segment<T>& segment, direction_1d dir, const point_type& point) {
+ if (dir.to_int()) {
+ segment.p1 = point;
+ } else {
+ segment.p0 = point;
+ }
+ }
+
+ static inline 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 segment = construct<segment_type>(point1, point2);
+
+ BOOST_CHECK(on_above_or_below(segment, point1) == 0);
+ BOOST_CHECK(on_above_or_below(segment, point2) == 0);
+ BOOST_CHECK(on_above_or_below(segment, point3) == 0);
+ BOOST_CHECK(on_above_or_below(segment, point4) == 0);
+ BOOST_CHECK(on_above_or_below(segment, point5) == 1);
+ BOOST_CHECK(on_above_or_below(segment, point6) == -1);
+ BOOST_CHECK(on_above_or_below(segment, point7) == 1);
+ BOOST_CHECK(on_above_or_below(segment, point8) == 0);
+ BOOST_CHECK(on_above_or_below(segment, point9) == -1);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test3, 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_test4, 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_test5, 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_test6, 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_test7, 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_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(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(intersects(segment1, segment2, false));
+ BOOST_CHECK(euclidean_distance(segment1, segment2) == 0.0);
+ BOOST_CHECK(!intersects(segment1, segment3, true));
+ BOOST_CHECK(euclidean_distance(segment1, segment3) == 5.0);
+ BOOST_CHECK(!intersects(segment1, segment4, true));
+ BOOST_CHECK(euclidean_distance(segment1, segment4) == 5.0);
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test9, T, test_types) {
+ typedef point_data<T> point_type;
+ typedef Segment<T> segment_type;
+
+}
+
+BOOST_AUTO_TEST_CASE_TEMPLATE(segment_concept_test10, T, test_types) {
+ typedef point_data<T> point_type;
+ typedef Segment<T> segment_type;
+
+}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk