g4tools  5.4.0
geom2
Go to the documentation of this file.
1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
2 // See the file tools.license for terms.
3 
4 #ifndef tools_geom2
5 #define tools_geom2
6 
7 #include <vector>
8 #include <cstddef>
9 
10 namespace tools {
11 
12 template <class VEC2>
13 inline double is_left(const VEC2& P0,const VEC2& P1,const VEC2& P2){
14  return ( (P1.v0() - P0.v0()) * (P2.v1() - P0.v1())
15  - (P2.v0() - P0.v0()) * (P1.v1() - P0.v1()) );
16 }
17 
18 template <class VEC2>
19 inline bool is_inside(const VEC2& a_P,const std::vector<VEC2>& a_V) {
20  // V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
21 
22  // From :
23  // http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
24  // Copyright 2001, softSurfer (www.softsurfer.com)
25  // This code may be freely used and modified for any purpose
26  // providing that this copyright notice is included with it.
27  // SoftSurfer makes no warranty for this code, and cannot be held
28  // liable for any real or imagined damage resulting from its use.
29  // Users of this code must verify correctness for their application.
30 
31  size_t n = a_V.size()-1;
32 
33  int wn = 0; // the winding number counter
34 
35  // loop through all edges of the polygon
36  for (size_t i=0; i<n; i++) { // edge from V[i] to V[i+1]
37  if (a_V[i].v1() <= a_P.v1()) { // start y <= P[1]
38  if (a_V[i+1].v1() > a_P.v1()) // an upward crossing
39  if (is_left( a_V[i], a_V[i+1], a_P) > 0) // P left of edge
40  ++wn; // have a valid up intersect
41  } else { // start y > P[1] (no test needed)
42  if (a_V[i+1].v1() <= a_P.v1()) // a downward crossing
43  if (is_left( a_V[i], a_V[i+1], a_P) < 0) // P right of edge
44  --wn; // have a valid down intersect
45  }
46  }
47 
48  return ((wn!=0)?true:false);
49 }
50 
51 // the same done with std::pair.
52 
53 template <class T>
54 inline double is_left(const std::pair<T,T>& P0,const std::pair<T,T>& P1,const std::pair<T,T>& P2){
55  return ( (P1.first - P0.first) * (P2.second - P0.second)
56  - (P2.first - P0.first) * (P1.second - P0.second) );
57 }
58 
59 template <class T>
60 inline bool inside(const std::pair<T,T>& a_P,const std::vector< std::pair<T,T> >& a_V) {
61  // V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
62 
63  // From :
64  // http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
65  // Copyright 2001, softSurfer (www.softsurfer.com)
66  // This code may be freely used and modified for any purpose
67  // providing that this copyright notice is included with it.
68  // SoftSurfer makes no warranty for this code, and cannot be held
69  // liable for any real or imagined damage resulting from its use.
70  // Users of this code must verify correctness for their application.
71 
72  size_t n = a_V.size()-1;
73 
74  int wn = 0; // the winding number counter
75 
76  // loop through all edges of the polygon
77  for (size_t i=0; i<n; i++) { // edge from V[i] to V[i+1]
78  if (a_V[i].second <= a_P.second) { // start y <= P[1]
79  if (a_V[i+1].second > a_P.second) // an upward crossing
80  if (is_left( a_V[i], a_V[i+1], a_P) > 0) // P left of edge
81  ++wn; // have a valid up intersect
82  } else { // start y > P[1] (no test needed)
83  if (a_V[i+1].second <= a_P.second) // a downward crossing
84  if (is_left( a_V[i], a_V[i+1], a_P) < 0) // P right of edge
85  --wn; // have a valid down intersect
86  }
87  }
88 
89  return ((wn!=0)?true:false);
90 }
91 
92 template <class VEC2>
93 inline bool intersect(const VEC2& P1,const VEC2& Q1,const VEC2& P2,const VEC2& Q2,VEC2& a_out) {
94  // (P1,Q1) first line, (P2,Q2) second line and a_out intersection.
95  // return false if no intersection. (For exa, parallel lines).
96 
97  // P1+(Q1-P1)*r = P2+(Q2-P2)*s
98  // (Q1-P1)*r - (Q2-P2)*s = P2-P1
99  // r*(Q1-P1).v0 - s*(Q2-P2).v0 = (P2-P1).v0 //x
100  // r*(Q1-P1).v1 - s*(Q2-P2).v1 = (P2-P1).v1 //y
101 
102  // a*r + b*s = c
103  // d*r + e*s = f
104 
105  // r = (c*e-f*b)/(a*e-d*b)
106  // s = (a*f-d*c)/(a*e-d*b)
107 
108  typedef typename VEC2::elem_t T;
109  VEC2 A = Q1-P1;
110  VEC2 B = P2-Q2;
111  VEC2 C = P2-P1;
112 
113  T a = A.v0();
114  T b = B.v0();
115  T c = C.v0();
116  T d = A.v1();
117  T e = B.v1();
118  T f = C.v1();
119 
120  T det = a*e-d*b;
121  if(det==T()) return false;
122 
123  T r = (c*e-f*b)/det;
124 
125  a_out = P1+A*r;
126  return true;
127 }
128 
129 }
130 
131 #endif
tools::is_left
double is_left(const VEC2 &P0, const VEC2 &P1, const VEC2 &P2)
Definition: geom2:13
tools::intersect
bool intersect(const VEC2 &P1, const VEC2 &Q1, const VEC2 &P2, const VEC2 &Q2, VEC2 &a_out)
Definition: geom2:93
tools
inlined C code : ///////////////////////////////////
Definition: aida_ntuple:26
tools::inside
bool inside(const std::pair< T, T > &a_P, const std::vector< std::pair< T, T > > &a_V)
Definition: geom2:60
tools::is_inside
bool is_inside(const VEC2 &a_P, const std::vector< VEC2 > &a_V)
Definition: geom2:19