Update SHAPE_LINE_CHAIN::Simplify to better handle small diff
When simplifying, a small difference in successive points would allow a larger difference than aMaxError to be removed. This change checks the intermediate points during removal to ensure we don't get overzelous
This commit is contained in:
parent
10c0bba9cc
commit
9e83a7bcb3
|
@ -2389,25 +2389,49 @@ void SHAPE_LINE_CHAIN::Simplify( int aMaxError )
|
||||||
new_points.reserve( m_points.size() );
|
new_points.reserve( m_points.size() );
|
||||||
new_shapes.reserve( m_shapes.size() );
|
new_shapes.reserve( m_shapes.size() );
|
||||||
|
|
||||||
|
auto is_skip = [this]( size_t i, size_t j, size_t k )
|
||||||
|
{
|
||||||
|
return ( ( m_points[i].x == m_points[j].x // First two points on same vertical line
|
||||||
|
&& m_points[i].y != m_points[j].y // and not on same horizontal line
|
||||||
|
&& m_points[i].x != m_points[k].x ) // and not on same vertical line as third point
|
||||||
|
|| ( m_points[i].y == m_points[j].y
|
||||||
|
&& m_points[i].x != m_points[j].x
|
||||||
|
&& m_points[i].y != m_points[k].y ) );
|
||||||
|
};
|
||||||
|
|
||||||
for( size_t ii = 0; ii < m_points.size(); )
|
for( size_t ii = 0; ii < m_points.size(); )
|
||||||
{
|
{
|
||||||
new_points.push_back( m_points[ii] );
|
new_points.push_back( m_points[ii] );
|
||||||
new_shapes.push_back( m_shapes[ii] );
|
new_shapes.push_back( m_shapes[ii] );
|
||||||
size_t jj = ( ii + 1 ) % m_points.size();
|
size_t jj = ( ii + 1 ) % m_points.size();
|
||||||
size_t kk = ( jj + 1 ) % m_points.size();
|
size_t kk = ( ii + 2 ) % m_points.size();
|
||||||
|
|
||||||
if( m_shapes[ii].first != SHAPE_IS_PT || m_shapes[jj].first != SHAPE_IS_PT
|
if( m_shapes[ii].first != SHAPE_IS_PT || m_shapes[jj].first != SHAPE_IS_PT
|
||||||
|| m_shapes[kk].first != SHAPE_IS_PT )
|
|| m_shapes[kk].first != SHAPE_IS_PT
|
||||||
|
|| is_skip( ii, jj, kk ) )
|
||||||
{
|
{
|
||||||
++ii;
|
++ii;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
while( TestSegmentHitFast( m_points[jj], m_points[ii], m_points[kk], aMaxError )
|
while( ii != kk && jj > ii && !( kk < ii && !m_closed ) )
|
||||||
&& ii != kk && jj > ii )
|
|
||||||
{
|
{
|
||||||
|
bool too_far = false;
|
||||||
|
|
||||||
|
for( size_t ll = ii + 1; ll < kk; ++ll )
|
||||||
|
{
|
||||||
|
if( !TestSegmentHitFast( m_points[ll], m_points[ii], m_points[kk], aMaxError ) )
|
||||||
|
{
|
||||||
|
too_far = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( too_far || is_skip( ii, jj, kk ) )
|
||||||
|
break;
|
||||||
|
|
||||||
jj = ( jj + 1 ) % m_points.size();
|
jj = ( jj + 1 ) % m_points.size();
|
||||||
kk = ( jj + 1 ) % m_points.size();
|
kk = ( kk + 1 ) % m_points.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ii == kk || jj <= ii )
|
if( ii == kk || jj <= ii )
|
||||||
|
|
Loading…
Reference in New Issue