From 8cc80e3b357456a9ed4edc8f9595ca8008546581 Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Tue, 10 Mar 2020 11:04:05 -0400 Subject: [PATCH] Add unit test for testing LIB_ARC objects. Added tests for calculating radius angles and arc mid point. --- eeschema/lib_arc.cpp | 48 ++------------ eeschema/lib_arc.h | 8 +++ qa/eeschema/CMakeLists.txt | 2 + qa/eeschema/test_lib_arc.cpp | 120 +++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 41 deletions(-) create mode 100644 qa/eeschema/test_lib_arc.cpp diff --git a/eeschema/lib_arc.cpp b/eeschema/lib_arc.cpp index 687b830551..3180ac4532 100644 --- a/eeschema/lib_arc.cpp +++ b/eeschema/lib_arc.cpp @@ -584,53 +584,19 @@ void LIB_ARC::CalcRadiusAngles() VECTOR2I LIB_ARC::CalcMidPoint() const { - double radA; - double radB; VECTOR2D midPoint; double startAngle = static_cast( m_t1 ) / 10.0; double endAngle = static_cast( m_t2 ) / 10.0; - // Normalize the draw angle to always be quadrant 1 to 4 (counter-clockwise). - if( startAngle > endAngle ) - std::swap( startAngle, endAngle ); + if( endAngle < startAngle ) + endAngle -= 360.0; - if( startAngle < 0 ) - startAngle += 360.0; + double midPointAngle = ( ( endAngle - startAngle ) / 2.0 ) + startAngle; + double x = cos( DEG2RAD( midPointAngle ) ) * m_Radius; + double y = sin( DEG2RAD( midPointAngle ) ) * m_Radius; - if( endAngle < 0 ) - endAngle += 360.0; - - bool interceptsNegativeX = InterceptsNegativeX( startAngle, endAngle ); - bool interceptsPositiveX = InterceptsPositiveX( startAngle, endAngle ); - - if( !interceptsPositiveX && !interceptsNegativeX ) - { - radA = 1.0; - radB = -1.0; - } - else if( interceptsPositiveX && !interceptsNegativeX ) - { - radA = 1.0; - radB = 1.0; - } - else if( !interceptsPositiveX && interceptsNegativeX ) - { - radA = -1.0; - radB = -1.0; - } - else - { - radA = -1.0; - radB = 1.0; - } - - double x = ( radA * std::sqrt( (m_Radius + m_ArcStart.x) * (m_Radius + m_ArcEnd.x) ) ) + - ( radB * std::sqrt( (m_Radius - m_ArcStart.x) * (m_Radius - m_ArcEnd.x) ) ); - double y = ( radA * std::sqrt( (m_Radius + m_ArcStart.y) * (m_Radius + m_ArcEnd.y) ) ) + - ( radB * std::sqrt( (m_Radius - m_ArcStart.y) * (m_Radius - m_ArcEnd.y) ) ); - - midPoint.x = KiROUND( x ); - midPoint.y = KiROUND( y ); + midPoint.x = KiROUND( x ) + m_Pos.x; + midPoint.y = KiROUND( y ) + m_Pos.y; return midPoint; } diff --git a/eeschema/lib_arc.h b/eeschema/lib_arc.h index 160b59bcd4..6c8ab21cee 100644 --- a/eeschema/lib_arc.h +++ b/eeschema/lib_arc.h @@ -116,6 +116,14 @@ public: wxPoint GetEnd() const { return m_ArcEnd; } void SetEnd( const wxPoint& aPoint ) { m_ArcEnd = aPoint; } + /** + * Calculate the arc mid point using the arc start and end angles and radius length. + * + * @note This is not a general purpose trigonometric arc midpoint calculation. It is + * limited to the less than 180.0 degree arcs used in symbols. + * + * @return A #VECTOR2I object containing the midpoint of the arc. + */ VECTOR2I CalcMidPoint() const; /** diff --git a/qa/eeschema/CMakeLists.txt b/qa/eeschema/CMakeLists.txt index a5c3ea4dab..6cea3401c7 100644 --- a/qa/eeschema/CMakeLists.txt +++ b/qa/eeschema/CMakeLists.txt @@ -45,6 +45,7 @@ add_executable( qa_eeschema test_sch_biu.cpp test_eagle_plugin.cpp + test_lib_arc.cpp test_lib_part.cpp test_sch_pin.cpp test_sch_rtree.cpp @@ -63,6 +64,7 @@ add_dependencies( qa_eeschema eeschema ) target_link_libraries( qa_eeschema common + kimath qa_utils unit_test_utils markdown_lib diff --git a/qa/eeschema/test_lib_arc.cpp b/qa/eeschema/test_lib_arc.cpp new file mode 100644 index 0000000000..5ee06c148d --- /dev/null +++ b/qa/eeschema/test_lib_arc.cpp @@ -0,0 +1,120 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2020 KiCad Developers, see CHANGELOG.TXT for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @file + * Test suite for LIB_ARC + */ + +#include +#include +#include + +// Code under test +#include + +class TEST_LIB_ARC_FIXTURE +{ +public: + TEST_LIB_ARC_FIXTURE() : + m_arc( nullptr ) + { + } + + ///> Part with no extra data set + LIB_ARC m_arc; +}; + + +/** + * Declare the test suite + */ +BOOST_FIXTURE_TEST_SUITE( LibArc, TEST_LIB_ARC_FIXTURE ) + + +/** + * Check that we can get the default properties out as expected + */ +BOOST_AUTO_TEST_CASE( DefaultProperties ) +{ + BOOST_CHECK_EQUAL( m_arc.Type(), LIB_ARC_T ); + BOOST_CHECK_EQUAL( m_arc.GetClass(), "LIB_ARC" ); + BOOST_CHECK_EQUAL( m_arc.GetPosition(), wxPoint( 0, 0 ) ); +} + + +/** + * Test the function that calculates the radius angles based on the center, start, and end points. + */ +BOOST_AUTO_TEST_CASE( TestCalcRadiusAngles ) +{ + double radius = 5.0; // Use millimeters and convert to internal units. + int startX = Millimeter2iu( radius * cos( DEG2RAD( 10.0 ) ) ); + int startY = Millimeter2iu( radius * sin( DEG2RAD( 10.0 ) ) ); + int endX = Millimeter2iu( radius * cos( DEG2RAD( 45.0 ) ) ); + int endY = Millimeter2iu( radius * sin( DEG2RAD( 45.0 ) ) ); + + m_arc.SetStart( wxPoint( startX, startY ) ); + m_arc.SetEnd( wxPoint( endX, endY ) ); + + m_arc.CalcRadiusAngles(); + BOOST_CHECK_EQUAL( m_arc.GetFirstRadiusAngle(), 100 ); + BOOST_CHECK_EQUAL( m_arc.GetSecondRadiusAngle(), 450 ); + + // Set arc end point in the second quadrant. + endX = Millimeter2iu( radius * cos( DEG2RAD( 145.0 ) ) ); + endY = Millimeter2iu( radius * sin( DEG2RAD( 145.0 ) ) ); + m_arc.SetEnd( wxPoint( endX, endY ) ); + m_arc.CalcRadiusAngles(); + BOOST_CHECK_EQUAL( m_arc.GetFirstRadiusAngle(), 100 ); + BOOST_CHECK_EQUAL( m_arc.GetSecondRadiusAngle(), 1450 ); +} + + +/** + * Test the function that calculates the mid point based on the start and end angles and + * radius length. + */ +BOOST_AUTO_TEST_CASE( TestCalcMidPoint ) +{ + // Midpoint angle is 77.5 degrees. + m_arc.SetRadius( Millimeter2iu( 5.0 ) ); + m_arc.SetFirstRadiusAngle( 100 ); + m_arc.SetSecondRadiusAngle( 1450 ); + BOOST_CHECK_EQUAL( m_arc.CalcMidPoint(), VECTOR2I( 10822, 48815 ) ); + m_arc.SetFirstRadiusAngle( 850 ); + m_arc.SetSecondRadiusAngle( 950 ); + BOOST_CHECK_EQUAL( m_arc.CalcMidPoint(), VECTOR2I( 0, 50000 ) ); + m_arc.SetFirstRadiusAngle( 1700 ); + m_arc.SetSecondRadiusAngle( 1900 ); + BOOST_CHECK_EQUAL( m_arc.CalcMidPoint(), VECTOR2I( -50000, 0 ) ); + m_arc.SetFirstRadiusAngle( 2500 ); + m_arc.SetSecondRadiusAngle( 2900 ); + BOOST_CHECK_EQUAL( m_arc.CalcMidPoint(), VECTOR2I( 0, -50000 ) ); + m_arc.SetFirstRadiusAngle( 3500 ); + m_arc.SetSecondRadiusAngle( 100 ); + BOOST_CHECK_EQUAL( m_arc.CalcMidPoint(), VECTOR2I( 50000, 0 ) ); +} + + +BOOST_AUTO_TEST_SUITE_END()