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
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 #ifndef __VCGLIB_SEGMENT3
00051 #define __VCGLIB_SEGMENT3
00052
00053 #include <vcg/space/point3.h>
00054 #include <vcg/space/line3.h>
00055 #include <vcg/space/box3.h>
00056
00057 namespace vcg {
00058
00066 template <class SegmentScalarType >
00067 class Segment3
00068 {
00069 public:
00070
00072 typedef SegmentScalarType ScalarType;
00073
00075 typedef Point3<SegmentScalarType> PointType;
00076
00078 typedef Segment3<SegmentScalarType> SegmentType;
00079
00080 private:
00081
00083 PointType _p0,_p1;
00084
00085 public:
00086
00088 inline const PointType &P0() const { return _p0; }
00089 inline const PointType &P1() const { return _p1; }
00090 inline PointType &P0() { return _p0; }
00091 inline PointType &P1() { return _p1; }
00093 Segment3() {};
00095 Segment3(const PointType &a, const PointType &b) { _p0=a; _p1=b; };
00097 inline bool operator == ( SegmentType const & p ) const
00098 { return _p0==p._p0 && _p1==p._p1; }
00100 inline bool operator != ( SegmentType const & p ) const
00101 { return _p0!=p._p0 || _p1!=p._p1; }
00103 void Set( const PointType &a, const PointType &b)
00104 { _p0=a; _p1=b;}
00107 inline PointType P( const ScalarType t ) const
00108 { return _p0 + (_p1 - _p0) * t; }
00110 inline PointType MidPoint( ) const
00111 { return ( _p0 + _p1) / ScalarType(2.0) ; }
00113 inline Box3<ScalarType> BBox( ) const
00114 { Box3<ScalarType> t;
00115 if (_p0[0]<_p1[0]) { t.min[0]=_p0[0];t.max[0]=_p1[0];} else { t.min[0]=_p1[0];t.max[0]=_p0[0];}
00116 if (_p0[1]<_p1[1]) { t.min[1]=_p0[1];t.max[1]=_p1[1];} else { t.min[1]=_p1[1];t.max[1]=_p0[1];}
00117 if (_p0[2]<_p1[2]) { t.min[2]=_p0[2];t.max[2]=_p1[2];} else { t.min[2]=_p1[2];t.max[2]=_p0[2];}
00118 return t; }
00120 ScalarType Length()
00121 { return (_p0 - _p1).Norm(); }
00123 ScalarType SquaredLength()
00124 { return (_p0 - _p1).SquaredNorm(); }
00126 void Flip()
00127 { PointType t=_p0; _p0=_p1; _p1=t; }
00129 template <class Q>
00130 inline void Import( const Segment3<Q> & b )
00131 { _p0.Import( b.P0() ); _p1.Import( b.P1() );
00132 }
00134 template <class Q>
00135 static SegmentType Construct( const Segment3<Q> & b )
00136 { return SegmentType(PointType::Construct(b.P0()), PointType::Construct(b.P1()));}
00137
00139
00140 inline SegmentType operator + ( SegmentType const & p) const
00141 {return SegmentType( _p0+p.P0(), _p1+p.P1() );}
00142 inline SegmentType operator - ( SegmentType const & p) const
00143 {return SegmentType( _p0-p.P0(), _p1-p.P1() );}
00144 inline SegmentType operator * ( const ScalarType s ) const
00145 {return SegmentType( _p0*s, _p1*s );}
00146 inline SegmentType operator / ( const ScalarType s ) const
00147 {ScalarType s0=((ScalarType)1.0)/s; return SegmentType( _p0*s0, _p1*s0 );}
00149
00150 };
00151
00152
00153
00154 typedef Segment3<short> Segment3s;
00155 typedef Segment3<int> Segment3i;
00156 typedef Segment3<float> Segment3f;
00157 typedef Segment3<double> Segment3d;
00158
00159
00160
00161
00162
00163
00164
00165 template < class ScalarType >
00166 ScalarType SquaredDistance(Segment3< ScalarType > &segment, Point3< ScalarType > &p)
00167 {
00168 typedef typename vcg::Point3< ScalarType > Point3t;
00169
00170 Point3t dir = (segment.P1()-segment.P0()).Normalize();
00171 ScalarType h = dir * (p-segment.P0());
00172 if (h<=ScalarType(0.0)) return vcg::SquaredDistance<ScalarType>(p, segment.P0());
00173 else if (h>=segment.Length()) return vcg::SquaredDistance<ScalarType>(p, segment.P1());
00174 else
00175 {
00176 dir = segment.P0() + dir*h;
00177 return vcg::SquaredDistance<ScalarType>(p, dir);
00178 }
00179 };
00180
00181 template <class ScalarType>
00182 Point3<ScalarType> ClosestPoint( Segment3<ScalarType> s, const Point3<ScalarType> & p)
00183 {
00184 vcg::Line3<ScalarType> l;
00185 l.Set(s.P0(),s.P1()-s.P0());
00186 l.Normalize();
00187 Point3<ScalarType> clos=vcg::ClosestPoint<ScalarType,true>(l,p) ;
00188 vcg::Box3<ScalarType> b;
00189 b.Add(s.P0());
00190 b.Add(s.P1());
00191 if (b.IsIn(clos))
00192 return clos;
00193 else
00194 {
00195 ScalarType d0=(s.P0()-p).Norm();
00196 ScalarType d1=(s.P1()-p).Norm();
00197 if (d0<d1)
00198 return (s.P0());
00199 else
00200 return (s.P1());
00201 }
00202
00203
00204
00205
00206 }
00207
00210 }
00211 #endif