00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef __VCGLIB_RAY3
00039 #define __VCGLIB_RAY3
00040
00041 #include <vcg/space/point3.h>
00042
00043 namespace vcg {
00044
00054 template <class RayScalarType, bool NORM=false>
00055 class Ray3
00056 {
00057 public:
00058
00060 typedef RayScalarType ScalarType;
00061
00063 typedef Point3<RayScalarType> PointType;
00064
00066 typedef Ray3<RayScalarType,NORM> RayType;
00067
00068 private:
00069
00071 PointType _ori;
00072
00074 PointType _dir;
00075
00076 public:
00077
00079
00083
00084 inline const PointType &Origin() const { return _ori; }
00085 inline PointType &Origin() { return _ori; }
00086 inline const PointType &Direction() const { return _dir; }
00088 inline void SetOrigin( const PointType & ori )
00089 { _ori=ori; }
00091 inline void SetDirection( const PointType & dir)
00092 { _dir=dir; if (NORM) _dir.Normalize(); }
00094 inline void Set( const PointType & ori, const PointType & dir )
00095 { SetOrigin(ori); SetDirection(dir); }
00097
00099
00101
00102 Ray3() {};
00104 Ray3(const PointType &ori, const PointType &dir) {SetOrigin(ori); SetDirection(dir);};
00106
00108 inline bool operator == ( RayType const & p ) const
00109 { return _ori==p._ori && _dir==p._dir; }
00111 inline bool operator != ( RayType const & p ) const
00112 { return _ori!=p._ori || _dir!=p._dir; }
00114 inline ScalarType Projection( const PointType &p ) const
00115 { if (NORM) return ScalarType((p-_ori).dot(_dir));
00116 else return ScalarType((p-_ori).dot(_dir)/_dir.SquaredNorm());
00117 }
00119 static bool IsNormalized() {return NORM;};
00121 inline PointType P( const ScalarType t ) const
00122 { return _ori + _dir * t; }
00124 inline Ray3<ScalarType,true> &Normalize()
00125 { if (!NORM) _dir.Normalize(); return *((Ray3<ScalarType,true>*)this);}
00127 static Ray3<ScalarType,true> &Normalize(RayType &p)
00128 { p.Normalize(); return *((Ray3<ScalarType,true>*)(&p));}
00130 template <class Q, bool K>
00131 inline void Import( const Ray3<Q,K> & b )
00132 { _ori.Import( b.Origin() ); _dir.Import( b.Direction() );
00133 if ((NORM) && (!K)) _dir.Normalize();
00134
00135 }
00137 template <class Q, bool K>
00138 static RayType Construct( const Ray3<Q,K> & b )
00139 { RayType res; res.Import(b); return res;
00140 }
00141 PointType ClosestPoint(const PointType & p) const{
00142 return P(Projection(p));
00143 }
00145 inline void Flip(){
00146 _dir=-_dir;
00147 };
00148
00150
00157 inline Ray3<ScalarType,false> operator + ( RayType const & p) const
00158 {return Ray3<ScalarType,false> ( _ori+p.Origin(), _dir+p.Direction() );}
00159 inline Ray3<ScalarType,false> operator - ( RayType const & p) const
00160 {return Ray3<ScalarType,false> ( _ori-p.Origin(), _dir-p.Direction() );}
00161 inline Ray3<ScalarType,false> operator * ( const ScalarType s ) const
00162 {return Ray3<ScalarType,false> ( _ori*s, _dir*s );}
00163 inline Ray3<ScalarType,false> operator / ( const ScalarType s ) const
00164 {ScalarType s0=((ScalarType)1.0)/s; return RayType( _ori*s0, _dir*s0 );}
00166
00167
00169
00173
00174 Ray3(const Ray3<ScalarType,!NORM > &r)
00175 { Import(r); };
00177 inline RayType & operator = ( Ray3<ScalarType,!NORM> const &r)
00178 { Import(r); return *this; };
00180
00181 };
00182
00183 typedef Ray3<short> Ray3s;
00184 typedef Ray3<int> Ray3i;
00185 typedef Ray3<float> Ray3f;
00186 typedef Ray3<double> Ray3d;
00187
00188 typedef Ray3<short ,true> Ray3sN;
00189 typedef Ray3<int ,true> Ray3iN;
00190 typedef Ray3<float ,true> Ray3fN;
00191 typedef Ray3<double,true> Ray3dN;
00192
00194 template <class ScalarType, bool NORM>
00195 Point3<ScalarType> ClosestPoint( Ray3<ScalarType,NORM> r, const Point3<ScalarType> & p)
00196 {
00197 ScalarType t = r.Projection(p);
00198 if (t<0) return r.Origin();
00199 return r.P(t);
00200 }
00201
00204 }
00205 #endif