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 #ifndef __VCGLIB_SEGMENT2
00032 #define __VCGLIB_SEGMENT2
00033
00034 #include <vcg/space/point2.h>
00035 #include <vcg/space/line2.h>
00036 #include <vcg/space/box2.h>
00037
00038 namespace vcg {
00039
00047 template <class SegmentScalarType >
00048 class Segment2
00049 {
00050 public:
00051
00053 typedef SegmentScalarType ScalarType;
00054
00056 typedef Point2<SegmentScalarType> PointType;
00057
00059 typedef Segment2<SegmentScalarType> SegmentType;
00060
00061 private:
00062
00064 PointType _p0,_p1;
00065
00066 public:
00067
00069 inline const PointType &P0() const { return _p0; }
00070 inline const PointType &P1() const { return _p1; }
00071 inline PointType &P0() { return _p0; }
00072 inline PointType &P1() { return _p1; }
00074 Segment2() {};
00076 Segment2(const PointType &a, const PointType &b) { _p0=a; _p1=b; };
00078 inline bool operator == ( SegmentType const & p ) const
00079 { return _p0==p._p0 && _p1==p._p1; }
00081 inline bool operator != ( SegmentType const & p ) const
00082 { return _p0!=p._p0 || _p1!=p._p1; }
00084 void Set( const PointType &a, const PointType &b)
00085 { _p0=a; _p1=b;}
00088 inline PointType P( const ScalarType t ) const
00089 { return _p0 + (_p1 - _p0) * t; }
00091 inline PointType MidPoint( ) const
00092 { return ( _p0 + _p1) / ScalarType(2.0) ; }
00094 inline Box2<ScalarType> BBox( ) const
00095 {
00096 Box2<ScalarType> t;
00097 t.Add(_p0);
00098 t.Add(_p1);
00099 return t;
00100 }
00102 ScalarType Length()
00103 { return (_p0 - _p1).Norm(); }
00104
00106 ScalarType Length() const
00107 { return (_p0 - _p1).Norm(); }
00108
00110 ScalarType SquaredLength()
00111 { return (_p0 - _p1).SquaredNorm(); }
00113 void Flip()
00114 { PointType t=_p0; _p0=_p1; _p1=t; }
00116 template <class Q>
00117 inline void Import( const Segment2<Q> & b )
00118 { _p0.Import( b.P0() ); _p1.Import( b.P1() );
00119 }
00121 template <class Q>
00122 static SegmentType Construct( const Segment2<Q> & b )
00123 { return SegmentType(PointType::Construct(b.P0()), PointType::Construct(b.P1()));}
00124
00126
00127 inline SegmentType operator + ( SegmentType const & p) const
00128 {return SegmentType( _p0+p.P0(), _p1+p.P1() );}
00129 inline SegmentType operator - ( SegmentType const & p) const
00130 {return SegmentType( _p0-p.P0(), _p1-p.P1() );}
00131 inline SegmentType operator * ( const ScalarType s ) const
00132 {return SegmentType( _p0*s, _p1*s );}
00133 inline SegmentType operator / ( const ScalarType s ) const
00134 {ScalarType s0=((ScalarType)1.0)/s; return SegmentType( _p0*s0, _p1*s0 );}
00136
00137 };
00138
00139
00140
00141 typedef Segment2<short> Segment2s;
00142 typedef Segment2<int> Segment2i;
00143 typedef Segment2<float> Segment2f;
00144 typedef Segment2<double> Segment2d;
00145
00146 template <class ScalarType>
00147 Point2<ScalarType> ClosestPoint( Segment2<ScalarType> s, const Point2<ScalarType> & p)
00148 {
00149 vcg::Line2<ScalarType> l;
00150 l.Set(s.P0(),s.P1()-s.P0());
00151 l.Normalize();
00152 Point2<ScalarType> clos=vcg::ClosestPoint<ScalarType,true>(l,p) ;
00153 vcg::Box2<ScalarType> b;
00154 b.Add(s.P0());
00155 b.Add(s.P1());
00156 if (b.IsIn(clos))
00157 return clos;
00158 else
00159 {
00160 ScalarType d0=(s.P0()-p).Norm();
00161 ScalarType d1=(s.P1()-p).Norm();
00162 if (d0<d1)
00163 return (s.P0());
00164 else
00165 return (s.P1());
00166 }
00167
00168
00169
00170
00171 }
00172
00175 }
00176 #endif