Cleanup geometry functions
Added Distance(VECTOR2) function that returns a double. Removed superfluous EuclideanNorm, GetLineLength, integer constructor for EDA_ANGLE (this promotes to double in the CTOR), DistanceLinePoint and HitTestPoints Also extended the size for arc calculations that get distances to center points to avoid overflow
This commit is contained in:
parent
931de12072
commit
a9ae86eefd
|
@ -467,7 +467,7 @@ bool DS_DRAW_ITEM_LINE::HitTest( const VECTOR2I& aPosition, int aAccuracy ) cons
|
||||||
wxString DS_DRAW_ITEM_LINE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
wxString DS_DRAW_ITEM_LINE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||||
{
|
{
|
||||||
return wxString::Format( _( "Line, length %s" ),
|
return wxString::Format( _( "Line, length %s" ),
|
||||||
aUnitsProvider->MessageTextFromValue( EuclideanNorm( GetStart() - GetEnd() ) ) );
|
aUnitsProvider->MessageTextFromValue( GetStart().Distance( GetEnd() ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -128,12 +128,12 @@ double EDA_SHAPE::GetLength() const
|
||||||
{
|
{
|
||||||
case SHAPE_T::BEZIER:
|
case SHAPE_T::BEZIER:
|
||||||
for( size_t ii = 1; ii < m_bezierPoints.size(); ++ii )
|
for( size_t ii = 1; ii < m_bezierPoints.size(); ++ii )
|
||||||
length += GetLineLength( m_bezierPoints[ ii - 1], m_bezierPoints[ii] );
|
length += m_bezierPoints[ ii - 1].Distance( m_bezierPoints[ii] );
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
|
|
||||||
case SHAPE_T::SEGMENT:
|
case SHAPE_T::SEGMENT:
|
||||||
return GetLineLength( GetStart(), GetEnd() );
|
return GetStart().Distance( GetEnd() );
|
||||||
|
|
||||||
case SHAPE_T::POLY:
|
case SHAPE_T::POLY:
|
||||||
for( int ii = 0; ii < m_poly.COutline( 0 ).SegmentCount(); ii++ )
|
for( int ii = 0; ii < m_poly.COutline( 0 ).SegmentCount(); ii++ )
|
||||||
|
@ -623,11 +623,11 @@ int EDA_SHAPE::GetRadius() const
|
||||||
switch( m_shape )
|
switch( m_shape )
|
||||||
{
|
{
|
||||||
case SHAPE_T::ARC:
|
case SHAPE_T::ARC:
|
||||||
radius = GetLineLength( m_arcCenter, m_start );
|
radius = m_arcCenter.Distance( m_start );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHAPE_T::CIRCLE:
|
case SHAPE_T::CIRCLE:
|
||||||
radius = GetLineLength( m_start, m_end );
|
radius = m_start.Distance( m_end );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -796,7 +796,7 @@ void EDA_SHAPE::ShapeGetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PA
|
||||||
case SHAPE_T::SEGMENT:
|
case SHAPE_T::SEGMENT:
|
||||||
{
|
{
|
||||||
aList.emplace_back( _( "Length" ),
|
aList.emplace_back( _( "Length" ),
|
||||||
aFrame->MessageTextFromValue( GetLineLength( GetStart(), GetEnd() ) ));
|
aFrame->MessageTextFromValue( GetStart().Distance( GetEnd() ) ));
|
||||||
|
|
||||||
// angle counter-clockwise from 3'o-clock
|
// angle counter-clockwise from 3'o-clock
|
||||||
EDA_ANGLE angle( atan2( (double)( GetStart().y - GetEnd().y ),
|
EDA_ANGLE angle( atan2( (double)( GetStart().y - GetEnd().y ),
|
||||||
|
@ -869,19 +869,17 @@ const BOX2I EDA_SHAPE::getBoundingBox() const
|
||||||
|
|
||||||
bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||||
{
|
{
|
||||||
int maxdist = aAccuracy;
|
double maxdist = aAccuracy;
|
||||||
|
|
||||||
if( GetWidth() > 0 )
|
if( GetWidth() > 0 )
|
||||||
maxdist += GetWidth() / 2;
|
maxdist += GetWidth() / 2.0;
|
||||||
|
|
||||||
switch( m_shape )
|
switch( m_shape )
|
||||||
{
|
{
|
||||||
case SHAPE_T::CIRCLE:
|
case SHAPE_T::CIRCLE:
|
||||||
{
|
{
|
||||||
int radius = GetRadius();
|
double radius = GetRadius();
|
||||||
|
double dist = aPosition.Distance( getCenter() );
|
||||||
VECTOR2I::extended_type dist = KiROUND<double, VECTOR2I::extended_type>(
|
|
||||||
EuclideanNorm( aPosition - getCenter() ) );
|
|
||||||
|
|
||||||
if( IsFilled() )
|
if( IsFilled() )
|
||||||
return dist <= radius + maxdist; // Filled circle hit-test
|
return dist <= radius + maxdist; // Filled circle hit-test
|
||||||
|
@ -891,17 +889,15 @@ bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||||
|
|
||||||
case SHAPE_T::ARC:
|
case SHAPE_T::ARC:
|
||||||
{
|
{
|
||||||
if( EuclideanNorm( aPosition - m_start ) <= maxdist )
|
if( aPosition.Distance( m_start ) <= maxdist )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if( EuclideanNorm( aPosition - m_end ) <= maxdist )
|
if( aPosition.Distance( m_end ) <= maxdist )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
VECTOR2I relPos = aPosition - getCenter();
|
double radius = GetRadius();
|
||||||
int radius = GetRadius();
|
VECTOR2D relPos( VECTOR2D( aPosition ) - getCenter() );
|
||||||
|
double dist = relPos.EuclideanNorm();
|
||||||
VECTOR2I::extended_type dist =
|
|
||||||
KiROUND<double, VECTOR2I::extended_type>( EuclideanNorm( relPos ) );
|
|
||||||
|
|
||||||
if( IsFilled() )
|
if( IsFilled() )
|
||||||
{
|
{
|
||||||
|
@ -1491,14 +1487,14 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
m_end = aPosition;
|
m_end = aPosition;
|
||||||
radius = sqrt( sq( GetLineLength( m_start, m_end ) ) / 2.0 );
|
radius = m_start.Distance( m_end ) * M_SQRT1_2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
VECTOR2I v = m_start - m_end;
|
VECTOR2I v = m_start - m_end;
|
||||||
double chordBefore = sq( v.x ) + sq( v.y );
|
double chordBefore = v.SquaredEuclideanNorm();
|
||||||
|
|
||||||
if( m_editState == 2 )
|
if( m_editState == 2 )
|
||||||
m_start = aPosition;
|
m_start = aPosition;
|
||||||
|
@ -1507,7 +1503,7 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
||||||
|
|
||||||
v = m_start - m_end;
|
v = m_start - m_end;
|
||||||
|
|
||||||
double chordAfter = sq( v.x ) + sq( v.y );
|
double chordAfter = v.SquaredEuclideanNorm();
|
||||||
double ratio = 0.0;
|
double ratio = 0.0;
|
||||||
|
|
||||||
if( chordBefore > 0 )
|
if( chordBefore > 0 )
|
||||||
|
@ -1520,8 +1516,8 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
double radialA = GetLineLength( m_start, aPosition );
|
double radialA = m_start.Distance( aPosition );
|
||||||
double radialB = GetLineLength( m_end, aPosition );
|
double radialB = m_end.Distance( aPosition );
|
||||||
radius = ( radialA + radialB ) / 2.0;
|
radius = ( radialA + radialB ) / 2.0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1534,9 +1530,9 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
||||||
// Calculate center based on start, end, and radius
|
// Calculate center based on start, end, and radius
|
||||||
//
|
//
|
||||||
// Let 'l' be the length of the chord and 'm' the middle point of the chord
|
// Let 'l' be the length of the chord and 'm' the middle point of the chord
|
||||||
double l = GetLineLength( m_start, m_end );
|
double l = m_start.Distance( m_end );
|
||||||
VECTOR2D m = ( m_start + m_end ) / 2;
|
VECTOR2D m = ( m_start + m_end ) / 2;
|
||||||
double sqRadDiff = sq( radius ) - sq( l / 2 );
|
double sqRadDiff = ( radius * radius ) - 0.25;
|
||||||
|
|
||||||
// Calculate 'd', the vector from the chord midpoint to the center
|
// Calculate 'd', the vector from the chord midpoint to the center
|
||||||
VECTOR2D d;
|
VECTOR2D d;
|
||||||
|
@ -1575,7 +1571,7 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
// Pick the one closer to the mouse position
|
// Pick the one closer to the mouse position
|
||||||
m_arcCenter = GetLineLength( c1, aPosition ) < GetLineLength( c2, aPosition ) ? c1 : c2;
|
m_arcCenter = c1.Distance( aPosition ) < c2.Distance( aPosition ) ? c1 : c2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -491,7 +491,7 @@ void PLOTTER::segmentAsOval( const VECTOR2I& start, const VECTOR2I& end, int aWi
|
||||||
EDA_ANGLE orient( size );
|
EDA_ANGLE orient( size );
|
||||||
orient = -orient; // this is due to our Y axis orientation
|
orient = -orient; // this is due to our Y axis orientation
|
||||||
|
|
||||||
size.x = KiROUND( EuclideanNorm( size ) ) + aWidth;
|
size.x = size.EuclideanNorm() + aWidth;
|
||||||
size.y = aWidth;
|
size.y = aWidth;
|
||||||
|
|
||||||
FlashPadOval( center, size, orient, aTraceMode, nullptr );
|
FlashPadOval( center, size, orient, aTraceMode, nullptr );
|
||||||
|
|
|
@ -241,7 +241,7 @@ const BOX2I SCH_LINE::GetBoundingBox() const
|
||||||
|
|
||||||
double SCH_LINE::GetLength() const
|
double SCH_LINE::GetLength() const
|
||||||
{
|
{
|
||||||
return GetLineLength( m_start, m_end );
|
return m_start.Distance( m_end );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -768,7 +768,7 @@ wxString SCH_LINE::GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
return wxString::Format( txtfmt,
|
return wxString::Format( txtfmt,
|
||||||
aUnitsProvider->MessageTextFromValue( EuclideanNorm( m_start - m_end ) ) );
|
aUnitsProvider->MessageTextFromValue( m_start.Distance( m_end ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1231,8 +1231,8 @@ int EE_POINT_EDITOR::addCorner( const TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
for( unsigned i = 0; i < numPoints; ++i )
|
for( unsigned i = 0; i < numPoints; ++i )
|
||||||
{
|
{
|
||||||
int distance = (int) DistanceLinePoint( poly.CPoint( i ),
|
SEG seg = poly.GetSegment( i );
|
||||||
poly.CPoint( i + 1 ), cursor );
|
int distance = seg.Distance( cursor );
|
||||||
|
|
||||||
if( distance < currentMinDistance )
|
if( distance < currentMinDistance )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1264,9 +1264,9 @@ bool EE_SELECTION_TOOL::selectPoint( EE_COLLECTOR& aCollector, const VECTOR2I& a
|
||||||
{
|
{
|
||||||
SCH_LINE* line = (SCH_LINE*) aCollector[i];
|
SCH_LINE* line = (SCH_LINE*) aCollector[i];
|
||||||
|
|
||||||
if( HitTestPoints( line->GetStartPoint(), aWhere, aCollector.m_Threshold ) )
|
if( line->GetStartPoint().Distance( aWhere ) <= aCollector.m_Threshold )
|
||||||
flags = STARTPOINT;
|
flags = STARTPOINT;
|
||||||
else if( HitTestPoints( line->GetEndPoint(), aWhere, aCollector.m_Threshold ) )
|
else if( line->GetEndPoint().Distance( aWhere ) <= aCollector.m_Threshold )
|
||||||
flags = ENDPOINT;
|
flags = ENDPOINT;
|
||||||
else
|
else
|
||||||
flags = STARTPOINT | ENDPOINT;
|
flags = STARTPOINT | ENDPOINT;
|
||||||
|
@ -1516,8 +1516,7 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
|
||||||
|
|
||||||
if( line )
|
if( line )
|
||||||
{
|
{
|
||||||
dist = KiROUND( DistanceLinePoint( line->GetStartPoint(),
|
dist = line->GetSeg().Distance( aPos );
|
||||||
line->GetEndPoint(), aPos ) );
|
|
||||||
}
|
}
|
||||||
else if( field )
|
else if( field )
|
||||||
{
|
{
|
||||||
|
@ -1567,13 +1566,13 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
|
||||||
SHAPE_RECT rect( bbox.GetPosition(), bbox.GetWidth(), bbox.GetHeight() );
|
SHAPE_RECT rect( bbox.GetPosition(), bbox.GetWidth(), bbox.GetHeight() );
|
||||||
|
|
||||||
if( bbox.Contains( aPos ) )
|
if( bbox.Contains( aPos ) )
|
||||||
dist = KiROUND( EuclideanNorm( bbox.GetCenter() - aPos ) );
|
dist = bbox.GetCenter().Distance( aPos );
|
||||||
else
|
else
|
||||||
rect.Collide( poss, closestDist, &dist );
|
rect.Collide( poss, closestDist, &dist );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dist = KiROUND( EuclideanNorm( bbox.GetCenter() - aPos ) );
|
dist = bbox.GetCenter().Distance( aPos );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -460,7 +460,7 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( APERTURE_MACRO* aApertMacro,
|
||||||
VECTOR2I end =
|
VECTOR2I end =
|
||||||
mapPt( m_Params[4].GetValueFromMacro( aApertMacro ), m_Params[5].GetValueFromMacro( aApertMacro ), m_GerbMetric );
|
mapPt( m_Params[4].GetValueFromMacro( aApertMacro ), m_Params[5].GetValueFromMacro( aApertMacro ), m_GerbMetric );
|
||||||
VECTOR2I delta = end - start;
|
VECTOR2I delta = end - start;
|
||||||
int len = KiROUND( EuclideanNorm( delta ) );
|
int len = delta.EuclideanNorm();
|
||||||
|
|
||||||
// To build the polygon, we must create a horizontal polygon starting to "start"
|
// To build the polygon, we must create a horizontal polygon starting to "start"
|
||||||
// and rotate it to have the end point to "end"
|
// and rotate it to have the end point to "end"
|
||||||
|
|
|
@ -285,7 +285,7 @@ const BOX2I GERBER_DRAW_ITEM::GetBoundingBox() const
|
||||||
|
|
||||||
case GBR_CIRCLE:
|
case GBR_CIRCLE:
|
||||||
{
|
{
|
||||||
double radius = GetLineLength( m_Start, m_End );
|
double radius = m_Start.Distance( m_End );
|
||||||
bbox.Inflate( radius, radius );
|
bbox.Inflate( radius, radius );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -490,7 +490,7 @@ void GERBER_DRAW_ITEM::Print( wxDC* aDC, const VECTOR2I& aOffset, GBR_DISPLAY_OP
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GBR_CIRCLE:
|
case GBR_CIRCLE:
|
||||||
radius = KiROUND( GetLineLength( m_Start, m_End ) );
|
radius = KiROUND( m_Start.Distance( m_End ) );
|
||||||
|
|
||||||
halfPenWidth = m_Size.x >> 1;
|
halfPenWidth = m_Size.x >> 1;
|
||||||
|
|
||||||
|
@ -867,7 +867,7 @@ bool GERBER_DRAW_ITEM::HitTest( const VECTOR2I& aRefPos, int aAccuracy ) const
|
||||||
|
|
||||||
case GBR_ARC:
|
case GBR_ARC:
|
||||||
{
|
{
|
||||||
double radius = GetLineLength( m_Start, m_ArcCentre );
|
double radius = m_Start.Distance( m_ArcCentre );
|
||||||
VECTOR2D test_radius = VECTOR2D( ref_pos ) - VECTOR2D( m_ArcCentre );
|
VECTOR2D test_radius = VECTOR2D( ref_pos ) - VECTOR2D( m_ArcCentre );
|
||||||
|
|
||||||
int size = ( ( m_Size.x < MIN_HIT_TEST_RADIUS ) ? MIN_HIT_TEST_RADIUS : m_Size.x );
|
int size = ( ( m_Size.x < MIN_HIT_TEST_RADIUS ) ? MIN_HIT_TEST_RADIUS : m_Size.x );
|
||||||
|
@ -922,7 +922,7 @@ bool GERBER_DRAW_ITEM::HitTest( const VECTOR2I& aRefPos, int aAccuracy ) const
|
||||||
radius = MIN_HIT_TEST_RADIUS;
|
radius = MIN_HIT_TEST_RADIUS;
|
||||||
|
|
||||||
if( m_Flashed )
|
if( m_Flashed )
|
||||||
return HitTestPoints( m_Start, ref_pos, radius );
|
return m_Start.Distance( ref_pos ) <= radius;
|
||||||
else
|
else
|
||||||
return TestSegmentHit( ref_pos, m_Start, m_End, radius );
|
return TestSegmentHit( ref_pos, m_Start, m_End, radius );
|
||||||
}
|
}
|
||||||
|
@ -995,7 +995,7 @@ double GERBER_DRAW_ITEM::ViewGetLOD( int aLayer, KIGFX::VIEW* aView ) const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case GBR_ARC:
|
case GBR_ARC:
|
||||||
size = GetLineLength( m_Start, m_ArcCentre );
|
size = m_Start.Distance( m_ArcCentre );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -297,7 +297,7 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer )
|
||||||
case GBR_CIRCLE:
|
case GBR_CIRCLE:
|
||||||
{
|
{
|
||||||
isFilled = gvconfig()->m_Display.m_DisplayLinesFill;
|
isFilled = gvconfig()->m_Display.m_DisplayLinesFill;
|
||||||
double radius = GetLineLength( aItem->m_Start, aItem->m_End );
|
double radius = aItem->m_Start.Distance( aItem->m_End );
|
||||||
m_gal->DrawCircle( start, radius );
|
m_gal->DrawCircle( start, radius );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,7 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer )
|
||||||
|
|
||||||
// Gerber arcs are 3-point (start, center, end)
|
// Gerber arcs are 3-point (start, center, end)
|
||||||
// GAL needs center, radius, start angle, end angle
|
// GAL needs center, radius, start angle, end angle
|
||||||
double radius = GetLineLength( arcStart, aItem->m_ArcCentre );
|
double radius = arcStart.Distance( aItem->m_ArcCentre );
|
||||||
VECTOR2D center = aItem->GetABPosition( aItem->m_ArcCentre );
|
VECTOR2D center = aItem->GetABPosition( aItem->m_ArcCentre );
|
||||||
VECTOR2D startVec = VECTOR2D( aItem->GetABPosition( arcStart ) ) - center;
|
VECTOR2D startVec = VECTOR2D( aItem->GetABPosition( arcStart ) ) - center;
|
||||||
VECTOR2D endVec = VECTOR2D( aItem->GetABPosition( arcEnd ) ) - center;
|
VECTOR2D endVec = VECTOR2D( aItem->GetABPosition( arcEnd ) ) - center;
|
||||||
|
|
|
@ -106,48 +106,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit EDA_ANGLE( const VECTOR2I& aVector )
|
|
||||||
{
|
|
||||||
/* gcc is surprisingly smart in optimizing these conditions in a tree! */
|
|
||||||
|
|
||||||
if( aVector.x == 0 && aVector.y == 0 )
|
|
||||||
{
|
|
||||||
m_value = 0;
|
|
||||||
}
|
|
||||||
else if( aVector.y == 0 )
|
|
||||||
{
|
|
||||||
if( aVector.x >= 0 )
|
|
||||||
m_value = 0.0;
|
|
||||||
else
|
|
||||||
m_value = -180.0;
|
|
||||||
}
|
|
||||||
else if( aVector.x == 0 )
|
|
||||||
{
|
|
||||||
if( aVector.y >= 0 )
|
|
||||||
m_value = 90.0;
|
|
||||||
else
|
|
||||||
m_value = -90.0;
|
|
||||||
}
|
|
||||||
else if( aVector.x == aVector.y )
|
|
||||||
{
|
|
||||||
if( aVector.x >= 0 )
|
|
||||||
m_value = 45.0;
|
|
||||||
else
|
|
||||||
m_value = -180.0 + 45.0;
|
|
||||||
}
|
|
||||||
else if( aVector.x == -aVector.y )
|
|
||||||
{
|
|
||||||
if( aVector.x >= 0 )
|
|
||||||
m_value = -45.0;
|
|
||||||
else
|
|
||||||
m_value = 180.0 - 45.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*this = EDA_ANGLE( atan2( (double) aVector.y, (double) aVector.x ), RADIANS_T );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EDA_ANGLE() :
|
EDA_ANGLE() :
|
||||||
m_value( 0.0 )
|
m_value( 0.0 )
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -253,8 +253,9 @@ public:
|
||||||
*/
|
*/
|
||||||
bool IsCCW() const
|
bool IsCCW() const
|
||||||
{
|
{
|
||||||
VECTOR2I v1 = m_end - m_mid;
|
VECTOR2L mid = m_mid;
|
||||||
VECTOR2I v2 = m_start - m_mid;
|
VECTOR2L v1 = m_end - mid;
|
||||||
|
VECTOR2L v2 = m_start - mid;
|
||||||
|
|
||||||
return v1.Cross( v2 ) > 0;
|
return v1.Cross( v2 ) > 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,6 +180,12 @@ public:
|
||||||
*/
|
*/
|
||||||
extended_type Dot( const VECTOR2<T>& aVector ) const;
|
extended_type Dot( const VECTOR2<T>& aVector ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the distance between two vectors. This is a double precision
|
||||||
|
* value because the distance is frequently non-integer.
|
||||||
|
*/
|
||||||
|
double Distance( const VECTOR2<extended_type>& aVector ) const;
|
||||||
|
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
|
|
||||||
|
@ -267,8 +273,15 @@ T VECTOR2<T>::EuclideanNorm() const
|
||||||
// 45° are common in KiCad, so we can optimize the calculation
|
// 45° are common in KiCad, so we can optimize the calculation
|
||||||
if( std::abs( x ) == std::abs( y ) )
|
if( std::abs( x ) == std::abs( y ) )
|
||||||
return static_cast<T>( std::abs( x ) * M_SQRT2 );
|
return static_cast<T>( std::abs( x ) * M_SQRT2 );
|
||||||
|
if( x == 0 )
|
||||||
|
return static_cast<T>( std::abs( y ) );
|
||||||
|
if( y == 0 )
|
||||||
|
return static_cast<T>( std::abs( x ) );
|
||||||
|
|
||||||
return static_cast<T>( sqrt( (extended_type) x * x + (extended_type) y * y ) );
|
if( std::is_integral<T>::value )
|
||||||
|
return KiROUND<double, T>( std::hypot( x, y ) );
|
||||||
|
|
||||||
|
return static_cast<T>( std::hypot( x, y ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -482,6 +495,13 @@ typename VECTOR2<T>::extended_type VECTOR2<T>::Dot( const VECTOR2<T>& aVector )
|
||||||
(extended_type) y * (extended_type) aVector.y;
|
(extended_type) y * (extended_type) aVector.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
double VECTOR2<T>::Distance( const VECTOR2<extended_type>& aVector ) const
|
||||||
|
{
|
||||||
|
VECTOR2<double> diff( aVector.x - x, aVector.y - y );
|
||||||
|
return diff.EuclideanNorm();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
|
bool VECTOR2<T>::operator<( const VECTOR2<T>& aVector ) const
|
||||||
|
@ -598,9 +618,9 @@ std::ostream& operator<<( std::ostream& aStream, const VECTOR2<T>& aVector )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Default specializations */
|
/* Default specializations */
|
||||||
typedef VECTOR2<double> VECTOR2D;
|
typedef VECTOR2<double> VECTOR2D;
|
||||||
typedef VECTOR2<int> VECTOR2I;
|
typedef VECTOR2<int32_t> VECTOR2I;
|
||||||
typedef VECTOR2<long long int> VECTOR2L;
|
typedef VECTOR2<int64_t> VECTOR2L;
|
||||||
|
|
||||||
/* KiROUND specialization for vectors */
|
/* KiROUND specialization for vectors */
|
||||||
inline VECTOR2I KiROUND( const VECTOR2D& vec )
|
inline VECTOR2I KiROUND( const VECTOR2D& vec )
|
||||||
|
|
|
@ -125,54 +125,6 @@ const VECTOR2D CalcArcCenter( const VECTOR2D& aStart, const VECTOR2D& aEnd,
|
||||||
const VECTOR2I CalcArcMid( const VECTOR2I& aStart, const VECTOR2I& aEnd, const VECTOR2I& aCenter,
|
const VECTOR2I CalcArcMid( const VECTOR2I& aStart, const VECTOR2I& aEnd, const VECTOR2I& aCenter,
|
||||||
bool aMinArcAngle = true );
|
bool aMinArcAngle = true );
|
||||||
|
|
||||||
inline double EuclideanNorm( const VECTOR2I& vector )
|
|
||||||
{
|
|
||||||
// this is working with doubles
|
|
||||||
return hypot( vector.x, vector.y );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compute the distance between a line and a reference point.
|
|
||||||
*
|
|
||||||
* Reference: http://mathworld.wolfram.com/Point-LineDistance2-Dimensional.html
|
|
||||||
*
|
|
||||||
* @param linePointA Point on line.
|
|
||||||
* @param linePointB Point on line.
|
|
||||||
* @param referencePoint Reference point.
|
|
||||||
*/
|
|
||||||
inline double DistanceLinePoint( const VECTOR2I& linePointA, const VECTOR2I& linePointB,
|
|
||||||
const VECTOR2I& referencePoint )
|
|
||||||
{
|
|
||||||
// Some of the multiple double casts are redundant. However in the previous definition
|
|
||||||
// the cast was (implicitly) done too late, just before the division (EuclideanNorm gives
|
|
||||||
// a double so from int it would be promoted); that means that the whole expression were
|
|
||||||
// vulnerable to overflow during int multiplications
|
|
||||||
return fabs( ( static_cast<double>( linePointB.x - linePointA.x ) *
|
|
||||||
static_cast<double>( linePointA.y - referencePoint.y ) -
|
|
||||||
static_cast<double>( linePointA.x - referencePoint.x ) *
|
|
||||||
static_cast<double>( linePointB.y - linePointA.y) )
|
|
||||||
/ EuclideanNorm( linePointB - linePointA ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Test if two points are near each other.
|
|
||||||
*
|
|
||||||
* @param pointA First point.
|
|
||||||
* @param pointB Second point.
|
|
||||||
* @param threshold The maximum distance.
|
|
||||||
* @return true if \a pointA is within \a threshold of \a pointB otherwise false.
|
|
||||||
*/
|
|
||||||
inline bool HitTestPoints( const VECTOR2I& pointA, const VECTOR2I& pointB, double threshold )
|
|
||||||
{
|
|
||||||
VECTOR2I vectorAB = pointB - pointA;
|
|
||||||
|
|
||||||
// Compare the distances squared. The double is needed to avoid overflow during int
|
|
||||||
// multiplication
|
|
||||||
double sqdistance = (double)vectorAB.x * vectorAB.x + (double)vectorAB.y * vectorAB.y;
|
|
||||||
|
|
||||||
return sqdistance < threshold * threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if \a aRefPoint is with \a aDistance on the line defined by \a aStart and \a aEnd..
|
* Test if \a aRefPoint is with \a aDistance on the line defined by \a aStart and \a aEnd..
|
||||||
*
|
*
|
||||||
|
@ -184,18 +136,6 @@ inline bool HitTestPoints( const VECTOR2I& pointA, const VECTOR2I& pointB, doubl
|
||||||
bool TestSegmentHit( const VECTOR2I& aRefPoint, const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
bool TestSegmentHit( const VECTOR2I& aRefPoint, const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
||||||
int aDist );
|
int aDist );
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the length of a line segment defined by \a aPointA and \a aPointB.
|
|
||||||
*
|
|
||||||
* See also EuclideanNorm and Distance for the single vector or four scalar versions.
|
|
||||||
*
|
|
||||||
* @return Length of a line (as double)
|
|
||||||
*/
|
|
||||||
inline double GetLineLength( const VECTOR2I& aPointA, const VECTOR2I& aPointB )
|
|
||||||
{
|
|
||||||
return hypot( (double) aPointA.x - aPointB.x, (double) aPointA.y - aPointB.y );
|
|
||||||
}
|
|
||||||
|
|
||||||
// These are the usual degrees <-> radians conversion routines
|
// These are the usual degrees <-> radians conversion routines
|
||||||
inline double DEG2RAD( double deg ) { return deg * M_PI / 180.0; }
|
inline double DEG2RAD( double deg ) { return deg * M_PI / 180.0; }
|
||||||
inline double RAD2DEG( double rad ) { return rad * 180.0 / M_PI; }
|
inline double RAD2DEG( double rad ) { return rad * 180.0 / M_PI; }
|
||||||
|
|
|
@ -163,7 +163,7 @@ void TransformOvalToPolygon( SHAPE_POLY_SET& aBuffer, const VECTOR2I& aStart, co
|
||||||
}
|
}
|
||||||
|
|
||||||
EDA_ANGLE delta_angle( endp );
|
EDA_ANGLE delta_angle( endp );
|
||||||
int seg_len = KiROUND( EuclideanNorm( endp ) );
|
int seg_len = endp.EuclideanNorm();
|
||||||
|
|
||||||
// Compute the outlines of the segment, and creates a polygon
|
// Compute the outlines of the segment, and creates a polygon
|
||||||
// Note: the polygonal shape is built from the equivalent horizontal
|
// Note: the polygonal shape is built from the equivalent horizontal
|
||||||
|
|
|
@ -429,7 +429,7 @@ bool SHAPE_ARC::Collide( const VECTOR2I& aP, int aClearance, int* aActual,
|
||||||
if( !bbox.Contains( aP ) )
|
if( !bbox.Contains( aP ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
VECTOR2I center = GetCenter();
|
VECTOR2L center = GetCenter();
|
||||||
double radius = ( center - m_start ).EuclideanNorm();
|
double radius = ( center - m_start ).EuclideanNorm();
|
||||||
CIRCLE fullCircle( center, radius );
|
CIRCLE fullCircle( center, radius );
|
||||||
VECTOR2I nearestPt = fullCircle.NearestPoint( aP );
|
VECTOR2I nearestPt = fullCircle.NearestPoint( aP );
|
||||||
|
@ -488,14 +488,16 @@ bool SHAPE_ARC::Collide( const VECTOR2I& aP, int aClearance, int* aActual,
|
||||||
|
|
||||||
EDA_ANGLE SHAPE_ARC::GetStartAngle() const
|
EDA_ANGLE SHAPE_ARC::GetStartAngle() const
|
||||||
{
|
{
|
||||||
EDA_ANGLE angle( m_start - GetCenter() );
|
VECTOR2L center = GetCenter();
|
||||||
|
EDA_ANGLE angle( m_start - center );
|
||||||
return angle.Normalize();
|
return angle.Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EDA_ANGLE SHAPE_ARC::GetEndAngle() const
|
EDA_ANGLE SHAPE_ARC::GetEndAngle() const
|
||||||
{
|
{
|
||||||
EDA_ANGLE angle( m_end - GetCenter() );
|
VECTOR2L center = GetCenter();
|
||||||
|
EDA_ANGLE angle( m_end - center );
|
||||||
return angle.Normalize();
|
return angle.Normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,7 +525,7 @@ EDA_ANGLE SHAPE_ARC::GetCentralAngle() const
|
||||||
if( m_start == m_end )
|
if( m_start == m_end )
|
||||||
return ANGLE_360;
|
return ANGLE_360;
|
||||||
|
|
||||||
VECTOR2I center = GetCenter();
|
VECTOR2L center = GetCenter();
|
||||||
EDA_ANGLE angle1 = EDA_ANGLE( m_mid - center ) - EDA_ANGLE( m_start - center );
|
EDA_ANGLE angle1 = EDA_ANGLE( m_mid - center ) - EDA_ANGLE( m_start - center );
|
||||||
EDA_ANGLE angle2 = EDA_ANGLE( m_end - center ) - EDA_ANGLE( m_mid - center );
|
EDA_ANGLE angle2 = EDA_ANGLE( m_end - center ) - EDA_ANGLE( m_mid - center );
|
||||||
|
|
||||||
|
|
|
@ -726,12 +726,12 @@ static int getMinDist( BOARD_CONNECTED_ITEM* aItem, const VECTOR2I& aPoint )
|
||||||
{
|
{
|
||||||
PCB_TRACK* track = static_cast<PCB_TRACK*>( aItem );
|
PCB_TRACK* track = static_cast<PCB_TRACK*>( aItem );
|
||||||
|
|
||||||
return std::min( GetLineLength( track->GetStart(), aPoint ),
|
return std::min( track->GetStart().Distance(aPoint ),
|
||||||
GetLineLength( track->GetEnd(), aPoint ) );
|
track->GetEnd().Distance( aPoint ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return GetLineLength( aItem->GetPosition(), aPoint );
|
return aItem->GetPosition().Distance( aPoint );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1196,7 +1196,7 @@ void GENCAD_EXPORTER::FootprintWriteShape( FOOTPRINT* aFootprint, const wxString
|
||||||
|
|
||||||
case SHAPE_T::CIRCLE:
|
case SHAPE_T::CIRCLE:
|
||||||
{
|
{
|
||||||
int radius = KiROUND( GetLineLength( end, start ) );
|
int radius = KiROUND( end.Distance( start ) );
|
||||||
|
|
||||||
fprintf( m_file, "CIRCLE %g %g %g\n",
|
fprintf( m_file, "CIRCLE %g %g %g\n",
|
||||||
start.x / SCALE_FACTOR,
|
start.x / SCALE_FACTOR,
|
||||||
|
|
|
@ -50,9 +50,9 @@
|
||||||
static void gen_arc( std::vector<VECTOR2I>& aBuffer, const VECTOR2I& aStartPoint,
|
static void gen_arc( std::vector<VECTOR2I>& aBuffer, const VECTOR2I& aStartPoint,
|
||||||
const VECTOR2I& aCenter, const EDA_ANGLE& a_ArcAngle )
|
const VECTOR2I& aCenter, const EDA_ANGLE& a_ArcAngle )
|
||||||
{
|
{
|
||||||
auto first_point = aStartPoint - aCenter;
|
VECTOR2D first_point = VECTOR2D( aStartPoint ) - aCenter;
|
||||||
auto radius = KiROUND( EuclideanNorm( first_point ) );
|
double radius = first_point.EuclideanNorm();
|
||||||
int seg_count = GetArcToSegmentCount( radius, ARC_HIGH_DEF, a_ArcAngle );
|
int seg_count = GetArcToSegmentCount( radius, ARC_HIGH_DEF, a_ArcAngle );
|
||||||
|
|
||||||
double increment_angle = a_ArcAngle.AsRadians() / seg_count;
|
double increment_angle = a_ArcAngle.AsRadians() / seg_count;
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ static INDUCTOR_S_SHAPE_RESULT BuildCornersList_S_Shape( std::vector<VECTOR2I>&
|
||||||
|
|
||||||
auto pt = aEndPoint - aStartPoint;
|
auto pt = aEndPoint - aStartPoint;
|
||||||
EDA_ANGLE angle( pt );
|
EDA_ANGLE angle( pt );
|
||||||
int min_len = KiROUND( EuclideanNorm( pt ) );
|
int min_len = pt.EuclideanNorm();
|
||||||
int segm_len = 0; // length of segments
|
int segm_len = 0; // length of segments
|
||||||
int full_len; // full len of shape (sum of length of all segments + arcs)
|
int full_len; // full len of shape (sum of length of all segments + arcs)
|
||||||
|
|
||||||
|
@ -358,7 +358,7 @@ FOOTPRINT* MICROWAVE_TOOL::createMicrowaveInductor( MICROWAVE_INDUCTOR_PATTERN&
|
||||||
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
|
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
|
||||||
|
|
||||||
VECTOR2I pt = aInductorPattern.m_End - aInductorPattern.m_Start;
|
VECTOR2I pt = aInductorPattern.m_End - aInductorPattern.m_Start;
|
||||||
int min_len = KiROUND( EuclideanNorm( pt ) );
|
int min_len = pt.EuclideanNorm();
|
||||||
aInductorPattern.m_Length = min_len;
|
aInductorPattern.m_Length = min_len;
|
||||||
|
|
||||||
// Enter the desired length.
|
// Enter the desired length.
|
||||||
|
@ -462,4 +462,4 @@ FOOTPRINT* MICROWAVE_TOOL::createMicrowaveInductor( MICROWAVE_INDUCTOR_PATTERN&
|
||||||
footprint->Value().SetPosition( valPos );
|
footprint->Value().SetPosition( valPos );
|
||||||
|
|
||||||
return footprint;
|
return footprint;
|
||||||
}
|
}
|
|
@ -105,8 +105,8 @@ void HelperShapeLineChainFromAltiumVertices( SHAPE_LINE_CHAIN& aLine,
|
||||||
VECTOR2I arcStart = vertex.center + arcStartOffset;
|
VECTOR2I arcStart = vertex.center + arcStartOffset;
|
||||||
VECTOR2I arcEnd = vertex.center + arcEndOffset;
|
VECTOR2I arcEnd = vertex.center + arcEndOffset;
|
||||||
|
|
||||||
if( GetLineLength( arcStart, vertex.position )
|
if( arcStart.Distance( vertex.position )
|
||||||
< GetLineLength( arcEnd, vertex.position ) )
|
< arcEnd.Distance( vertex.position ) )
|
||||||
{
|
{
|
||||||
aLine.Append( SHAPE_ARC( vertex.center, arcStart, -angle ) );
|
aLine.Append( SHAPE_ARC( vertex.center, arcStart, -angle ) );
|
||||||
}
|
}
|
||||||
|
@ -1413,7 +1413,7 @@ void ALTIUM_PCB::HelperParseDimensions6Linear( const ADIMENSION6& aElem )
|
||||||
|
|
||||||
dimension->SetEnd( *intersection );
|
dimension->SetEnd( *intersection );
|
||||||
|
|
||||||
int height = static_cast<int>( EuclideanNorm( direction ) );
|
int height = direction.EuclideanNorm();
|
||||||
|
|
||||||
if( ( direction.x > 0 || direction.y < 0 ) != ( aElem.angle >= 180.0 ) )
|
if( ( direction.x > 0 || direction.y < 0 ) != ( aElem.angle >= 180.0 ) )
|
||||||
height = -height;
|
height = -height;
|
||||||
|
@ -1603,7 +1603,7 @@ void ALTIUM_PCB::HelperParseDimensions6Leader( const ADIMENSION6& aElem )
|
||||||
|
|
||||||
if( dirVec.x != 0 || dirVec.y != 0 )
|
if( dirVec.x != 0 || dirVec.y != 0 )
|
||||||
{
|
{
|
||||||
double scaling = EuclideanNorm( dirVec ) / aElem.arrowsize;
|
double scaling = dirVec.EuclideanNorm() / aElem.arrowsize;
|
||||||
VECTOR2I arrVec =
|
VECTOR2I arrVec =
|
||||||
VECTOR2I( KiROUND( dirVec.x / scaling ), KiROUND( dirVec.y / scaling ) );
|
VECTOR2I( KiROUND( dirVec.x / scaling ), KiROUND( dirVec.y / scaling ) );
|
||||||
RotatePoint( arrVec, EDA_ANGLE( 20.0, DEGREES_T ) );
|
RotatePoint( arrVec, EDA_ANGLE( 20.0, DEGREES_T ) );
|
||||||
|
|
|
@ -1097,7 +1097,7 @@ void PCB_IO_EAGLE::loadPlain( wxXmlNode* aGraphics )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int offset = GetLineLength( pt3, pt1 );
|
int offset = KiROUND( pt3.Distance( pt1 ) );
|
||||||
|
|
||||||
if( pt1.y > pt2.y )
|
if( pt1.y > pt2.y )
|
||||||
dimension->SetHeight( offset );
|
dimension->SetHeight( offset );
|
||||||
|
|
|
@ -557,7 +557,7 @@ FOOTPRINT* GPCB_FPL_CACHE::parseFOOTPRINT( LINE_READER* aLineReader )
|
||||||
|
|
||||||
VECTOR2I padPos( ( x1 + x2 ) / 2, ( y1 + y2 ) / 2 );
|
VECTOR2I padPos( ( x1 + x2 ) / 2, ( y1 + y2 ) / 2 );
|
||||||
|
|
||||||
pad->SetSize( VECTOR2I( KiROUND( EuclideanNorm( delta ) ) + width, width ) );
|
pad->SetSize( VECTOR2I( delta.EuclideanNorm() + width, width ) );
|
||||||
|
|
||||||
padPos += footprint->GetPosition();
|
padPos += footprint->GetPosition();
|
||||||
pad->SetPosition( padPos );
|
pad->SetPosition( padPos );
|
||||||
|
|
|
@ -589,14 +589,14 @@ EDA_ITEM_FLAGS PCB_TRACK::IsPointOnEnds( const VECTOR2I& point, int min_dist ) c
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
double dist = GetLineLength( m_Start, point );
|
double dist = m_Start.Distance( point );
|
||||||
|
|
||||||
if( min_dist >= KiROUND( dist ) )
|
if( min_dist >= dist )
|
||||||
result |= STARTPOINT;
|
result |= STARTPOINT;
|
||||||
|
|
||||||
dist = GetLineLength( m_End, point );
|
dist = m_End.Distance( point );
|
||||||
|
|
||||||
if( min_dist >= KiROUND( dist ) )
|
if( min_dist >= dist )
|
||||||
result |= ENDPOINT;
|
result |= ENDPOINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -651,7 +651,7 @@ const BOX2I PCB_TRACK::GetBoundingBox() const
|
||||||
|
|
||||||
double PCB_TRACK::GetLength() const
|
double PCB_TRACK::GetLength() const
|
||||||
{
|
{
|
||||||
return GetLineLength( m_Start, m_End );
|
return m_Start.Distance( m_End );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -742,8 +742,9 @@ void PCB_ARC::Flip( const VECTOR2I& aCentre, bool aFlipLeftRight )
|
||||||
|
|
||||||
bool PCB_ARC::IsCCW() const
|
bool PCB_ARC::IsCCW() const
|
||||||
{
|
{
|
||||||
VECTOR2I start_end = m_End - m_Start;
|
VECTOR2L start = m_Start;
|
||||||
VECTOR2I start_mid = m_Mid - m_Start;
|
VECTOR2L start_end = m_End - start;
|
||||||
|
VECTOR2L start_mid = m_Mid - start;
|
||||||
|
|
||||||
return start_end.Cross( start_mid ) < 0;
|
return start_end.Cross( start_mid ) < 0;
|
||||||
}
|
}
|
||||||
|
@ -1399,18 +1400,17 @@ bool PCB_TRACK::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||||
|
|
||||||
bool PCB_ARC::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
bool PCB_ARC::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
|
||||||
{
|
{
|
||||||
int max_dist = aAccuracy + ( m_Width / 2 );
|
double max_dist = aAccuracy + ( m_Width / 2.0 );
|
||||||
|
|
||||||
// Short-circuit common cases where the arc is connected to a track or via at an endpoint
|
// Short-circuit common cases where the arc is connected to a track or via at an endpoint
|
||||||
if( EuclideanNorm( GetStart() - aPosition ) <= max_dist ||
|
if( GetStart().Distance( aPosition ) <= max_dist || GetEnd().Distance( aPosition ) <= max_dist )
|
||||||
EuclideanNorm( GetEnd() - aPosition ) <= max_dist )
|
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
VECTOR2I center = GetPosition();
|
VECTOR2L center = GetPosition();
|
||||||
VECTOR2I relpos = aPosition - center;
|
VECTOR2L relpos = aPosition - center;
|
||||||
double dist = EuclideanNorm( relpos );
|
int64_t dist = relpos.EuclideanNorm();
|
||||||
double radius = GetRadius();
|
double radius = GetRadius();
|
||||||
|
|
||||||
if( std::abs( dist - radius ) > max_dist )
|
if( std::abs( dist - radius ) > max_dist )
|
||||||
|
@ -1536,13 +1536,13 @@ VECTOR2I PCB_ARC::GetPosition() const
|
||||||
double PCB_ARC::GetRadius() const
|
double PCB_ARC::GetRadius() const
|
||||||
{
|
{
|
||||||
auto center = CalcArcCenter( m_Start, m_Mid , m_End );
|
auto center = CalcArcCenter( m_Start, m_Mid , m_End );
|
||||||
return GetLineLength( center, m_Start );
|
return center.Distance( m_Start );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
EDA_ANGLE PCB_ARC::GetAngle() const
|
EDA_ANGLE PCB_ARC::GetAngle() const
|
||||||
{
|
{
|
||||||
VECTOR2I center = GetPosition();
|
VECTOR2D center = GetPosition();
|
||||||
EDA_ANGLE angle1 = EDA_ANGLE( m_Mid - center ) - EDA_ANGLE( m_Start - center );
|
EDA_ANGLE angle1 = EDA_ANGLE( m_Mid - center ) - EDA_ANGLE( m_Start - center );
|
||||||
EDA_ANGLE angle2 = EDA_ANGLE( m_End - center ) - EDA_ANGLE( m_Mid - center );
|
EDA_ANGLE angle2 = EDA_ANGLE( m_End - center ) - EDA_ANGLE( m_Mid - center );
|
||||||
|
|
||||||
|
@ -1552,7 +1552,7 @@ EDA_ANGLE PCB_ARC::GetAngle() const
|
||||||
|
|
||||||
EDA_ANGLE PCB_ARC::GetArcAngleStart() const
|
EDA_ANGLE PCB_ARC::GetArcAngleStart() const
|
||||||
{
|
{
|
||||||
VECTOR2I pos( GetPosition() );
|
VECTOR2D pos( GetPosition() );
|
||||||
EDA_ANGLE angleStart( m_Start - pos );
|
EDA_ANGLE angleStart( m_Start - pos );
|
||||||
|
|
||||||
return angleStart.Normalize();
|
return angleStart.Normalize();
|
||||||
|
@ -1562,7 +1562,7 @@ EDA_ANGLE PCB_ARC::GetArcAngleStart() const
|
||||||
// Note: used in python tests. Ignore CLion's claim that it's unused....
|
// Note: used in python tests. Ignore CLion's claim that it's unused....
|
||||||
EDA_ANGLE PCB_ARC::GetArcAngleEnd() const
|
EDA_ANGLE PCB_ARC::GetArcAngleEnd() const
|
||||||
{
|
{
|
||||||
VECTOR2I pos( GetPosition() );
|
VECTOR2D pos( GetPosition() );
|
||||||
EDA_ANGLE angleEnd( m_End - pos );
|
EDA_ANGLE angleEnd( m_End - pos );
|
||||||
|
|
||||||
return angleEnd.Normalize();
|
return angleEnd.Normalize();
|
||||||
|
|
|
@ -675,8 +675,8 @@ int EDIT_TOOL::DragArcTrack( const TOOL_EVENT& aEvent )
|
||||||
auto isTrackStartClosestToArcStart =
|
auto isTrackStartClosestToArcStart =
|
||||||
[&]( PCB_TRACK* aTrack ) -> bool
|
[&]( PCB_TRACK* aTrack ) -> bool
|
||||||
{
|
{
|
||||||
double trackStartToArcStart = GetLineLength( aTrack->GetStart(), theArc->GetStart() );
|
double trackStartToArcStart = aTrack->GetStart().Distance( theArc->GetStart() );
|
||||||
double trackEndToArcStart = GetLineLength( aTrack->GetEnd(), theArc->GetStart() );
|
double trackEndToArcStart = aTrack->GetEnd().Distance( theArc->GetStart() );
|
||||||
|
|
||||||
return trackStartToArcStart < trackEndToArcStart;
|
return trackStartToArcStart < trackEndToArcStart;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1473,7 +1473,7 @@ void PCB_POINT_EDITOR::updateItem( BOARD_COMMIT* aCommit )
|
||||||
case PAD_SHAPE::CIRCLE:
|
case PAD_SHAPE::CIRCLE:
|
||||||
{
|
{
|
||||||
VECTOR2I end = m_editPoints->Point( 0 ).GetPosition();
|
VECTOR2I end = m_editPoints->Point( 0 ).GetPosition();
|
||||||
int diameter = (int) EuclideanNorm( end - pad->GetPosition() ) * 2;
|
int diameter = ( end - pad->GetPosition() ).SquaredEuclideanNorm();
|
||||||
|
|
||||||
pad->SetSize( VECTOR2I( diameter, diameter ) );
|
pad->SetSize( VECTOR2I( diameter, diameter ) );
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue