stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,391 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2012 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)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
|
||||
#define BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
#include <boost/geometry/arithmetic/determinant.hpp>
|
||||
#include <boost/geometry/strategies/side_info.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/select_calculation_type.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
namespace policies { namespace relate
|
||||
{
|
||||
|
||||
struct direction_type
|
||||
{
|
||||
// NOTE: "char" will be replaced by enum in future version
|
||||
|
||||
inline direction_type(side_info const& s, char h,
|
||||
int ha, int hb,
|
||||
int da = 0, int db = 0,
|
||||
bool op = false)
|
||||
: how(h)
|
||||
, opposite(op)
|
||||
, how_a(ha)
|
||||
, how_b(hb)
|
||||
, dir_a(da)
|
||||
, dir_b(db)
|
||||
, sides(s)
|
||||
{
|
||||
arrival[0] = ha;
|
||||
arrival[1] = hb;
|
||||
}
|
||||
|
||||
inline direction_type(char h, bool op, int ha = 0, int hb = 0)
|
||||
: how(h)
|
||||
, opposite(op)
|
||||
, how_a(ha)
|
||||
, how_b(hb)
|
||||
, dir_a(0)
|
||||
, dir_b(0)
|
||||
{
|
||||
arrival[0] = ha;
|
||||
arrival[1] = hb;
|
||||
}
|
||||
|
||||
|
||||
// TODO: replace this
|
||||
// NOTE: "char" will be replaced by enum in future version
|
||||
// "How" is the intersection formed?
|
||||
char how;
|
||||
|
||||
// Is it opposite (for collinear/equal cases)
|
||||
bool opposite;
|
||||
|
||||
// Information on how A arrives at intersection, how B arrives at intersection
|
||||
// 1: arrives at intersection
|
||||
// -1: starts from intersection
|
||||
int how_a;
|
||||
int how_b;
|
||||
|
||||
// Direction: how is A positioned from B
|
||||
// 1: points left, seen from IP
|
||||
// -1: points right, seen from IP
|
||||
// In case of intersection: B's TO direction
|
||||
// In case that B's TO direction is at A: B's from direction
|
||||
// In collinear cases: it is 0
|
||||
int dir_a; // Direction of A-s TO from IP
|
||||
int dir_b; // Direction of B-s TO from IP
|
||||
|
||||
// New information
|
||||
side_info sides;
|
||||
// THIS IS EQUAL TO arrival_a, arrival_b - they probably can go now we have robust fractions
|
||||
int arrival[2]; // 1=arrival, -1=departure, 0=neutral; == how_a//how_b
|
||||
|
||||
|
||||
// About arrival[0] (== arrival of a2 w.r.t. b) for COLLINEAR cases
|
||||
// Arrival 1: a1--------->a2 (a arrives within b)
|
||||
// b1----->b2
|
||||
|
||||
// Arrival 1: (a in b)
|
||||
//
|
||||
|
||||
|
||||
// Arrival -1: a1--------->a2 (a does not arrive within b)
|
||||
// b1----->b2
|
||||
|
||||
// Arrival -1: (b in a) a_1-------------a_2
|
||||
// b_1---b_2
|
||||
|
||||
// Arrival 0: a1------->a2 (a arrives at TO-border of b)
|
||||
// b1--->b2
|
||||
|
||||
};
|
||||
|
||||
struct segments_direction
|
||||
{
|
||||
typedef direction_type return_type;
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment1,
|
||||
typename Segment2,
|
||||
typename SegmentIntersectionInfo
|
||||
>
|
||||
static inline return_type segments_crosses(side_info const& sides,
|
||||
SegmentIntersectionInfo const& ,
|
||||
Segment1 const& , Segment2 const& )
|
||||
{
|
||||
bool const ra0 = sides.get<0,0>() == 0;
|
||||
bool const ra1 = sides.get<0,1>() == 0;
|
||||
bool const rb0 = sides.get<1,0>() == 0;
|
||||
bool const rb1 = sides.get<1,1>() == 0;
|
||||
|
||||
return
|
||||
// opposite and same starting point (FROM)
|
||||
ra0 && rb0 ? calculate_side<1>(sides, 'f', -1, -1)
|
||||
|
||||
// opposite and point to each other (TO)
|
||||
: ra1 && rb1 ? calculate_side<0>(sides, 't', 1, 1)
|
||||
|
||||
// not opposite, forming an angle, first a then b,
|
||||
// directed either both left, or both right
|
||||
// Check side of B2 from A. This is not calculated before
|
||||
: ra1 && rb0 ? angle<1>(sides, 'a', 1, -1)
|
||||
|
||||
// not opposite, forming a angle, first b then a,
|
||||
// directed either both left, or both right
|
||||
: ra0 && rb1 ? angle<0>(sides, 'a', -1, 1)
|
||||
|
||||
// b starts from interior of a
|
||||
: rb0 ? starts_from_middle(sides, 'B', 0, -1)
|
||||
|
||||
// a starts from interior of b (#39)
|
||||
: ra0 ? starts_from_middle(sides, 'A', -1, 0)
|
||||
|
||||
// b ends at interior of a, calculate direction of A from IP
|
||||
: rb1 ? b_ends_at_middle(sides)
|
||||
|
||||
// a ends at interior of b
|
||||
: ra1 ? a_ends_at_middle(sides)
|
||||
|
||||
// normal intersection
|
||||
: calculate_side<1>(sides, 'i', -1, -1)
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Ratio>
|
||||
static inline int arrival_value(Ratio const& r_from, Ratio const& r_to)
|
||||
{
|
||||
// a1--------->a2
|
||||
// b1----->b2
|
||||
// a departs: -1
|
||||
|
||||
// a1--------->a2
|
||||
// b1----->b2
|
||||
// a arrives: 1
|
||||
|
||||
// a1--------->a2
|
||||
// b1----->b2
|
||||
// both arrive there -> r-to = 1/1, or 0/1 (on_segment)
|
||||
|
||||
// First check the TO (for arrival), then FROM (for departure)
|
||||
return r_to.in_segment() ? 1
|
||||
: r_to.on_segment() ? 0
|
||||
: r_from.on_segment() ? -1
|
||||
: -1
|
||||
;
|
||||
}
|
||||
|
||||
template <typename Ratio>
|
||||
static inline void analyze(Ratio const& r,
|
||||
int& in_segment_count,
|
||||
int& on_end_count,
|
||||
int& outside_segment_count)
|
||||
{
|
||||
if (r.on_end())
|
||||
{
|
||||
on_end_count++;
|
||||
}
|
||||
else if (r.in_segment())
|
||||
{
|
||||
in_segment_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
outside_segment_count++;
|
||||
}
|
||||
}
|
||||
|
||||
static inline int arrival_from_position_value(int /*v_from*/, int v_to)
|
||||
{
|
||||
return v_to == 2 ? 1
|
||||
: v_to == 1 || v_to == 3 ? 0
|
||||
//: v_from >= 1 && v_from <= 3 ? -1
|
||||
: -1;
|
||||
|
||||
// NOTE: this should be an equivalent of the above for the other order
|
||||
/* (v_from < 3 && v_to > 3) || (v_from > 3 && v_to < 3) ? 1
|
||||
: v_from == 3 || v_to == 3 ? 0
|
||||
: -1;*/
|
||||
}
|
||||
|
||||
static inline void analyse_position_value(int pos_val,
|
||||
int & in_segment_count,
|
||||
int & on_end_count,
|
||||
int & outside_segment_count)
|
||||
{
|
||||
if ( pos_val == 1 || pos_val == 3 )
|
||||
{
|
||||
on_end_count++;
|
||||
}
|
||||
else if ( pos_val == 2 )
|
||||
{
|
||||
in_segment_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
outside_segment_count++;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Segment1, typename Segment2, typename Ratio>
|
||||
static inline return_type segments_collinear(
|
||||
Segment1 const& , Segment2 const& , bool opposite,
|
||||
int a1_wrt_b, int a2_wrt_b, int b1_wrt_a, int b2_wrt_a,
|
||||
Ratio const& /*ra_from_wrt_b*/, Ratio const& /*ra_to_wrt_b*/,
|
||||
Ratio const& /*rb_from_wrt_a*/, Ratio const& /*rb_to_wrt_a*/)
|
||||
{
|
||||
return_type r('c', opposite);
|
||||
|
||||
// IMPORTANT: the order of conditions is different as in intersection_points.hpp
|
||||
// We assign A in 0 and B in 1
|
||||
r.arrival[0] = arrival_from_position_value(a1_wrt_b, a2_wrt_b);
|
||||
r.arrival[1] = arrival_from_position_value(b1_wrt_a, b2_wrt_a);
|
||||
|
||||
// Analyse them
|
||||
int a_in_segment_count = 0;
|
||||
int a_on_end_count = 0;
|
||||
int a_outside_segment_count = 0;
|
||||
int b_in_segment_count = 0;
|
||||
int b_on_end_count = 0;
|
||||
int b_outside_segment_count = 0;
|
||||
analyse_position_value(a1_wrt_b,
|
||||
a_in_segment_count, a_on_end_count, a_outside_segment_count);
|
||||
analyse_position_value(a2_wrt_b,
|
||||
a_in_segment_count, a_on_end_count, a_outside_segment_count);
|
||||
analyse_position_value(b1_wrt_a,
|
||||
b_in_segment_count, b_on_end_count, b_outside_segment_count);
|
||||
analyse_position_value(b2_wrt_a,
|
||||
b_in_segment_count, b_on_end_count, b_outside_segment_count);
|
||||
|
||||
if (a_on_end_count == 1
|
||||
&& b_on_end_count == 1
|
||||
&& a_outside_segment_count == 1
|
||||
&& b_outside_segment_count == 1)
|
||||
{
|
||||
// This is a collinear touch
|
||||
// --------> A (or B)
|
||||
// <---------- B (or A)
|
||||
// We adapt the "how"
|
||||
// TODO: how was to be refactored anyway,
|
||||
if (! opposite)
|
||||
{
|
||||
r.how = 'a';
|
||||
}
|
||||
else
|
||||
{
|
||||
r.how = r.arrival[0] == 0 ? 't' : 'f';
|
||||
}
|
||||
}
|
||||
else if (a_on_end_count == 2
|
||||
&& b_on_end_count == 2)
|
||||
{
|
||||
r.how = 'e';
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
template <typename Segment>
|
||||
static inline return_type degenerate(Segment const& , bool)
|
||||
{
|
||||
return return_type('0', false);
|
||||
}
|
||||
|
||||
template <typename Segment, typename Ratio>
|
||||
static inline return_type one_degenerate(Segment const& ,
|
||||
Ratio const& ,
|
||||
bool)
|
||||
{
|
||||
// To be decided
|
||||
return return_type('0', false);
|
||||
}
|
||||
|
||||
static inline return_type disjoint()
|
||||
{
|
||||
return return_type('d', false);
|
||||
}
|
||||
|
||||
static inline return_type error(std::string const&)
|
||||
{
|
||||
// Return "E" to denote error
|
||||
// This will throw an error in get_turn_info
|
||||
// TODO: change to enum or similar
|
||||
return return_type('E', false);
|
||||
}
|
||||
|
||||
private :
|
||||
|
||||
template <std::size_t I>
|
||||
static inline return_type calculate_side(side_info const& sides,
|
||||
char how, int how_a, int how_b)
|
||||
{
|
||||
int const dir = sides.get<1, I>() == 1 ? 1 : -1;
|
||||
return return_type(sides, how, how_a, how_b, -dir, dir);
|
||||
}
|
||||
|
||||
template <std::size_t I>
|
||||
static inline return_type angle(side_info const& sides,
|
||||
char how, int how_a, int how_b)
|
||||
{
|
||||
int const dir = sides.get<1, I>() == 1 ? 1 : -1;
|
||||
return return_type(sides, how, how_a, how_b, dir, dir);
|
||||
}
|
||||
|
||||
|
||||
static inline return_type starts_from_middle(side_info const& sides,
|
||||
char which,
|
||||
int how_a, int how_b)
|
||||
{
|
||||
// Calculate ARROW of b segment w.r.t. s1
|
||||
int dir = sides.get<1, 1>() == 1 ? 1 : -1;
|
||||
|
||||
// From other perspective, then reverse
|
||||
bool const is_a = which == 'A';
|
||||
if (is_a)
|
||||
{
|
||||
dir = -dir;
|
||||
}
|
||||
|
||||
return return_type(sides, 's',
|
||||
how_a,
|
||||
how_b,
|
||||
is_a ? dir : -dir,
|
||||
! is_a ? dir : -dir);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// To be harmonized
|
||||
static inline return_type a_ends_at_middle(side_info const& sides)
|
||||
{
|
||||
// Ending at the middle, one ARRIVES, the other one is NEUTRAL
|
||||
// (because it both "arrives" and "departs" there)
|
||||
int const dir = sides.get<1, 1>() == 1 ? 1 : -1;
|
||||
return return_type(sides, 'm', 1, 0, dir, dir);
|
||||
}
|
||||
|
||||
|
||||
static inline return_type b_ends_at_middle(side_info const& sides)
|
||||
{
|
||||
int const dir = sides.get<0, 1>() == 1 ? 1 : -1;
|
||||
return return_type(sides, 'm', 0, 1, dir, dir);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}} // namespace policies::relate
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_GEOMETRY_POLICIES_RELATE_DIRECTION_HPP
|
||||
Reference in New Issue
Block a user