1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
|
/****************************************************************************
* VCGLib o o *
* Visual and Computer Graphics Library o o *
* _ O _ *
* Copyright(C) 2004-2016 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
/****************************************************************************
History
****************************************************************************/
#ifndef __VCGLIB_SEGMENT2
#define __VCGLIB_SEGMENT2
#include <vcg/space/point2.h>
#include <vcg/space/line2.h>
#include <vcg/space/box2.h>
namespace vcg {
/** \addtogroup space */
/*@{*/
/**
Templated class for 3D segment.
This is the class for a segment in 3D space. A Segment is stored just as its two extrema (Point3).
@param SegmentScalarType (template parameter) Specifies the type of scalar used to represent coords.
*/
template <class SegmentScalarType >
class Segment2
{
public:
/// The scalar type
typedef SegmentScalarType ScalarType;
/// The point type
typedef Point2<SegmentScalarType> PointType;
/// The point type
typedef Segment2<SegmentScalarType> SegmentType;
private:
/// _extrema
PointType _p0,_p1;
public:
/// Members to access either extrema
inline const PointType &P0() const { return _p0; }
inline const PointType &P1() const { return _p1; }
inline PointType &P0() { return _p0; }
inline PointType &P1() { return _p1; }
/// The empty constructor
Segment2() {};
/// The (a,b) constructor
Segment2(const PointType &a, const PointType &b) { _p0=a; _p1=b; };
/// Operator to compare segments
inline bool operator == ( SegmentType const & p ) const
{ return _p0==p._p0 && _p1==p._p1; }
/// Operator to dispare segments
inline bool operator != ( SegmentType const & p ) const
{ return _p0!=p._p0 || _p1!=p._p1; }
/// initializes the segment with its extrema
void Set( const PointType &a, const PointType &b)
{ _p0=a; _p1=b;}
/// calculates the point of parameter t on the segment.
/// if t is in [0..1] returned point is inside the segment
inline PointType Lerp( const ScalarType t ) const
{ return _p0 + (_p1 - _p0) * t; }
/// return the middle point
inline PointType MidPoint( ) const
{ return ( _p0 + _p1) / ScalarType(2.0) ; }
/// return the bounding box
inline void GetBBox( Box2<ScalarType> &t) const
{
t.Set(_p0);
t.Add(_p1);
}
/// returns segment length
ScalarType Length()
{ return (_p0 - _p1).Norm(); }
/// returns segment length
ScalarType Length() const
{ return (_p0 - _p1).Norm(); }
/// return segment squared length
ScalarType SquaredLength()
{ return (_p0 - _p1).SquaredNorm(); }
/// flips: a-b becomes b-a
void Flip()
{ PointType t=_p0; _p0=_p1; _p1=t; }
/// importer for different line types
template <class Q>
inline void Import( const Segment2<Q> & b )
{ _p0.Import( b.P0() ); _p1.Import( b.P1() );
}
/// copy constructor (builds a new segment importing an existing one)
template <class Q>
static SegmentType Construct( const Segment2<Q> & b )
{ return SegmentType(PointType::Construct(b.P0()), PointType::Construct(b.P1()));}
//@{
/** @name Linearity for 3d segments (operators +, -, *, /) **/
inline SegmentType operator + ( SegmentType const & p) const
{return SegmentType( _p0+p.P0(), _p1+p.P1() );}
inline SegmentType operator - ( SegmentType const & p) const
{return SegmentType( _p0-p.P0(), _p1-p.P1() );}
inline SegmentType operator * ( const ScalarType s ) const
{return SegmentType( _p0*s, _p1*s );}
inline SegmentType operator / ( const ScalarType s ) const
{ScalarType s0=((ScalarType)1.0)/s; return SegmentType( _p0*s0, _p1*s0 );}
//@}
}; // end class definition
typedef Segment2<short> Segment2s;
typedef Segment2<int> Segment2i;
typedef Segment2<float> Segment2f;
typedef Segment2<double> Segment2d;
template <class ScalarType>
Point2<ScalarType> ClosestPoint( Segment2<ScalarType> s, const Point2<ScalarType> & p)
{
vcg::Line2<ScalarType, true> l;
l.Set(s.P0(),s.P1()-s.P0());
ScalarType t = l.Projection(p);
Point2<ScalarType> clos = l.P(t);
ScalarType length = s.Length();
if (t <= 0)
return s.P0();
else if (t >= length)
return s.P1();
else
return clos;
}
template <class S>
class PointSegment2DEPFunctor {
public:
typedef S ScalarType;
typedef Point2<ScalarType> QueryType;
static inline const Point2<ScalarType> & Pos(const QueryType & qt) {return qt;}
template <class EdgeType, class ScalarType>
inline bool operator () (const EdgeType & e, const Point2<ScalarType> & p,
ScalarType & minDist, Point2<ScalarType> & q)
{
const Point2<typename EdgeType::ScalarType> fp = Point2<typename EdgeType::ScalarType>::Construct(p);
Point2<typename EdgeType::ScalarType> fq;
fq=ClosestPoint(e,fp);
ScalarType currD = (ScalarType)(fp-fq).Norm();
if (currD>minDist)return false;
minDist=currD;
q = Point2<ScalarType>::Construct(fq);
return true;
}
};
} // end namespace
#endif
|