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;