From fcdaa4a59e6b50216f1c964975abe4f5038217a4 Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Tue, 23 Apr 2024 19:19:49 +0300 Subject: [PATCH] Cache center point and radius along with BBox in SHAPE_ARC. --- libs/kimath/include/geometry/shape_arc.h | 15 +++++---- libs/kimath/src/geometry/shape_arc.cpp | 43 ++++++++++++------------ 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/libs/kimath/include/geometry/shape_arc.h b/libs/kimath/include/geometry/shape_arc.h index ce306c44fd..9c20be5c84 100644 --- a/libs/kimath/include/geometry/shape_arc.h +++ b/libs/kimath/include/geometry/shape_arc.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2018 CERN - * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2019-2024 KiCad Developers, see AUTHORS.txt for contributors. * @author Tomasz Wlostowski * * This program is free software; you can redistribute it and/or @@ -39,7 +39,8 @@ public: SHAPE_ARC() : SHAPE( SH_ARC ), - m_width( 0 ) + m_width( 0 ), + m_radius( 0 ) {}; /** @@ -112,7 +113,7 @@ public: const VECTOR2I& GetP0() const { return m_start; } const VECTOR2I& GetP1() const { return m_end; } const VECTOR2I& GetArcMid() const { return m_mid; } - VECTOR2I GetCenter() const; + const VECTOR2I& GetCenter() const; const BOX2I BBox( int aClearance = 0 ) const override; @@ -256,7 +257,7 @@ private: ( ecoord{ aB.y } - aA.y ) * ( ecoord{ aC.x } - aA.x ); } - void update_bbox(); + void update_values(); bool sliceContainsPoint( const VECTOR2I& p ) const; @@ -264,9 +265,11 @@ private: VECTOR2I m_start; VECTOR2I m_mid; VECTOR2I m_end; - int m_width; - BOX2I m_bbox; + + BOX2I m_bbox; // Calculated value + VECTOR2I m_center; // Calculated value + double m_radius; // Calculated value }; // Required for Boost Test BOOST_CHECK_EQUAL: diff --git a/libs/kimath/src/geometry/shape_arc.cpp b/libs/kimath/src/geometry/shape_arc.cpp index c1c9815516..65e75b7f56 100644 --- a/libs/kimath/src/geometry/shape_arc.cpp +++ b/libs/kimath/src/geometry/shape_arc.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2017 CERN - * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2019-2024 KiCad Developers, see AUTHORS.txt for contributors. * @author Tomasz Wlostowski * * This program is free software; you can redistribute it and/or @@ -58,7 +58,7 @@ SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint m_mid = VECTOR2I( KiROUND( mid.x ), KiROUND( mid.y ) ); m_end = VECTOR2I( KiROUND( end.x ), KiROUND( end.y ) ); - update_bbox(); + update_values(); } @@ -70,7 +70,7 @@ SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcStart, const VECTOR2I& aArcMid, m_end( aArcEnd ), m_width( aWidth ) { - update_bbox(); + update_values(); } @@ -174,7 +174,7 @@ SHAPE_ARC::SHAPE_ARC( const SEG& aSegmentA, const SEG& aSegmentB, int aRadius, i RotatePoint( m_mid, arcCenter, midPointRotAngle ); } - update_bbox(); + update_values(); } @@ -186,6 +186,8 @@ SHAPE_ARC::SHAPE_ARC( const SHAPE_ARC& aOther ) m_mid = aOther.m_mid; m_width = aOther.m_width; m_bbox = aOther.m_bbox; + m_center = aOther.m_center; + m_radius = aOther.m_radius; } @@ -201,7 +203,7 @@ SHAPE_ARC& SHAPE_ARC::ConstructFromStartEndAngle( const VECTOR2I& aStart, const RotatePoint( m_mid, center, -aAngle / 2.0 ); - update_bbox(); + update_values(); return *this; } @@ -233,7 +235,7 @@ SHAPE_ARC& SHAPE_ARC::ConstructFromStartEndCenter( const VECTOR2I& aStart, const RotatePoint( m_mid, aCenter, -angle / 2.0 ); - update_bbox(); + update_values(); return *this; } @@ -316,8 +318,11 @@ int SHAPE_ARC::Intersect( const SHAPE_ARC& aArc, std::vector* aIpsBuff } -void SHAPE_ARC::update_bbox() +void SHAPE_ARC::update_values() { + m_center = CalcArcCenter( m_start, m_mid, m_end ); + m_radius = std::sqrt( ( VECTOR2D( m_start ) - m_center ).SquaredEuclideanNorm() ); + std::vector points; // Put start and end points in the point list points.push_back( m_start ); @@ -336,18 +341,14 @@ void SHAPE_ARC::update_bbox() // very large radius means the arc is similar to a segment // so do not try to add more points, center cannot be handled // Very large is here > INT_MAX/2 - double d_radius = GetRadius(); - - if( d_radius < (double)INT_MAX/2.0 ) + if( m_radius < (double)INT_MAX/2.0 ) { - VECTOR2I center = GetCenter(); - - const int radius = KiROUND( d_radius ); + const int radius = KiROUND( m_radius ); // count through quadrants included in arc for( int quad_angle = quad_angle_start; quad_angle <= quad_angle_end; ++quad_angle ) { - VECTOR2I quad_pt = center; + VECTOR2I quad_pt = m_center; switch( quad_angle % 4 ) { @@ -471,9 +472,9 @@ EDA_ANGLE SHAPE_ARC::GetEndAngle() const } -VECTOR2I SHAPE_ARC::GetCenter() const +const VECTOR2I& SHAPE_ARC::GetCenter() const { - return CalcArcCenter( m_start, m_mid, m_end ); + return m_center; } @@ -504,7 +505,7 @@ EDA_ANGLE SHAPE_ARC::GetCentralAngle() const double SHAPE_ARC::GetRadius() const { - return std::sqrt( ( m_start - GetCenter() ).SquaredEuclideanNorm() ); + return m_radius; } @@ -579,7 +580,7 @@ void SHAPE_ARC::Move( const VECTOR2I& aVector ) m_start += aVector; m_end += aVector; m_mid += aVector; - update_bbox(); + update_values(); } @@ -589,7 +590,7 @@ void SHAPE_ARC::Rotate( const EDA_ANGLE& aAngle, const VECTOR2I& aCenter ) RotatePoint( m_end, aCenter, aAngle ); RotatePoint( m_mid, aCenter, aAngle ); - update_bbox(); + update_values(); } @@ -609,7 +610,7 @@ void SHAPE_ARC::Mirror( bool aX, bool aY, const VECTOR2I& aVector ) m_mid.y = -m_mid.y + 2 * aVector.y; } - update_bbox(); + update_values(); } @@ -619,7 +620,7 @@ void SHAPE_ARC::Mirror( const SEG& axis ) m_end = axis.ReflectPoint( m_end ); m_mid = axis.ReflectPoint( m_mid ); - update_bbox(); + update_values(); }