显然,本算法的抽稀精度也与阈值相关,阈值越大,简化程度越大,点减少的越多,反之,化简程度越低,点保留的越多,形状也越趋于原曲线。
bool SimplifyCurve(CurveVertexes &prevPts, CurveVertexes &nextPts, double tolerance)
{
// Exception
if(!prevPts.size() || tolerance < 0.)
{
return false;
}
nextPts.clear();
// Initialization
int ptSize = prevPts.size();
SimpStack stack(ptSize);
// Loop until two vertex meet with ...
while(stack.m_curOrder >= 0)
{
//Get Top Elemelt;
int lOrder = stack.m_lOrders[stack.m_curOrder];
int rOrder = stack.m_rOrders[stack.m_curOrder];
stack.m_curOrder--;
//
CGeoPoint<double> lPt = prevPts[lOrder];
CGeoPoint<double> rPt = prevPts[rOrder];
// Max proj distance and which point
double maxProjDist = 0.0;
int whichPt = 0;
// Not in the same X or Y direction
if((rPt.m_x - lPt.m_x) != 0 || (rPt.m_y - lPt.m_y) != 0)
{
// Get Max Distance;
int i = lOrder+1;
for(; i < rOrder; i++)
{
double factor = 0.;
CGeoPoint<double> result;
double projDist = CVectOP<double>::Point2Line(prevPts[lOrder], prevPts[rOrder], prevPts[i], factor, result);
if(projDist > maxProjDist )
{
maxProjDist = projDist;
whichPt = i;
}
}
}
else
{
if(rOrder - lOrder > 1)
{
stack.m_curOrder++;
stack.m_lOrders[stack.m_curOrder] = lOrder;
stack.m_rOrders[stack.m_curOrder] = rOrder-1;
}
}
// Based on this point to split this point array
if(maxProjDist > tolerance) //大于给定值接着二分
{
stack.m_isRetain[whichPt] = true;
if(rOrder - lOrder > 1)
{
stack.m_curOrder++;
stack.m_lOrders[stack.m_curOrder] = lOrder;
stack.m_rOrders[stack.m_curOrder] = whichPt;
stack.m_curOrder++;
stack.m_lOrders[stack.m_curOrder] = whichPt;
stack.m_rOrders[stack.m_curOrder] = rOrder;
}
}
else //小于给定值舍去中间点,留下首末点
{
stack.m_isRetain[lOrder] = true;
stack.m_isRetain[rOrder] = true;
}
}
int i = 0;
for(; i < ptSize; i++)
{
if(!stack.m_isRetain[i])
{
continue;
}
nextPts.push_back(prevPts[i]);
}
return true;
}