00001
00002
00003 #include <kernel/jafarMacro.hpp>
00004
00005 namespace jafar {
00006 namespace geom {
00007 namespace impl {
00008 inline double safeacos( double cosi )
00009 {
00010 if( cosi - 1.0 > 0.0)
00011 {
00012 JFR_ASSERT( (cosi - 1.0) < 1e-10, "Cosinus is supperior from 1.0" );
00013 return 0.0;
00014 }
00015 return acos(cosi);
00016 }
00017 }
00018 template<int dimension>
00019 inline double angle(const Point<dimension>&, const Point<dimension>& )
00020 {
00021 return 0.0;
00022 }
00023 template<int dimension>
00024 inline double angle(const Point<dimension>&, const Line<dimension>& )
00025 {
00026 return 0.0;
00027 }
00028 template<int dimension>
00029 inline double angle(const Point<dimension>&, const HyperPlane<dimension>& )
00030 {
00031 return 0.0;
00032 }
00033 template<int dimension>
00034 inline double angle(const Point<dimension>&, const Repere<dimension>& )
00035 {
00036 return 0.0;
00037 }
00038
00039 template<int dimension>
00040 inline double angle(const Line<dimension>& line, const Point<dimension>& point)
00041 {
00042 return angle(point, line);
00043 }
00044 template<int dimension>
00045 inline double angle(const Line<dimension>& line1, const typename Atom<dimension>::HomogenousVecD& v)
00046 {
00047 return impl::safeacos(ublas::inner_prod( line1.direction(), v) / ( ublas::norm_2(v)));
00048 }
00049 template<int dimension>
00050 inline double angle(const Line<dimension>& line1, const Line<dimension>& line2)
00051 {
00052 return impl::safeacos(ublas::inner_prod( line1.direction(), line2.reference()->convertIn( line2.direction(), line1.reference() ) ) );
00053 }
00054 template<int dimension>
00055 inline double angle(const Line<dimension>& line, const HyperPlane<dimension>& plan)
00056 {
00057 return impl::safeacos( ublas::inner_prod(line.direction(), plan.reference()->convertIn( plan.normal(), line.reference() ) ) );
00058 }
00059 template<int dimension>
00060 inline double angle(const Line<dimension>& l, const Repere<dimension>& r)
00061 {
00062 typename Atom<dimension>::HomogenousVecD v = jblas::zero_vec(dimension+1);
00063 v(0) = 1.0;
00064 return impl::safeacos( ublas::inner_prod( l.direction(), r.convertIn( v, l.reference() ) ) );
00065 }
00066
00067 template<int dimension>
00068 inline double angle(const HyperPlane<dimension>& plan, const Point<dimension>& point)
00069 {
00070 return angle(point, plan);
00071 }
00072 template<int dimension>
00073 inline double angle(const HyperPlane<dimension>& plan, const Line<dimension>& line)
00074 {
00075 return angle(line, plan);
00076 }
00077 template<int dimension>
00078 inline double angle(const HyperPlane<dimension>& plan1, const HyperPlane<dimension>& plan2)
00079 {
00080 return impl::safeacos( ublas::inner_prod(plan1.normal(), plan2.reference()->convertIn( plan2.normal(), plan1.reference() ) ) );
00081 }
00082 template<int dimension>
00083 inline double angle(const HyperPlane<dimension>& plan, const Repere<dimension>& r)
00084 {
00085 typename Atom<dimension>::HomogenousVecD v = jblas::zero_vec(dimension+1);
00086 v(0) = 1.0;
00087 return impl::safeacos( ublas::inner_prod( plan.normal(), r.convertIn( v, plan.reference() ) ) ) ;
00088 }
00089
00090 template<int dimension, typename _T2_>
00091 inline double angle(const Segment<dimension>& segment, const _T2_& t2)
00092 {
00093 return angle(segment.support(), t2);
00094 }
00095 template<int dimension, typename _T1_>
00096 inline double angle(const _T1_& t1, const Segment<dimension>& segment)
00097 {
00098 return angle(segment.support(), t1);
00099 }
00100 template<int dimension>
00101 inline double angle(const Segment<dimension>& segment1, const Segment<dimension>& segment2)
00102 {
00103 return angle(segment1.support(), segment2.support() );
00104 }
00105
00106 template<int dimension, typename _T2_>
00107 inline double anglePolyLine(const PolyLine<dimension>& pl, const _T2_& t2)
00108 {
00109 std::vector< Segment<dimension> > segments = pl.segments();
00110 double minAngle = 10.0;
00111 for( typename std::vector< Segment<dimension> >::iterator it = segments.begin(); it != segments.end(); ++it)
00112 {
00113 double angle_ = angle( *it, t2 );
00114 if(angle_ < minAngle) minAngle = angle_;
00115 }
00116 return minAngle;
00117 }
00118 template<int dimension, typename _T2_>
00119 inline double angle(const PolyLine<dimension>& pl, const _T2_& t2)
00120 {
00121 return anglePolyLine(pl, t2);
00122 }
00123 template<int dimension, typename _T1_>
00124 inline double angle(const _T1_& t1, const PolyLine<dimension>& pl)
00125 {
00126 return anglePolyLine(pl, t1);
00127 }
00128 template<int dimension>
00129 inline double angle(const PolyLine<dimension>& pl1, const PolyLine<dimension>& pl2)
00130 {
00131 return anglePolyLine(pl1, pl2);
00132 }
00133 template<int dimension>
00134 inline double angle(const PolyLine<dimension>& pl, const Segment<dimension>& s)
00135 {
00136 return anglePolyLine(pl,s);
00137 }
00138 template<int dimension>
00139 inline double angle(const Segment<dimension>& s, const PolyLine<dimension>& pl)
00140 {
00141 return anglePolyLine(pl,s);
00142 }
00143
00144 template<int dimension>
00145 inline double angle(const Repere<dimension>& r, const Point<dimension>& p)
00146 {
00147 return angle(p,r);
00148 }
00149 template<int dimension>
00150 inline double angle(const Repere<dimension>& r, const Line<dimension>& l)
00151 {
00152 return angle(l,r);
00153 }
00154 template<int dimension>
00155 inline double angle(const Repere<dimension>& r, const HyperPlane<dimension>& hp)
00156 {
00157 return angle(hp,r);
00158 }
00159 template<int dimension>
00160 inline double angle(const Repere<dimension>& r1, const Repere<dimension>& r2)
00161 {
00162 typename Atom<dimension>::HomogenousVecD v = jblas::zero_vec(dimension+1);
00163 v(0) = 1.0;
00164 return impl::safeacos(ublas::inner_prod( r1.vec( 0 ), r2.convertIn( v, &r1 ) ));
00165 }
00166 template<int dimension>
00167 inline double angle(const Repere<dimension>& r, const PolyLine<dimension>& pl)
00168 {
00169 return angle(pl,r);
00170 }
00171 }
00172 }