diff --git a/common/drawing_sheet/ds_draw_item.cpp b/common/drawing_sheet/ds_draw_item.cpp index e8f17d1cdb..f87280e2d0 100644 --- a/common/drawing_sheet/ds_draw_item.cpp +++ b/common/drawing_sheet/ds_draw_item.cpp @@ -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() ) ) ); } diff --git a/common/eda_shape.cpp b/common/eda_shape.cpp index 0b450d3e3e..a6ed0dbfb9 100644 --- a/common/eda_shape.cpp +++ b/common/eda_shape.cpp @@ -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; } } diff --git a/common/plotters/plotter.cpp b/common/plotters/plotter.cpp index 34e72cf877..5085d1cc48 100644 --- a/common/plotters/plotter.cpp +++ b/common/plotters/plotter.cpp @@ -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 ); diff --git a/eeschema/sch_line.cpp b/eeschema/sch_line.cpp index 29caf7542c..8233e2f786 100644 --- a/eeschema/sch_line.cpp +++ b/eeschema/sch_line.cpp @@ -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 ) ) ); } diff --git a/eeschema/tools/ee_point_editor.cpp b/eeschema/tools/ee_point_editor.cpp index 1a5755bfa9..4b55474d09 100644 --- a/eeschema/tools/ee_point_editor.cpp +++ b/eeschema/tools/ee_point_editor.cpp @@ -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 ) { diff --git a/eeschema/tools/ee_selection_tool.cpp b/eeschema/tools/ee_selection_tool.cpp index 1272537e90..6c17176a1b 100644 --- a/eeschema/tools/ee_selection_tool.cpp +++ b/eeschema/tools/ee_selection_tool.cpp @@ -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 diff --git a/gerbview/am_primitive.cpp b/gerbview/am_primitive.cpp index 80135abfcb..8d57fc6c54 100644 --- a/gerbview/am_primitive.cpp +++ b/gerbview/am_primitive.cpp @@ -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" diff --git a/gerbview/gerber_draw_item.cpp b/gerbview/gerber_draw_item.cpp index 1a79327663..0087a08391 100644 --- a/gerbview/gerber_draw_item.cpp +++ b/gerbview/gerber_draw_item.cpp @@ -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: diff --git a/gerbview/gerbview_painter.cpp b/gerbview/gerbview_painter.cpp index 1d1525b802..783d559f4e 100644 --- a/gerbview/gerbview_painter.cpp +++ b/gerbview/gerbview_painter.cpp @@ -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; diff --git a/libs/kimath/include/geometry/eda_angle.h b/libs/kimath/include/geometry/eda_angle.h index 3fd3dc143b..912f42c6a6 100644 --- a/libs/kimath/include/geometry/eda_angle.h +++ b/libs/kimath/include/geometry/eda_angle.h @@ -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 ) {} diff --git a/libs/kimath/include/geometry/shape_arc.h b/libs/kimath/include/geometry/shape_arc.h index 1f11eeebc6..048d0d13ae 100644 --- a/libs/kimath/include/geometry/shape_arc.h +++ b/libs/kimath/include/geometry/shape_arc.h @@ -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; } diff --git a/libs/kimath/include/math/vector2d.h b/libs/kimath/include/math/vector2d.h index e1d68dd30d..aa1cb51864 100644 --- a/libs/kimath/include/math/vector2d.h +++ b/libs/kimath/include/math/vector2d.h @@ -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 ) diff --git a/libs/kimath/include/trigo.h b/libs/kimath/include/trigo.h index 639907d17c..e57b1e4652 100644 --- a/libs/kimath/include/trigo.h +++ b/libs/kimath/include/trigo.h @@ -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; } diff --git a/libs/kimath/src/convert_basic_shapes_to_polygon.cpp b/libs/kimath/src/convert_basic_shapes_to_polygon.cpp index 17c1d07a82..48729c4d3f 100644 --- a/libs/kimath/src/convert_basic_shapes_to_polygon.cpp +++ b/libs/kimath/src/convert_basic_shapes_to_polygon.cpp @@ -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 diff --git a/libs/kimath/src/geometry/shape_arc.cpp b/libs/kimath/src/geometry/shape_arc.cpp index cb23d30989..8f944a7480 100644 --- a/libs/kimath/src/geometry/shape_arc.cpp +++ b/libs/kimath/src/geometry/shape_arc.cpp @@ -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 ); diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp index fec89f91b0..f122ac78b5 100644 --- a/pcbnew/connectivity/connectivity_data.cpp +++ b/pcbnew/connectivity/connectivity_data.cpp @@ -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 ); } } diff --git a/pcbnew/exporters/export_gencad_writer.cpp b/pcbnew/exporters/export_gencad_writer.cpp index 31f4e71d43..6268277d6c 100644 --- a/pcbnew/exporters/export_gencad_writer.cpp +++ b/pcbnew/exporters/export_gencad_writer.cpp @@ -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, diff --git a/pcbnew/microwave/microwave_inductor.cpp b/pcbnew/microwave/microwave_inductor.cpp index 8684574df2..e198956812 100644 --- a/pcbnew/microwave/microwave_inductor.cpp +++ b/pcbnew/microwave/microwave_inductor.cpp @@ -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; -} +} \ No newline at end of file diff --git a/pcbnew/pcb_io/altium/altium_pcb.cpp b/pcbnew/pcb_io/altium/altium_pcb.cpp index 928808130d..a164a87f08 100644 --- a/pcbnew/pcb_io/altium/altium_pcb.cpp +++ b/pcbnew/pcb_io/altium/altium_pcb.cpp @@ -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 ) ); diff --git a/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp b/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp index 6e4879c8ab..58f762ad70 100644 --- a/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp +++ b/pcbnew/pcb_io/eagle/pcb_io_eagle.cpp @@ -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 ); diff --git a/pcbnew/pcb_io/geda/pcb_io_geda.cpp b/pcbnew/pcb_io/geda/pcb_io_geda.cpp index 80ecd8162b..0cf71a09db 100644 --- a/pcbnew/pcb_io/geda/pcb_io_geda.cpp +++ b/pcbnew/pcb_io/geda/pcb_io_geda.cpp @@ -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 ); diff --git a/pcbnew/pcb_track.cpp b/pcbnew/pcb_track.cpp index bd9e92cacd..7897c8dbed 100644 --- a/pcbnew/pcb_track.cpp +++ b/pcbnew/pcb_track.cpp @@ -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(); diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index b71ac973b5..5f4917389e 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -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; }; diff --git a/pcbnew/tools/pcb_point_editor.cpp b/pcbnew/tools/pcb_point_editor.cpp index 36a2520648..5fd33f48b4 100644 --- a/pcbnew/tools/pcb_point_editor.cpp +++ b/pcbnew/tools/pcb_point_editor.cpp @@ -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;