SHAPE_LINE_CHAIN::Area() should always be positive

The algorithm relied on the assumption that the points were
ordered anti-clockwise. When ordered in a clockwise fashion, the
result was correct but negative.

Refer to https://www.mathopenref.com/coordpolygonarea2.html
for more information.
This commit is contained in:
Roberto Fernandez Bautista 2021-05-09 20:01:47 +01:00 committed by Jon Evans
parent c3051ba48a
commit 3f73d8c2b5
3 changed files with 6 additions and 6 deletions

View File

@ -1714,7 +1714,7 @@ double SHAPE_LINE_CHAIN::Area() const
j = i;
}
return -area * 0.5;
return std::fabs( area * 0.5 ); // The result would be negative if points are anti-clockwise
}

View File

@ -323,13 +323,13 @@ void DIALOG_BOARD_STATISTICS::getDataFromPCB()
for( int i = 0; i < polySet.OutlineCount(); i++ )
{
SHAPE_LINE_CHAIN& outline = polySet.Outline( i );
m_boardArea += std::fabs( outline.Area() );
m_boardArea += outline.Area();
// If checkbox "subtract holes" is checked
if( m_checkBoxSubtractHoles->GetValue() )
{
for( int j = 0; j < polySet.HoleCount( i ); j++ )
m_boardArea -= std::fabs( polySet.Hole( i, j ).Area() );
m_boardArea -= polySet.Hole( i, j ).Area();
}
if( boundingBoxCreated )

View File

@ -119,7 +119,7 @@ DIRECTION_45 MOUSE_TRAIL_TRACER::GetPosture( const VECTOR2I& aP )
PNS_DBG( dbg, AddLine, straight, m_forced ? BLUE : GREEN, 100000, "mt-straight" );
double areaS = std::abs( straight.Area() );
double areaS = straight.Area();
SHAPE_LINE_CHAIN diag( DIRECTION_45().BuildInitialTrace( p0, aP, true, false ) );
diag.Append( m_trail.Reverse() );
@ -128,7 +128,7 @@ DIRECTION_45 MOUSE_TRAIL_TRACER::GetPosture( const VECTOR2I& aP )
PNS_DBG( dbg, AddLine, diag, YELLOW, 100000, "mt-diag" );
double areaDiag = std::abs( diag.Area() );
double areaDiag = diag.Area();
double ratio = areaS / ( areaDiag + 1.0 );
// heuristic to detect that the user dragged back the cursor to the beginning of the trace
@ -152,7 +152,7 @@ DIRECTION_45 MOUSE_TRAIL_TRACER::GetPosture( const VECTOR2I& aP )
SHAPE_LINE_CHAIN trail( m_trail );
trail.SetClosed( true );
if( std::abs( trail.Area() ) > areaCutoff )
if( trail.Area() > areaCutoff )
areaOk = true;
}