diff --git a/common/eda_text.cpp b/common/eda_text.cpp index 094d474e00..3271dd273e 100644 --- a/common/eda_text.cpp +++ b/common/eda_text.cpp @@ -868,7 +868,7 @@ int EDA_TEXT::Compare( const EDA_TEXT* aOther ) const TEST_PT( m_attributes.m_Size, aOther->m_attributes.m_Size ); TEST_E( m_attributes.m_StrokeWidth, aOther->m_attributes.m_StrokeWidth ); - TEST( m_attributes.m_Angle.AsTenthsOfADegree(), aOther->m_attributes.m_Angle.AsTenthsOfADegree() ); + TEST( m_attributes.m_Angle.AsDegrees(), aOther->m_attributes.m_Angle.AsDegrees() ); TEST( m_attributes.m_LineSpacing, aOther->m_attributes.m_LineSpacing ); TEST( m_attributes.m_Halign, aOther->m_attributes.m_Halign ); diff --git a/common/hash_eda.cpp b/common/hash_eda.cpp index 9b6691c342..7d0d19e241 100644 --- a/common/hash_eda.cpp +++ b/common/hash_eda.cpp @@ -62,7 +62,7 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags ) hash_combine( ret, footprint->GetPosition().x, footprint->GetPosition().y ); if( aFlags & HASH_ROT ) - hash_combine( ret, footprint->GetOrientation().AsTenthsOfADegree() ); + hash_combine( ret, footprint->GetOrientation().AsDegrees() ); for( BOARD_ITEM* item : footprint->GraphicalItems() ) hash_combine( ret, hash_fp_item( item, aFlags ) ); @@ -96,7 +96,7 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags ) } if( aFlags & HASH_ROT ) - hash_combine( ret, pad->GetOrientation().AsTenthsOfADegree() ); + hash_combine( ret, pad->GetOrientation().AsDegrees() ); if( aFlags & HASH_NET ) hash_combine( ret, pad->GetNetCode() ); @@ -132,7 +132,7 @@ size_t hash_fp_item( const EDA_ITEM* aItem, int aFlags ) } if( aFlags & HASH_ROT ) - hash_combine( ret, text->GetTextAngle().AsTenthsOfADegree() ); + hash_combine( ret, text->GetTextAngle().AsDegrees() ); } break; diff --git a/libs/kimath/include/geometry/eda_angle.h b/libs/kimath/include/geometry/eda_angle.h index a38a19f1ef..c1ce760cce 100644 --- a/libs/kimath/include/geometry/eda_angle.h +++ b/libs/kimath/include/geometry/eda_angle.h @@ -28,9 +28,9 @@ enum EDA_ANGLE_T { - TENTHS_OF_A_DEGREE_T = 1, - DEGREES_T = 10, - RADIANS_T ///< enum value does not matter + TENTHS_OF_A_DEGREE_T, + DEGREES_T, + RADIANS_T }; @@ -44,88 +44,64 @@ public: * Angle type must be explicitly specified at creation, because there is no other way of * knowing what an int or a double represents. */ - EDA_ANGLE( int aValue, EDA_ANGLE_T aAngleType ) : - m_value( 0 ), - m_radians( 0.0 ), - m_initial_type( aAngleType ) + EDA_ANGLE( double aValue, EDA_ANGLE_T aAngleType ) { switch( aAngleType ) { case RADIANS_T: - m_radians = aValue; - m_value = KiROUND( aValue / TENTHS_OF_A_DEGREE_TO_RADIANS ); + m_value = aValue / DEGREES_TO_RADIANS; + break; + + case TENTHS_OF_A_DEGREE_T: + m_value = aValue * 10.0; break; default: - m_value = aValue * aAngleType; + m_value = aValue; } } - EDA_ANGLE( double aValue, EDA_ANGLE_T aAngleType ) : - m_value( 0 ), - m_radians( 0.0 ), - m_initial_type( aAngleType ) - { - switch( aAngleType ) - { - case RADIANS_T: - m_radians = aValue; - m_value = KiROUND( aValue / TENTHS_OF_A_DEGREE_TO_RADIANS ); - break; - - default: - m_value = int( aValue * aAngleType ); - } - } - - explicit EDA_ANGLE( const VECTOR2D& aVector ) : - m_value( 0 ), - m_radians( 0.0 ), - m_initial_type( TENTHS_OF_A_DEGREE_T ) + explicit EDA_ANGLE( const VECTOR2D& aVector ) { if( aVector.x == 0.0 && aVector.y == 0.0 ) { - m_value = 0; + m_value = 0.0; } else if( aVector.y == 0.0 ) { if( aVector.x >= 0 ) - m_value = 0; + m_value = 0.0; else - m_value = -1800; + m_value = -180.0; } else if( aVector.x == 0.0 ) { if( aVector.y >= 0.0 ) - m_value = 900; + m_value = 90.0; else - m_value = -900; + m_value = -90.0; } else if( aVector.x == aVector.y ) { if( aVector.x >= 0.0 ) - m_value = 450; + m_value = 45.0; else - m_value = -1800 + 450; + m_value = -180.0 + 45.0; } else if( aVector.x == -aVector.y ) { if( aVector.x >= 0.0 ) - m_value = -450; + m_value = -45.0; else - m_value = 1800 - 450; + m_value = 180.0 - 45.0; } else { - m_value = KiROUND( atan2( (double) aVector.y, (double) aVector.x ) - / TENTHS_OF_A_DEGREE_TO_RADIANS ); + *this = EDA_ANGLE( atan2( aVector.y, aVector.x ), RADIANS_T ); } } - explicit EDA_ANGLE( const VECTOR2I& aVector ) : - m_value( 0 ), - m_radians( 0.0 ), - m_initial_type( TENTHS_OF_A_DEGREE_T ) + explicit EDA_ANGLE( const VECTOR2I& aVector ) { /* gcc is surprisingly smart in optimizing these conditions in a tree! */ @@ -136,61 +112,46 @@ public: else if( aVector.y == 0 ) { if( aVector.x >= 0 ) - m_value = 0; + m_value = 0.0; else - m_value = -1800; + m_value = -180.0; } else if( aVector.x == 0 ) { if( aVector.y >= 0 ) - m_value = 900; + m_value = 90.0; else - m_value = -900; + m_value = -90.0; } else if( aVector.x == aVector.y ) { if( aVector.x >= 0 ) - m_value = 450; + m_value = 45.0; else - m_value = -1800 + 450; + m_value = -180.0 + 45.0; } else if( aVector.x == -aVector.y ) { if( aVector.x >= 0 ) - m_value = -450; + m_value = -45.0; else - m_value = 1800 - 450; + m_value = 180.0 - 45.0; } else { - m_value = KiROUND( atan2( (double) aVector.y, (double) aVector.x ) - / TENTHS_OF_A_DEGREE_TO_RADIANS ); + *this = EDA_ANGLE( atan2( (double) aVector.y, (double) aVector.x ), RADIANS_T ); } } EDA_ANGLE() : - m_value( 0 ), - m_radians( 0.0 ), - m_initial_type( RADIANS_T ) + m_value( 0.0 ) {} - inline double AsDegrees() const { return m_value / (double) DEGREES_T; } + inline double AsDegrees() const { return m_value; } - inline int AsTenthsOfADegree() const { return m_value; } + inline int AsTenthsOfADegree() const { return KiROUND( m_value * 10.0 ); } - inline double AsRadians() const - { - if( m_initial_type == RADIANS_T ) - { - // if this was initialized with radians, return exact initial value - return m_radians; - } - else - { - // otherwise compute from value stored as 1/10ths of a degree - return m_value * TENTHS_OF_A_DEGREE_TO_RADIANS; - } - } + inline double AsRadians() const { return m_value * DEGREES_TO_RADIANS; } inline double AsAngleType( EDA_ANGLE_T aAngleType ) const { @@ -199,11 +160,11 @@ public: case TENTHS_OF_A_DEGREE_T: return AsTenthsOfADegree(); case DEGREES_T: return AsDegrees(); case RADIANS_T: return AsRadians(); - default: assert( 1 == 0 ); + default: assert( false ); } } - static constexpr double TENTHS_OF_A_DEGREE_TO_RADIANS = M_PI / 1800; + static constexpr double DEGREES_TO_RADIANS = M_PI / 180.0; /** * @return true if angle is one of the four cardinal directions (0/90/180/270 degrees), @@ -211,73 +172,66 @@ public: */ bool IsCardinal() const { - return AsTenthsOfADegree() % 900 == 0; + double test = m_value; + + while( test < 0.0 ) + test += 90.0; + + while( test > 90.0 ) + test -= 90.0; + + return test == 0.0; } bool IsZero() const { - return AsTenthsOfADegree() == 0; + return m_value == 0.0; } bool IsHorizontal() const { - return AsTenthsOfADegree() == 0 || AsTenthsOfADegree() == 1800; + return m_value == 0.0 || m_value == 180.0; } bool IsVertical() const { - return AsTenthsOfADegree() == 900 || AsTenthsOfADegree() == 2700; - } - - EDA_ANGLE Add( const EDA_ANGLE& aAngle ) const - { - EDA_ANGLE_T initialType = GetInitialAngleType(); - - // if both were given in radians, addition is exact - if( initialType == RADIANS_T - && aAngle.GetInitialAngleType() == RADIANS_T ) - { - //double newAngle = normalize( AsRadians() + aAngle.AsRadians(), RADIANS_T ); - double newAngle = AsRadians() + aAngle.AsRadians(); - return EDA_ANGLE( newAngle, RADIANS_T ); - } - - // if both were not given in radians, addition is done using 1/10ths of a degree, then - // converted to original angle type - int newAngle = AsTenthsOfADegree() + aAngle.AsTenthsOfADegree(); - - switch( initialType ) - { - case DEGREES_T: - return EDA_ANGLE( newAngle / DEGREES_T, DEGREES_T ); - - case RADIANS_T: - return EDA_ANGLE( newAngle * TENTHS_OF_A_DEGREE_TO_RADIANS, RADIANS_T ); - - default: - case TENTHS_OF_A_DEGREE_T: - return EDA_ANGLE( newAngle, TENTHS_OF_A_DEGREE_T ); - } + return m_value == 90.0 || m_value == 270.0; } EDA_ANGLE Invert() const { - switch( GetInitialAngleType() ) - { - case RADIANS_T: - return EDA_ANGLE( -m_radians, RADIANS_T ); - default: - return EDA_ANGLE( -m_value / GetInitialAngleType(), GetInitialAngleType() ); - } + return EDA_ANGLE( -AsDegrees(), DEGREES_T ); } - EDA_ANGLE Subtract( const EDA_ANGLE& aAngle ) const { return Add( aAngle.Invert() ); } + double Sin() const + { + EDA_ANGLE test = *this; + test.Normalize(); - inline EDA_ANGLE_T GetInitialAngleType() const { return m_initial_type; } + if( test.m_value == 0.0 || test.m_value == 180.0 ) + return 0.0; + else if( test.m_value == 90.0 ) + return 1.0; + else if( test.m_value == 270.0 ) + return -1.0; + else + return sin( AsRadians() ); + } - double Sin() const { return sin( AsRadians() ); } + double Cos() const + { + EDA_ANGLE test = *this; + test.Normalize(); - double Cos() const { return cos( AsRadians() ); } + if( test.m_value == 0.0 ) + return 1.0; + else if( test.m_value == 180.0 ) + return -1.0; + else if( test.m_value == 90.0 || test.m_value == 270.0 ) + return 0.0; + else + return cos( AsRadians() ); + } double Tan() const { return tan( AsRadians() ); } @@ -294,43 +248,45 @@ public: inline EDA_ANGLE Normalize() { - normalize( false ); + while( m_value < -0.0 ) + m_value += 360.0; + + while( m_value >= 360.0 ) + m_value -= 360.0; + return *this; } inline EDA_ANGLE Normalize90() { - int angle = AsTenthsOfADegree(); + while( m_value < -90.0 ) + m_value += 180.0; - while( angle < -900 ) - angle += 1800; - - while( angle > 900 ) - angle -= 1800; - - *this = EDA_ANGLE( angle, TENTHS_OF_A_DEGREE_T ); + while( m_value > 90.0 ) + m_value -= 180.0; return *this; } inline EDA_ANGLE Normalize180() { - int angle = AsTenthsOfADegree(); + while( m_value <= -180.0 ) + m_value += 360.0; - while( angle <= -1800 ) - angle += 3600; - - while( angle > 1800 ) - angle -= 3600; - - *this = EDA_ANGLE( angle, TENTHS_OF_A_DEGREE_T ); + while( m_value > 180.0 ) + m_value -= 360.0; return *this; } inline EDA_ANGLE Normalize720() { - normalize( true ); + while( m_value < -360.0 ) + m_value += 360.0; + + while( m_value >= 360.0 ) + m_value -= 360.0; + return *this; } @@ -338,31 +294,18 @@ public: EDA_ANGLE& operator+=( const EDA_ANGLE& aAngle ) { - *this = Add( aAngle ); + *this = EDA_ANGLE( AsDegrees() + aAngle.AsDegrees(), DEGREES_T ); return *this; } EDA_ANGLE& operator-=( const EDA_ANGLE& aAngle ) { - EDA_ANGLE angle( aAngle ); - *this = Add( angle.Invert() ); + *this = EDA_ANGLE( AsDegrees() - aAngle.AsDegrees(), DEGREES_T ); return *this; } private: - void normalize( bool n720 = false ); - int normalize( int aValue, EDA_ANGLE_T aAngleType, bool n720 = false ) const; - double normalize( double aValue, EDA_ANGLE_T aAngleType, bool n720 = false ) const; - -private: - - int m_value; ///< value is always stored in 1/10ths of a degree - double m_radians; ///< only used with as-radians constructor - EDA_ANGLE_T m_initial_type; - - static constexpr int TENTHS_OF_A_DEGREE_FULL_CIRCLE = 3600; - static constexpr int DEGREES_FULL_CIRCLE = 360; - static constexpr double RADIANS_FULL_CIRCLE = 2 * M_PI; + double m_value; ///< value in degrees public: static EDA_ANGLE m_Angle0; @@ -383,70 +326,61 @@ inline EDA_ANGLE operator-( const EDA_ANGLE& aAngle ) inline EDA_ANGLE operator-( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB ) { - return aAngleA.Add( aAngleB.Invert() ); + return EDA_ANGLE( aAngleA.AsDegrees() - aAngleB.AsDegrees(), DEGREES_T ); } inline EDA_ANGLE operator+( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB ) { - return aAngleA.Add( aAngleB ); + return EDA_ANGLE( aAngleA.AsDegrees() + aAngleB.AsDegrees(), DEGREES_T ); } inline EDA_ANGLE operator*( const EDA_ANGLE& aAngleA, double aOperator ) { - switch( aAngleA.GetInitialAngleType() ) - { - case RADIANS_T: - return EDA_ANGLE( aAngleA.AsRadians() * aOperator, RADIANS_T ); - default: - return EDA_ANGLE( aAngleA.AsDegrees() * aOperator, DEGREES_T ); - } + return EDA_ANGLE( aAngleA.AsDegrees() * aOperator, DEGREES_T ); } inline EDA_ANGLE operator/( const EDA_ANGLE& aAngleA, double aOperator ) { - switch( aAngleA.GetInitialAngleType() ) - { - case RADIANS_T: - return EDA_ANGLE( aAngleA.AsRadians() / aOperator, RADIANS_T ); - default: - return EDA_ANGLE( aAngleA.AsDegrees() / aOperator, DEGREES_T ); - } + return EDA_ANGLE( aAngleA.AsDegrees() / aOperator, DEGREES_T ); } inline bool operator==( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB ) { - return aAngleA.AsTenthsOfADegree() == aAngleB.AsTenthsOfADegree(); + return aAngleA.AsDegrees() == aAngleB.AsDegrees(); } inline bool operator!=( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB ) { - return aAngleA.AsTenthsOfADegree() != aAngleB.AsTenthsOfADegree(); + return aAngleA.AsDegrees() != aAngleB.AsDegrees(); } inline bool operator>( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB ) { - return aAngleA.AsTenthsOfADegree() > aAngleB.AsTenthsOfADegree(); + return aAngleA.AsDegrees() > aAngleB.AsDegrees(); } + inline bool operator<( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB ) { - return aAngleA.AsTenthsOfADegree() < aAngleB.AsTenthsOfADegree(); + return aAngleA.AsDegrees() < aAngleB.AsDegrees(); } + inline bool operator<=( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB ) { - return aAngleA.AsTenthsOfADegree() <= aAngleB.AsTenthsOfADegree(); + return aAngleA.AsDegrees() <= aAngleB.AsDegrees(); } + inline bool operator>=( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB ) { - return aAngleA.AsTenthsOfADegree() >= aAngleB.AsTenthsOfADegree(); + return aAngleA.AsDegrees() >= aAngleB.AsDegrees(); } diff --git a/libs/kimath/src/convert_basic_shapes_to_polygon.cpp b/libs/kimath/src/convert_basic_shapes_to_polygon.cpp index 8049b895b0..515795bb39 100644 --- a/libs/kimath/src/convert_basic_shapes_to_polygon.cpp +++ b/libs/kimath/src/convert_basic_shapes_to_polygon.cpp @@ -550,7 +550,7 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aStar // and arc inner to polyline and merge shapes. int radial_offset = ( aWidth + 1 ) / 2; - SHAPE_POLY_SET polyshape; + SHAPE_POLY_SET polyshape; std::vector outside_pts; /// We start by making rounded ends on the arc @@ -626,7 +626,7 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aStar if( arc_angle_end != ANGLE_0 && arc_angle_end != ANGLE_180 ) polyshape.Outline(0).Rotate( arc_angle_end.AsRadians(), arcSpine.GetPoint( 0 ) ); - arc_angle_end_deg = arc.GetEndAngle(); + arc_angle_end = arc.GetEndAngle(); if( arc_angle_end != ANGLE_0 && arc_angle_end != ANGLE_180 ) polyshape.Outline(1).Rotate( arc_angle_end.AsRadians(), arcSpine.GetPoint( -1 ) ); diff --git a/libs/kimath/src/geometry/eda_angle.cpp b/libs/kimath/src/geometry/eda_angle.cpp index 5d96ccd291..a4d20f67dd 100644 --- a/libs/kimath/src/geometry/eda_angle.cpp +++ b/libs/kimath/src/geometry/eda_angle.cpp @@ -47,72 +47,3 @@ EDA_ANGLE EDA_ANGLE::KeepUpright() const } -void EDA_ANGLE::normalize( bool n720 ) -{ - if( GetInitialAngleType() == RADIANS_T ) - { - m_radians = normalize( m_radians, RADIANS_T, n720 ); - m_value = int( m_radians / TENTHS_OF_A_DEGREE_TO_RADIANS ); - } - else - { - m_value = normalize( m_value, TENTHS_OF_A_DEGREE_T, n720 ); - } -} - - -int EDA_ANGLE::normalize( int aValue, EDA_ANGLE_T aAngleType, bool n720 ) const -{ - int full_circle_upper = DEGREES_FULL_CIRCLE; - - switch( aAngleType ) - { - case DEGREES_T: - full_circle_upper = DEGREES_FULL_CIRCLE; - break; - - case TENTHS_OF_A_DEGREE_T: - full_circle_upper = TENTHS_OF_A_DEGREE_FULL_CIRCLE; - break; - - case RADIANS_T: - wxFAIL_MSG( "should be unreachable..." ); - } - - /* - * if n720 == false, clamp between 0..full_circle_upper - * if n720 == true, clamp between +/- full_circle_upper - */ - int full_circle_lower = n720 ? -full_circle_upper : 0; - - while( aValue < full_circle_lower ) - aValue += full_circle_upper; - - while( aValue >= full_circle_upper ) - aValue -= full_circle_upper; - - return aValue; -} - - -double EDA_ANGLE::normalize( double aValue, EDA_ANGLE_T aAngleType, bool n720 ) const -{ - double full_circle_upper = DEGREES_FULL_CIRCLE; - - switch( aAngleType ) - { - case DEGREES_T: full_circle_upper = DEGREES_FULL_CIRCLE; break; - case TENTHS_OF_A_DEGREE_T: full_circle_upper = TENTHS_OF_A_DEGREE_FULL_CIRCLE; break; - case RADIANS_T: full_circle_upper = RADIANS_FULL_CIRCLE; break; - } - - double full_circle_lower = n720 ? 0 : -full_circle_upper; - - while( aValue < full_circle_lower ) - aValue += full_circle_upper; - - while( aValue >= full_circle_upper ) - aValue -= full_circle_upper; - - return aValue; -} diff --git a/pcbnew/drc/drc_test_provider_library_parity.cpp b/pcbnew/drc/drc_test_provider_library_parity.cpp index 510bb1e01f..28b1d08c28 100644 --- a/pcbnew/drc/drc_test_provider_library_parity.cpp +++ b/pcbnew/drc/drc_test_provider_library_parity.cpp @@ -95,7 +95,7 @@ bool primitivesNeedUpdate( const std::shared_ptr& a, TEST( a->GetStart(), b->GetStart() ); TEST( a->GetEnd(), b->GetEnd() ); TEST( a->GetCenter(), b->GetCenter() ); - TEST( a->GetArcAngle().AsTenthsOfADegree(), b->GetArcAngle().AsTenthsOfADegree() ); + TEST( a->GetArcAngle().AsDegrees(), b->GetArcAngle().AsDegrees() ); break; case SHAPE_T::BEZIER: @@ -147,8 +147,8 @@ bool padsNeedUpdate( const PAD* a, const PAD* b ) TEST( a->GetProperty(), b->GetProperty() ); // The pad orientation, for historical reasons is the pad rotation + parent rotation. - TEST( ( a->GetOrientation() - a->GetParent()->GetOrientation() ).Normalize().AsTenthsOfADegree(), - ( b->GetOrientation() - b->GetParent()->GetOrientation() ).Normalize().AsTenthsOfADegree() ); + TEST( ( a->GetOrientation() - a->GetParent()->GetOrientation() ).Normalize().AsDegrees(), + ( b->GetOrientation() - b->GetParent()->GetOrientation() ).Normalize().AsDegrees() ); TEST( a->GetSize(), b->GetSize() ); TEST( a->GetDelta(), b->GetDelta() ); @@ -169,7 +169,7 @@ bool padsNeedUpdate( const PAD* a, const PAD* b ) TEST( a->GetZoneConnection(), b->GetZoneConnection() ); TEST( a->GetThermalGap(), b->GetThermalGap() ); TEST( a->GetThermalSpokeWidth(), b->GetThermalSpokeWidth() ); - TEST( a->GetThermalSpokeAngle().AsTenthsOfADegree(), b->GetThermalSpokeAngle().AsTenthsOfADegree() ); + TEST( a->GetThermalSpokeAngle().AsDegrees(), b->GetThermalSpokeAngle().AsDegrees() ); TEST( a->GetCustomShapeInZoneOpt(), b->GetCustomShapeInZoneOpt() ); TEST( a->GetPrimitives().size(), b->GetPrimitives().size() ); @@ -198,7 +198,7 @@ bool shapesNeedUpdate( const FP_SHAPE* a, const FP_SHAPE* b ) TEST( a->GetStart0(), b->GetStart0() ); TEST( a->GetEnd0(), b->GetEnd0() ); TEST( a->GetCenter0(), b->GetCenter0() ); - TEST( a->GetArcAngle().AsTenthsOfADegree(), b->GetArcAngle().AsTenthsOfADegree() ); + TEST( a->GetArcAngle().AsDegrees(), b->GetArcAngle().AsDegrees() ); break; case SHAPE_T::BEZIER: