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
|
template <class T>
class TLineApproximator
{
public:
//! \name Structures and typedefs
//@{
//! 2D homogenous point
struct SHomog
{
public:
SHomog(T _x=0, T _y=0, T _w=1) { x=_x; y=_y; w=_w;};
T x;
T y;
T w;
};
//! 2D point
struct SPoint
{
public:
SPoint(T _x=0, T _y=0) { x=_x; y=_y;};
static void CrossProduct( const SPoint& p, const SPoint& q, SHomog& r)
{
r.w = p.x * q.y - p.y * q.x;
r.x = - q.y + p.y;
r.y = q.x - p.x;
};
static T DotProduct( const SPoint& p, const SHomog& q)
{
return q.w + p.x*q.x + p.y*q.y;
};
static T DotProduct( const SPoint& p, const SPoint& q)
{
return p.x*q.x + p.y*q.y;
};
static void LinComb( T a, const SPoint& p, T b, const SPoint& q, SPoint& r)
{
r.x = a * p.x + b * q.x;
r.y = a * p.y + b * q.y;
};
T x;
T y;
};
//! Internal limit structure
struct SLimits
{
T dMinX;
T dMaxX;
T dMinY;
T dMaxY;
T GetCenterX() { return (dMaxX+dMinX)/2.0;};
T GetCenterY() { return (dMaxX+dMinX)/2.0;};
T GetWidth() { return dMaxX-dMinX;};
T GetHeight() { return dMaxY-dMinY;};
};
//! points container
typedef typename std::vector<SPoint> PointContainer;
//! Key containers
typedef typename std::list<PointContainer> KeyContainer;
//@}
//! \name Constructor
//@{
TLineApproximator(): m_dTol(0), m_bNormalization(true)
{m_limits.dMinX=m_limits.dMinY=0;m_limits.dMaxX=m_limits.dMaxY=1;};
~TLineApproximator(){};
//@}
//! \name Point handling
//@{
//! returns number of points
UINT GetPointSize() const { return m_cPoints.size();};
//! sets the points as copy of the vectors
void SetPoints( const std::vector<T>& vX, const std::vector<T>& vY);
//! return vector of points
PointContainer& GetPoints() { return m_cPoints;};
//! return vector of points, const
const PointContainer& GetPoints() const { return m_cPoints;};
//@}
//! \name Key handling
//@{
//! returns number of keys
UINT GetKeySize() const { return m_cKeys.size();};
//! return keys
KeyContainer& GetKeys() { return m_cKeys;};
//! return keys, const
const KeyContainer& GetKeys() const { return m_cKeys;};
//! fill vectors with keys
void GetKeys( std::vector<T>& vX, std::vector<T>& vY);
//@}
//! \name Tolerance
//@{
//! sets the tolerance
void SetTol( double dTol) { m_dTol = __max( dTol, 0);};
//! return current tolerance
double GetTol() const { return m_dTol;};
//@}
//! \name Normalization
//@{
//! enabled, disable normalization
void SetNormalization( bool bEnabled = true) { m_bNormalization = true;};
//! returns true if normalizing
bool IsNormalization() const { return m_bNormalization;};
//@}
//! \name Simplification functions
//@{
//! Initialize simplification
void ClearKeys() { m_cKeys.clear();};
//! Compute the keys
void Simplify();
/*! Shrink to compression level
\param dScale scaling to apply [0...1]
\param dScaleTol [optional] tolerance with respect to dScale, default is 0.05
\param nMaxIter [optional] maximum number of iterations, default is 250
\return number of estimations
*/
UINT ShrinkNorm( double dScale, double dScaleTol = 0.05, UINT nMaxIter = 250);
/*! Shrink to a specified number of points
\param n desired number of points in the approximate curve
\param nTol [optional] tolerance with respect to n, default is 10
\param nMaxIter [optional] maximum number of iterations, default is 250
\return number of estimations
*/
UINT Shrink( UINT nDesiredPoints, UINT nTol = 10, UINT nMaxIter = 250);
//@}
//! \name Helper functions
//@{
//! compute the bounding box
void ComputeBoundingBox();
//! return the point bounding box
const SLimits& GetBoundingBox() const { return m_limits;};
/*! Point normalization
Let $(x_i,y_i)$, the original points and $(\hat x_x, \hat y_i)$ the normalized points:
\[
\hat x_i = \frac{x_i - \bar x]}{\max_i (x_i-x_j)}
\]
where $\bar x, \bar y$ denote respectively the mean value of the $x_i$ and $y_i$.
\sa DeNormalizePoints
*/
void NormalizePoints();
/*! \brief Roll back normalization
\sa NormalizePoints
*/
void DeNormalizePoints();
//@}
protected:
//! \name Virtual functions
//@{
virtual void ComputeKeys() { ClearKeys();};
//@}
private:
double m_dTol;
bool m_bNormalization;
PointContainer m_cPoints;
KeyContainer m_cKeys;
SLimits m_limits;
}; |
Partager