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
|
||||
{
|
||||
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:
|
||||
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;
|
||||
|
||||
case SHAPE_T::SEGMENT:
|
||||
return GetLineLength( GetStart(), GetEnd() );
|
||||
return GetStart().Distance( GetEnd() );
|
||||
|
||||
case SHAPE_T::POLY:
|
||||
for( int ii = 0; ii < m_poly.COutline( 0 ).SegmentCount(); ii++ )
|
||||
|
@ -623,11 +623,11 @@ int EDA_SHAPE::GetRadius() const
|
|||
switch( m_shape )
|
||||
{
|
||||
case SHAPE_T::ARC:
|
||||
radius = GetLineLength( m_arcCenter, m_start );
|
||||
radius = m_arcCenter.Distance( m_start );
|
||||
break;
|
||||
|
||||
case SHAPE_T::CIRCLE:
|
||||
radius = GetLineLength( m_start, m_end );
|
||||
radius = m_start.Distance( m_end );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -796,7 +796,7 @@ void EDA_SHAPE::ShapeGetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PA
|
|||
case SHAPE_T::SEGMENT:
|
||||
{
|
||||
aList.emplace_back( _( "Length" ),
|
||||
aFrame->MessageTextFromValue( GetLineLength( GetStart(), GetEnd() ) ));
|
||||
aFrame->MessageTextFromValue( GetStart().Distance( GetEnd() ) ));
|
||||
|
||||
// angle counter-clockwise from 3'o-clock
|
||||
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
|
||||
{
|
||||
int maxdist = aAccuracy;
|
||||
double maxdist = aAccuracy;
|
||||
|
||||
if( GetWidth() > 0 )
|
||||
maxdist += GetWidth() / 2;
|
||||
maxdist += GetWidth() / 2.0;
|
||||
|
||||
switch( m_shape )
|
||||
{
|
||||
case SHAPE_T::CIRCLE:
|
||||
{
|
||||
int radius = GetRadius();
|
||||
|
||||
VECTOR2I::extended_type dist = KiROUND<double, VECTOR2I::extended_type>(
|
||||
EuclideanNorm( aPosition - getCenter() ) );
|
||||
double radius = GetRadius();
|
||||
double dist = aPosition.Distance( getCenter() );
|
||||
|
||||
if( IsFilled() )
|
||||
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:
|
||||
{
|
||||
if( EuclideanNorm( aPosition - m_start ) <= maxdist )
|
||||
if( aPosition.Distance( m_start ) <= maxdist )
|
||||
return true;
|
||||
|
||||
if( EuclideanNorm( aPosition - m_end ) <= maxdist )
|
||||
if( aPosition.Distance( m_end ) <= maxdist )
|
||||
return true;
|
||||
|
||||
VECTOR2I relPos = aPosition - getCenter();
|
||||
int radius = GetRadius();
|
||||
|
||||
VECTOR2I::extended_type dist =
|
||||
KiROUND<double, VECTOR2I::extended_type>( EuclideanNorm( relPos ) );
|
||||
double radius = GetRadius();
|
||||
VECTOR2D relPos( VECTOR2D( aPosition ) - getCenter() );
|
||||
double dist = relPos.EuclideanNorm();
|
||||
|
||||
if( IsFilled() )
|
||||
{
|
||||
|
@ -1491,14 +1487,14 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
|||
|
||||
case 1:
|
||||
m_end = aPosition;
|
||||
radius = sqrt( sq( GetLineLength( m_start, m_end ) ) / 2.0 );
|
||||
radius = m_start.Distance( m_end ) * M_SQRT1_2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case 3:
|
||||
{
|
||||
VECTOR2I v = m_start - m_end;
|
||||
double chordBefore = sq( v.x ) + sq( v.y );
|
||||
double chordBefore = v.SquaredEuclideanNorm();
|
||||
|
||||
if( m_editState == 2 )
|
||||
m_start = aPosition;
|
||||
|
@ -1507,7 +1503,7 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
|||
|
||||
v = m_start - m_end;
|
||||
|
||||
double chordAfter = sq( v.x ) + sq( v.y );
|
||||
double chordAfter = v.SquaredEuclideanNorm();
|
||||
double ratio = 0.0;
|
||||
|
||||
if( chordBefore > 0 )
|
||||
|
@ -1520,8 +1516,8 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
|||
|
||||
case 4:
|
||||
{
|
||||
double radialA = GetLineLength( m_start, aPosition );
|
||||
double radialB = GetLineLength( m_end, aPosition );
|
||||
double radialA = m_start.Distance( aPosition );
|
||||
double radialB = m_end.Distance( aPosition );
|
||||
radius = ( radialA + radialB ) / 2.0;
|
||||
}
|
||||
break;
|
||||
|
@ -1534,9 +1530,9 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
|||
// Calculate center based on start, end, and radius
|
||||
//
|
||||
// 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;
|
||||
double sqRadDiff = sq( radius ) - sq( l / 2 );
|
||||
double sqRadDiff = ( radius * radius ) - 0.25;
|
||||
|
||||
// Calculate 'd', the vector from the chord midpoint to the center
|
||||
VECTOR2D d;
|
||||
|
@ -1575,7 +1571,7 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
|||
|
||||
case 4:
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -491,7 +491,7 @@ void PLOTTER::segmentAsOval( const VECTOR2I& start, const VECTOR2I& end, int aWi
|
|||
EDA_ANGLE orient( size );
|
||||
orient = -orient; // this is due to our Y axis orientation
|
||||
|
||||
size.x = KiROUND( EuclideanNorm( size ) ) + aWidth;
|
||||
size.x = size.EuclideanNorm() + aWidth;
|
||||
size.y = aWidth;
|
||||
|
||||
FlashPadOval( center, size, orient, aTraceMode, nullptr );
|
||||
|
|
|
@ -241,7 +241,7 @@ const BOX2I SCH_LINE::GetBoundingBox() 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,
|
||||
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 )
|
||||
{
|
||||
int distance = (int) DistanceLinePoint( poly.CPoint( i ),
|
||||
poly.CPoint( i + 1 ), cursor );
|
||||
SEG seg = poly.GetSegment( i );
|
||||
int distance = seg.Distance( cursor );
|
||||
|
||||
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];
|
||||
|
||||
if( HitTestPoints( line->GetStartPoint(), aWhere, aCollector.m_Threshold ) )
|
||||
if( line->GetStartPoint().Distance( aWhere ) <= aCollector.m_Threshold )
|
||||
flags = STARTPOINT;
|
||||
else if( HitTestPoints( line->GetEndPoint(), aWhere, aCollector.m_Threshold ) )
|
||||
else if( line->GetEndPoint().Distance( aWhere ) <= aCollector.m_Threshold )
|
||||
flags = ENDPOINT;
|
||||
else
|
||||
flags = STARTPOINT | ENDPOINT;
|
||||
|
@ -1516,8 +1516,7 @@ void EE_SELECTION_TOOL::GuessSelectionCandidates( EE_COLLECTOR& collector, const
|
|||
|
||||
if( line )
|
||||
{
|
||||
dist = KiROUND( DistanceLinePoint( line->GetStartPoint(),
|
||||
line->GetEndPoint(), aPos ) );
|
||||
dist = line->GetSeg().Distance( aPos );
|
||||
}
|
||||
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() );
|
||||
|
||||
if( bbox.Contains( aPos ) )
|
||||
dist = KiROUND( EuclideanNorm( bbox.GetCenter() - aPos ) );
|
||||
dist = bbox.GetCenter().Distance( aPos );
|
||||
else
|
||||
rect.Collide( poss, closestDist, &dist );
|
||||
}
|
||||
else
|
||||
{
|
||||
dist = KiROUND( EuclideanNorm( bbox.GetCenter() - aPos ) );
|
||||
dist = bbox.GetCenter().Distance( aPos );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -460,7 +460,7 @@ void AM_PRIMITIVE::ConvertShapeToPolygon( APERTURE_MACRO* aApertMacro,
|
|||
VECTOR2I end =
|
||||
mapPt( m_Params[4].GetValueFromMacro( aApertMacro ), m_Params[5].GetValueFromMacro( aApertMacro ), m_GerbMetric );
|
||||
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"
|
||||
// and rotate it to have the end point to "end"
|
||||
|
|
|
@ -285,7 +285,7 @@ const BOX2I GERBER_DRAW_ITEM::GetBoundingBox() const
|
|||
|
||||
case GBR_CIRCLE:
|
||||
{
|
||||
double radius = GetLineLength( m_Start, m_End );
|
||||
double radius = m_Start.Distance( m_End );
|
||||
bbox.Inflate( radius, radius );
|
||||
break;
|
||||
}
|
||||
|
@ -490,7 +490,7 @@ void GERBER_DRAW_ITEM::Print( wxDC* aDC, const VECTOR2I& aOffset, GBR_DISPLAY_OP
|
|||
break;
|
||||
|
||||
case GBR_CIRCLE:
|
||||
radius = KiROUND( GetLineLength( m_Start, m_End ) );
|
||||
radius = KiROUND( m_Start.Distance( m_End ) );
|
||||
|
||||
halfPenWidth = m_Size.x >> 1;
|
||||
|
||||
|
@ -867,7 +867,7 @@ bool GERBER_DRAW_ITEM::HitTest( const VECTOR2I& aRefPos, int aAccuracy ) const
|
|||
|
||||
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 );
|
||||
|
||||
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;
|
||||
|
||||
if( m_Flashed )
|
||||
return HitTestPoints( m_Start, ref_pos, radius );
|
||||
return m_Start.Distance( ref_pos ) <= radius;
|
||||
else
|
||||
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;
|
||||
|
||||
case GBR_ARC:
|
||||
size = GetLineLength( m_Start, m_ArcCentre );
|
||||
size = m_Start.Distance( m_ArcCentre );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -297,7 +297,7 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer )
|
|||
case GBR_CIRCLE:
|
||||
{
|
||||
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 );
|
||||
break;
|
||||
}
|
||||
|
@ -313,7 +313,7 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer )
|
|||
|
||||
// Gerber arcs are 3-point (start, center, end)
|
||||
// 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 startVec = VECTOR2D( aItem->GetABPosition( arcStart ) ) - 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() :
|
||||
m_value( 0.0 )
|
||||
{}
|
||||
|
|
|
@ -253,8 +253,9 @@ public:
|
|||
*/
|
||||
bool IsCCW() const
|
||||
{
|
||||
VECTOR2I v1 = m_end - m_mid;
|
||||
VECTOR2I v2 = m_start - m_mid;
|
||||
VECTOR2L mid = m_mid;
|
||||
VECTOR2L v1 = m_end - mid;
|
||||
VECTOR2L v2 = m_start - mid;
|
||||
|
||||
return v1.Cross( v2 ) > 0;
|
||||
}
|
||||
|
|
|
@ -180,6 +180,12 @@ public:
|
|||
*/
|
||||
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
|
||||
|
||||
|
@ -267,8 +273,15 @@ T VECTOR2<T>::EuclideanNorm() const
|
|||
// 45° are common in KiCad, so we can optimize the calculation
|
||||
if( std::abs( x ) == std::abs( y ) )
|
||||
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;
|
||||
}
|
||||
|
||||
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>
|
||||
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 */
|
||||
typedef VECTOR2<double> VECTOR2D;
|
||||
typedef VECTOR2<int> VECTOR2I;
|
||||
typedef VECTOR2<long long int> VECTOR2L;
|
||||
typedef VECTOR2<double> VECTOR2D;
|
||||
typedef VECTOR2<int32_t> VECTOR2I;
|
||||
typedef VECTOR2<int64_t> VECTOR2L;
|
||||
|
||||
/* KiROUND specialization for vectors */
|
||||
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,
|
||||
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..
|
||||
*
|
||||
|
@ -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,
|
||||
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
|
||||
inline double DEG2RAD( double deg ) { return deg * M_PI / 180.0; }
|
||||
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 );
|
||||
int seg_len = KiROUND( EuclideanNorm( endp ) );
|
||||
int seg_len = endp.EuclideanNorm();
|
||||
|
||||
// Compute the outlines of the segment, and creates a polygon
|
||||
// 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 ) )
|
||||
return false;
|
||||
|
||||
VECTOR2I center = GetCenter();
|
||||
VECTOR2L center = GetCenter();
|
||||
double radius = ( center - m_start ).EuclideanNorm();
|
||||
CIRCLE fullCircle( center, radius );
|
||||
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 angle( m_start - GetCenter() );
|
||||
VECTOR2L center = GetCenter();
|
||||
EDA_ANGLE angle( m_start - center );
|
||||
return angle.Normalize();
|
||||
}
|
||||
|
||||
|
||||
EDA_ANGLE SHAPE_ARC::GetEndAngle() const
|
||||
{
|
||||
EDA_ANGLE angle( m_end - GetCenter() );
|
||||
VECTOR2L center = GetCenter();
|
||||
EDA_ANGLE angle( m_end - center );
|
||||
return angle.Normalize();
|
||||
}
|
||||
|
||||
|
@ -523,7 +525,7 @@ EDA_ANGLE SHAPE_ARC::GetCentralAngle() const
|
|||
if( m_start == m_end )
|
||||
return ANGLE_360;
|
||||
|
||||
VECTOR2I center = GetCenter();
|
||||
VECTOR2L center = GetCenter();
|
||||
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 );
|
||||
|
||||
|
|
|
@ -726,12 +726,12 @@ static int getMinDist( BOARD_CONNECTED_ITEM* aItem, const VECTOR2I& aPoint )
|
|||
{
|
||||
PCB_TRACK* track = static_cast<PCB_TRACK*>( aItem );
|
||||
|
||||
return std::min( GetLineLength( track->GetStart(), aPoint ),
|
||||
GetLineLength( track->GetEnd(), aPoint ) );
|
||||
return std::min( track->GetStart().Distance(aPoint ),
|
||||
track->GetEnd().Distance( aPoint ) );
|
||||
}
|
||||
|
||||
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:
|
||||
{
|
||||
int radius = KiROUND( GetLineLength( end, start ) );
|
||||
int radius = KiROUND( end.Distance( start ) );
|
||||
|
||||
fprintf( m_file, "CIRCLE %g %g %g\n",
|
||||
start.x / SCALE_FACTOR,
|
||||
|
|
|
@ -50,9 +50,9 @@
|
|||
static void gen_arc( std::vector<VECTOR2I>& aBuffer, const VECTOR2I& aStartPoint,
|
||||
const VECTOR2I& aCenter, const EDA_ANGLE& a_ArcAngle )
|
||||
{
|
||||
auto first_point = aStartPoint - aCenter;
|
||||
auto radius = KiROUND( EuclideanNorm( first_point ) );
|
||||
int seg_count = GetArcToSegmentCount( radius, ARC_HIGH_DEF, a_ArcAngle );
|
||||
VECTOR2D first_point = VECTOR2D( aStartPoint ) - aCenter;
|
||||
double radius = first_point.EuclideanNorm();
|
||||
int seg_count = GetArcToSegmentCount( radius, ARC_HIGH_DEF, a_ArcAngle );
|
||||
|
||||
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;
|
||||
EDA_ANGLE angle( pt );
|
||||
int min_len = KiROUND( EuclideanNorm( pt ) );
|
||||
int min_len = pt.EuclideanNorm();
|
||||
int segm_len = 0; // length of segments
|
||||
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>();
|
||||
|
||||
VECTOR2I pt = aInductorPattern.m_End - aInductorPattern.m_Start;
|
||||
int min_len = KiROUND( EuclideanNorm( pt ) );
|
||||
int min_len = pt.EuclideanNorm();
|
||||
aInductorPattern.m_Length = min_len;
|
||||
|
||||
// Enter the desired length.
|
||||
|
@ -462,4 +462,4 @@ FOOTPRINT* MICROWAVE_TOOL::createMicrowaveInductor( MICROWAVE_INDUCTOR_PATTERN&
|
|||
footprint->Value().SetPosition( valPos );
|
||||
|
||||
return footprint;
|
||||
}
|
||||
}
|
|
@ -105,8 +105,8 @@ void HelperShapeLineChainFromAltiumVertices( SHAPE_LINE_CHAIN& aLine,
|
|||
VECTOR2I arcStart = vertex.center + arcStartOffset;
|
||||
VECTOR2I arcEnd = vertex.center + arcEndOffset;
|
||||
|
||||
if( GetLineLength( arcStart, vertex.position )
|
||||
< GetLineLength( arcEnd, vertex.position ) )
|
||||
if( arcStart.Distance( vertex.position )
|
||||
< arcEnd.Distance( vertex.position ) )
|
||||
{
|
||||
aLine.Append( SHAPE_ARC( vertex.center, arcStart, -angle ) );
|
||||
}
|
||||
|
@ -1413,7 +1413,7 @@ void ALTIUM_PCB::HelperParseDimensions6Linear( const ADIMENSION6& aElem )
|
|||
|
||||
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 ) )
|
||||
height = -height;
|
||||
|
@ -1603,7 +1603,7 @@ void ALTIUM_PCB::HelperParseDimensions6Leader( const ADIMENSION6& aElem )
|
|||
|
||||
if( dirVec.x != 0 || dirVec.y != 0 )
|
||||
{
|
||||
double scaling = EuclideanNorm( dirVec ) / aElem.arrowsize;
|
||||
double scaling = dirVec.EuclideanNorm() / aElem.arrowsize;
|
||||
VECTOR2I arrVec =
|
||||
VECTOR2I( KiROUND( dirVec.x / scaling ), KiROUND( dirVec.y / scaling ) );
|
||||
RotatePoint( arrVec, EDA_ANGLE( 20.0, DEGREES_T ) );
|
||||
|
|
|
@ -1097,7 +1097,7 @@ void PCB_IO_EAGLE::loadPlain( wxXmlNode* aGraphics )
|
|||
}
|
||||
else
|
||||
{
|
||||
int offset = GetLineLength( pt3, pt1 );
|
||||
int offset = KiROUND( pt3.Distance( pt1 ) );
|
||||
|
||||
if( pt1.y > pt2.y )
|
||||
dimension->SetHeight( offset );
|
||||
|
|
|
@ -557,7 +557,7 @@ FOOTPRINT* GPCB_FPL_CACHE::parseFOOTPRINT( LINE_READER* aLineReader )
|
|||
|
||||
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();
|
||||
pad->SetPosition( padPos );
|
||||
|
|
|
@ -589,14 +589,14 @@ EDA_ITEM_FLAGS PCB_TRACK::IsPointOnEnds( const VECTOR2I& point, int min_dist ) c
|
|||
}
|
||||
else
|
||||
{
|
||||
double dist = GetLineLength( m_Start, point );
|
||||
double dist = m_Start.Distance( point );
|
||||
|
||||
if( min_dist >= KiROUND( dist ) )
|
||||
if( min_dist >= dist )
|
||||
result |= STARTPOINT;
|
||||
|
||||
dist = GetLineLength( m_End, point );
|
||||
dist = m_End.Distance( point );
|
||||
|
||||
if( min_dist >= KiROUND( dist ) )
|
||||
if( min_dist >= dist )
|
||||
result |= ENDPOINT;
|
||||
}
|
||||
|
||||
|
@ -651,7 +651,7 @@ const BOX2I PCB_TRACK::GetBoundingBox() 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
|
||||
{
|
||||
VECTOR2I start_end = m_End - m_Start;
|
||||
VECTOR2I start_mid = m_Mid - m_Start;
|
||||
VECTOR2L start = m_Start;
|
||||
VECTOR2L start_end = m_End - start;
|
||||
VECTOR2L start_mid = m_Mid - start;
|
||||
|
||||
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
|
||||
{
|
||||
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
|
||||
if( EuclideanNorm( GetStart() - aPosition ) <= max_dist ||
|
||||
EuclideanNorm( GetEnd() - aPosition ) <= max_dist )
|
||||
if( GetStart().Distance( aPosition ) <= max_dist || GetEnd().Distance( aPosition ) <= max_dist )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
VECTOR2I center = GetPosition();
|
||||
VECTOR2I relpos = aPosition - center;
|
||||
double dist = EuclideanNorm( relpos );
|
||||
VECTOR2L center = GetPosition();
|
||||
VECTOR2L relpos = aPosition - center;
|
||||
int64_t dist = relpos.EuclideanNorm();
|
||||
double radius = GetRadius();
|
||||
|
||||
if( std::abs( dist - radius ) > max_dist )
|
||||
|
@ -1536,13 +1536,13 @@ VECTOR2I PCB_ARC::GetPosition() const
|
|||
double PCB_ARC::GetRadius() const
|
||||
{
|
||||
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
|
||||
{
|
||||
VECTOR2I center = GetPosition();
|
||||
VECTOR2D center = GetPosition();
|
||||
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 );
|
||||
|
||||
|
@ -1552,7 +1552,7 @@ EDA_ANGLE PCB_ARC::GetAngle() const
|
|||
|
||||
EDA_ANGLE PCB_ARC::GetArcAngleStart() const
|
||||
{
|
||||
VECTOR2I pos( GetPosition() );
|
||||
VECTOR2D pos( GetPosition() );
|
||||
EDA_ANGLE angleStart( m_Start - pos );
|
||||
|
||||
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....
|
||||
EDA_ANGLE PCB_ARC::GetArcAngleEnd() const
|
||||
{
|
||||
VECTOR2I pos( GetPosition() );
|
||||
VECTOR2D pos( GetPosition() );
|
||||
EDA_ANGLE angleEnd( m_End - pos );
|
||||
|
||||
return angleEnd.Normalize();
|
||||
|
|
|
@ -675,8 +675,8 @@ int EDIT_TOOL::DragArcTrack( const TOOL_EVENT& aEvent )
|
|||
auto isTrackStartClosestToArcStart =
|
||||
[&]( PCB_TRACK* aTrack ) -> bool
|
||||
{
|
||||
double trackStartToArcStart = GetLineLength( aTrack->GetStart(), theArc->GetStart() );
|
||||
double trackEndToArcStart = GetLineLength( aTrack->GetEnd(), theArc->GetStart() );
|
||||
double trackStartToArcStart = aTrack->GetStart().Distance( theArc->GetStart() );
|
||||
double trackEndToArcStart = aTrack->GetEnd().Distance( theArc->GetStart() );
|
||||
|
||||
return trackStartToArcStart < trackEndToArcStart;
|
||||
};
|
||||
|
|
|
@ -1473,7 +1473,7 @@ void PCB_POINT_EDITOR::updateItem( BOARD_COMMIT* aCommit )
|
|||
case PAD_SHAPE::CIRCLE:
|
||||
{
|
||||
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 ) );
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue