Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/lina/geom2 is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_geom2
0005 #define tools_geom2
0006 
0007 #include <vector>
0008 #include <cstddef>
0009 
0010 namespace tools {
0011 
0012 template <class VEC2>
0013 inline double is_left(const VEC2& P0,const VEC2& P1,const VEC2& P2){
0014   return ( (P1.v0() - P0.v0()) * (P2.v1() - P0.v1())
0015          - (P2.v0() - P0.v0()) * (P1.v1() - P0.v1()) );
0016 }
0017 
0018 template <class VEC2>
0019 inline bool is_inside(const VEC2& a_P,const std::vector<VEC2>& a_V) {
0020   // V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
0021 
0022   // From :
0023   //   http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
0024   // Copyright 2001, softSurfer (www.softsurfer.com)
0025   // This code may be freely used and modified for any purpose
0026   // providing that this copyright notice is included with it.
0027   // SoftSurfer makes no warranty for this code, and cannot be held
0028   // liable for any real or imagined damage resulting from its use.
0029   // Users of this code must verify correctness for their application.
0030 
0031   size_t n = a_V.size()-1;
0032 
0033   int    wn = 0;    // the winding number counter
0034 
0035   // loop through all edges of the polygon
0036   for (size_t i=0; i<n; i++) {   // edge from V[i] to V[i+1]
0037     if (a_V[i].v1() <= a_P.v1()) {         // start y <= P[1]
0038       if (a_V[i+1].v1() > a_P.v1())      // an upward crossing
0039         if (is_left( a_V[i], a_V[i+1], a_P) > 0)  // P left of edge
0040           ++wn;            // have a valid up intersect
0041     } else {                       // start y > P[1] (no test needed)
0042       if (a_V[i+1].v1() <= a_P.v1())     // a downward crossing
0043         if (is_left( a_V[i], a_V[i+1], a_P) < 0)  // P right of edge
0044           --wn;            // have a valid down intersect
0045     }
0046   }
0047 
0048   return ((wn!=0)?true:false);
0049 }
0050 
0051 // the same done with std::pair.
0052 
0053 template <class T>
0054 inline double is_left(const std::pair<T,T>& P0,const std::pair<T,T>& P1,const std::pair<T,T>& P2){
0055   return ( (P1.first - P0.first) * (P2.second - P0.second)
0056          - (P2.first - P0.first) * (P1.second - P0.second) );
0057 }
0058 
0059 template <class T>
0060 inline bool inside(const std::pair<T,T>& a_P,const std::vector< std::pair<T,T> >& a_V) {
0061   // V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
0062 
0063   // From :
0064   //   http://softsurfer.com/Archive/algorithm_0103/algorithm_0103.htm
0065   // Copyright 2001, softSurfer (www.softsurfer.com)
0066   // This code may be freely used and modified for any purpose
0067   // providing that this copyright notice is included with it.
0068   // SoftSurfer makes no warranty for this code, and cannot be held
0069   // liable for any real or imagined damage resulting from its use.
0070   // Users of this code must verify correctness for their application.
0071 
0072   size_t n = a_V.size()-1;
0073 
0074   int    wn = 0;    // the winding number counter
0075 
0076   // loop through all edges of the polygon
0077   for (size_t i=0; i<n; i++) {   // edge from V[i] to V[i+1]
0078     if (a_V[i].second <= a_P.second) {         // start y <= P[1]
0079       if (a_V[i+1].second > a_P.second)      // an upward crossing
0080         if (is_left( a_V[i], a_V[i+1], a_P) > 0)  // P left of edge
0081           ++wn;            // have a valid up intersect
0082     } else {                       // start y > P[1] (no test needed)
0083       if (a_V[i+1].second <= a_P.second)     // a downward crossing
0084         if (is_left( a_V[i], a_V[i+1], a_P) < 0)  // P right of edge
0085           --wn;            // have a valid down intersect
0086     }
0087   }
0088 
0089   return ((wn!=0)?true:false);
0090 }
0091 
0092 template <class VEC2>
0093 inline bool intersect(const VEC2& P1,const VEC2& Q1,const VEC2& P2,const VEC2& Q2,VEC2& a_out) {
0094   // (P1,Q1) first line, (P2,Q2) second line and a_out intersection.
0095   // return false if no intersection. (For exa, parallel lines).
0096 
0097   // P1+(Q1-P1)*r = P2+(Q2-P2)*s
0098   // (Q1-P1)*r - (Q2-P2)*s = P2-P1
0099   // r*(Q1-P1).v0 - s*(Q2-P2).v0 = (P2-P1).v0 //x
0100   // r*(Q1-P1).v1 - s*(Q2-P2).v1 = (P2-P1).v1 //y
0101 
0102   // a*r + b*s = c
0103   // d*r + e*s = f
0104 
0105   // r = (c*e-f*b)/(a*e-d*b)
0106   // s = (a*f-d*c)/(a*e-d*b)
0107 
0108   typedef typename VEC2::elem_t T;
0109   VEC2 A = Q1-P1;
0110   VEC2 B = P2-Q2;
0111   VEC2 C = P2-P1;
0112 
0113   T a = A.v0();
0114   T b = B.v0();
0115   T c = C.v0();
0116   T d = A.v1();
0117   T e = B.v1();
0118   T f = C.v1();
0119 
0120   T det = a*e-d*b;
0121   if(det==T()) return false;
0122 
0123   T r = (c*e-f*b)/det;
0124 
0125   a_out = P1+A*r;
0126   return true;
0127 }
0128 
0129 }
0130 
0131 #endif