More EDA_ANGLE.

This commit is contained in:
Jeff Young 2022-01-14 15:34:41 +00:00
parent 1b19ff5f42
commit 07013d00e1
55 changed files with 424 additions and 410 deletions

View File

@ -289,7 +289,7 @@ unsigned int BOARD_ADAPTER::GetCircleSegmentCount( int aDiameterBIU ) const
{ {
wxASSERT( aDiameterBIU > 0 ); wxASSERT( aDiameterBIU > 0 );
return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, 360.0 ); return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, FULL_CIRCLE );
} }

View File

@ -242,11 +242,11 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
{ {
const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack ); const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack );
VECTOR2D center( arc->GetCenter() ); VECTOR2D center( arc->GetCenter() );
double arc_angle = arc->GetAngle(); EDA_ANGLE arc_angle = arc->GetAngle();
double radius = arc->GetRadius(); double radius = arc->GetRadius();
int arcsegcount = GetArcToSegmentCount( radius, ARC_HIGH_DEF, arc_angle / 10 ); int arcsegcount = GetArcToSegmentCount( radius, ARC_HIGH_DEF, arc_angle );
int circlesegcount; int circlesegcount;
// We need a circle to segment count. However, the arc angle can be small, and the // We need a circle to segment count. However, the arc angle can be small, and the
// radius very big. so we calculate a reasonable value for circlesegcount. // radius very big. so we calculate a reasonable value for circlesegcount.
@ -256,12 +256,13 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
} }
else else
{ {
circlesegcount = KiROUND( arcsegcount * 3600 / std::abs( arc_angle ) ); circlesegcount = KiROUND( arcsegcount * 360.0 / std::abs( arc_angle.AsDegrees() ) );
circlesegcount = std::max( 1, std::min( circlesegcount, 128 ) ); circlesegcount = std::max( 1, std::min( circlesegcount, 128 ) );
} }
transformArcToSegments( VECTOR2I( center.x, center.y ), arc->GetStart(), arc_angle, transformArcToSegments( VECTOR2I( center.x, center.y ), arc->GetStart(),
circlesegcount, arc->GetWidth(), aDstContainer, *arc ); arc_angle.AsTenthsOfADegree(), circlesegcount, arc->GetWidth(),
aDstContainer, *arc );
break; break;
} }
@ -658,8 +659,9 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aDstCo
{ {
unsigned int segCount = GetCircleSegmentCount( aShape->GetBoundingBox().GetSizeMax() ); unsigned int segCount = GetCircleSegmentCount( aShape->GetBoundingBox().GetSizeMax() );
transformArcToSegments( aShape->GetCenter(), aShape->GetStart(), aShape->GetArcAngle(), transformArcToSegments( aShape->GetCenter(), aShape->GetStart(),
segCount, linewidth, aDstContainer, *aShape ); aShape->GetArcAngle().AsTenthsOfADegree(), segCount, linewidth,
aDstContainer, *aShape );
} }
break; break;

View File

@ -451,12 +451,12 @@ std::string FormatInternalUnits( int aValue )
} }
std::string FormatAngle( double aAngle ) std::string FormatAngle( const EDA_ANGLE& aAngle )
{ {
char temp[50]; char temp[50];
int len; int len;
len = snprintf( temp, sizeof(temp), "%.10g", aAngle / 10.0 ); len = snprintf( temp, sizeof(temp), "%.10g", aAngle.AsDegrees() );
return std::string( temp, len ); return std::string( temp, len );
} }

View File

@ -76,19 +76,19 @@ int EDA_ANGLE::normalize( int aValue, EDA_ANGLE_T aAngleType, bool n720 ) const
break; break;
case RADIANS_T: case RADIANS_T:
/* ?? should not get here */ wxFAIL_MSG( "should be unreachable..." );
assert( 1 == 0 );
} }
/* if n720 == false, clamp between 0..full_circle_upper /*
* if n720 == true, clamp between +/- full_circle_upper * if n720 == false, clamp between 0..full_circle_upper
*/ * if n720 == true, clamp between +/- full_circle_upper
*/
int full_circle_lower = n720 ? 0 : -full_circle_upper; int full_circle_lower = n720 ? 0 : -full_circle_upper;
while( aValue < full_circle_lower ) while( aValue < full_circle_lower )
aValue += full_circle_upper; aValue += full_circle_upper;
while( aValue > full_circle_upper ) while( aValue >= full_circle_upper )
aValue -= full_circle_upper; aValue -= full_circle_upper;
return aValue; return aValue;
@ -101,9 +101,9 @@ double EDA_ANGLE::normalize( double aValue, EDA_ANGLE_T aAngleType, bool n720 )
switch( aAngleType ) switch( aAngleType )
{ {
case DEGREES_T: full_circle_upper = DEGREES_FULL_CIRCLE; break; 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 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; case RADIANS_T: full_circle_upper = RADIANS_FULL_CIRCLE; break;
} }
double full_circle_lower = n720 ? 0 : -full_circle_upper; double full_circle_lower = n720 ? 0 : -full_circle_upper;
@ -111,7 +111,7 @@ double EDA_ANGLE::normalize( double aValue, EDA_ANGLE_T aAngleType, bool n720 )
while( aValue < full_circle_lower ) while( aValue < full_circle_lower )
aValue += full_circle_upper; aValue += full_circle_upper;
while( aValue > full_circle_upper ) while( aValue >= full_circle_upper )
aValue -= full_circle_upper; aValue -= full_circle_upper;
return aValue; return aValue;

View File

@ -126,7 +126,7 @@ double EDA_SHAPE::GetLength() const
return length; return length;
case SHAPE_T::ARC: case SHAPE_T::ARC:
return 2 * M_PI * GetRadius() * ( GetArcAngle() / 3600.0 ); return GetRadius() * GetArcAngle().AsRadians();
default: default:
UNIMPLEMENTED_FOR( SHAPE_T_asString() ); UNIMPLEMENTED_FOR( SHAPE_T_asString() );
@ -512,14 +512,14 @@ void EDA_SHAPE::SetArcGeometry( const VECTOR2I& aStart, const VECTOR2I& aMid, co
} }
double EDA_SHAPE::GetArcAngle() const EDA_ANGLE EDA_SHAPE::GetArcAngle() const
{ {
double startAngle; double startAngle;
double endAngle; double endAngle;
CalcArcAngles( startAngle, endAngle ); CalcArcAngles( startAngle, endAngle );
return ( endAngle - startAngle ) * 10; return EDA_ANGLE( endAngle - startAngle, DEGREES_T );
} }
@ -556,7 +556,7 @@ void EDA_SHAPE::ShapeGetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PA
case SHAPE_T::ARC: case SHAPE_T::ARC:
aList.emplace_back( shape, _( "Arc" ) ); aList.emplace_back( shape, _( "Arc" ) );
msg.Printf( wxT( "%.1f" ), GetArcAngle() / 10.0 ); msg.Printf( wxT( "%.1f" ), GetArcAngle().AsDegrees() );
aList.emplace_back( _( "Angle" ), msg ); aList.emplace_back( _( "Angle" ), msg );
msg = MessageTextFromValue( units, GetRadius() ); msg = MessageTextFromValue( units, GetRadius() );
@ -1078,7 +1078,7 @@ std::vector<SHAPE*> EDA_SHAPE::MakeEffectiveShapes( bool aEdgeOnly ) const
switch( m_shape ) switch( m_shape )
{ {
case SHAPE_T::ARC: case SHAPE_T::ARC:
effectiveShapes.emplace_back( new SHAPE_ARC( m_arcCenter, m_start, GetArcAngle() / 10.0, effectiveShapes.emplace_back( new SHAPE_ARC( m_arcCenter, m_start, GetArcAngle(),
GetWidth() ) ); GetWidth() ) );
break; break;
@ -1109,7 +1109,7 @@ std::vector<SHAPE*> EDA_SHAPE::MakeEffectiveShapes( bool aEdgeOnly ) const
effectiveShapes.emplace_back( new SHAPE_CIRCLE( getCenter(), GetRadius() ) ); effectiveShapes.emplace_back( new SHAPE_CIRCLE( getCenter(), GetRadius() ) );
if( GetWidth() > 0 || !IsFilled() || aEdgeOnly ) if( GetWidth() > 0 || !IsFilled() || aEdgeOnly )
effectiveShapes.emplace_back( new SHAPE_ARC( getCenter(), GetEnd(), 360.0 ) ); effectiveShapes.emplace_back( new SHAPE_ARC( getCenter(), GetEnd(), ANGLE_360 ) );
break; break;
} }
@ -1344,12 +1344,11 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
case 1: case 1:
{ {
// Keep center clockwise from chord while drawing // Keep center clockwise from chord while drawing
VECTOR2I chordVector = m_end - m_start; VECTOR2I chordVector = m_end - m_start;
double chordAngle = ArcTangente( chordVector.y, chordVector.x ); EDA_ANGLE chordAngle( chordVector );
NORMALIZE_ANGLE_POS( chordAngle );
VECTOR2I c1Test = c1; VECTOR2I c1Test = c1;
RotatePoint( c1Test, m_start, -chordAngle ); RotatePoint( c1Test, m_start, -chordAngle.Normalize() );
m_arcCenter = c1Test.x > 0 ? c2 : c1; m_arcCenter = c1Test.x > 0 ? c2 : c1;
} }
@ -1365,7 +1364,7 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
// Pick the one closer to the mouse position // Pick the one closer to the mouse position
m_arcCenter = GetLineLength( c1, aPosition ) < GetLineLength( c2, aPosition ) ? c1 : c2; m_arcCenter = GetLineLength( c1, aPosition ) < GetLineLength( c2, aPosition ) ? c1 : c2;
if( GetArcAngle() > 1800 ) if( GetArcAngle() > ANGLE_180 )
std::swap( m_start, m_end ); std::swap( m_start, m_end );
break; break;

View File

@ -889,7 +889,7 @@ void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
SWAP( aStartAngle, >, aEndAngle ); SWAP( aStartAngle, >, aEndAngle );
// Calculate the seg count to approximate the arc with aMaxError or less // Calculate the seg count to approximate the arc with aMaxError or less
int segCount360 = GetArcToSegmentCount( aRadius, aMaxError, 360.0 ); int segCount360 = GetArcToSegmentCount( aRadius, aMaxError, FULL_CIRCLE );
segCount360 = std::max( SEG_PER_CIRCLE_COUNT, segCount360 ); segCount360 = std::max( SEG_PER_CIRCLE_COUNT, segCount360 );
double alphaIncrement = 2.0 * M_PI / segCount360; double alphaIncrement = 2.0 * M_PI / segCount360;

View File

@ -252,7 +252,10 @@ void GRCSegm( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2, int w
int radius = ( width + 1 ) >> 1; int radius = ( width + 1 ) >> 1;
int dx = x2 - x1; int dx = x2 - x1;
int dy = y2 - y1; int dy = y2 - y1;
double angle = -ArcTangente( dy, dx ); EDA_ANGLE angle( VECTOR2I( dx, dy ) );
angle = -angle;
VECTOR2I start; VECTOR2I start;
VECTOR2I end; VECTOR2I end;
VECTOR2I org( x1, y1 ); VECTOR2I org( x1, y1 );

View File

@ -462,21 +462,14 @@ void PLOTTER::Marker( const VECTOR2I& position, int diametre, unsigned aShapeId
void PLOTTER::segmentAsOval( const VECTOR2I& start, const VECTOR2I& end, int width, void PLOTTER::segmentAsOval( const VECTOR2I& start, const VECTOR2I& end, int width,
OUTLINE_MODE tracemode ) OUTLINE_MODE tracemode )
{ {
VECTOR2I center( ( start.x + end.x ) / 2, ( start.y + end.y ) / 2 ); VECTOR2I center( ( start.x + end.x ) / 2, ( start.y + end.y ) / 2 );
VECTOR2I size( end.x - start.x, end.y - start.y ); VECTOR2I size( end.x - start.x, end.y - start.y );
double orient; EDA_ANGLE orient( size );
if( size.y == 0 )
orient = 0;
else if( size.x == 0 )
orient = 900;
else
orient = -ArcTangente( size.y, size.x );
size.x = KiROUND( EuclideanNorm( size ) ) + width; size.x = KiROUND( EuclideanNorm( size ) ) + width;
size.y = width; size.y = width;
FlashPadOval( center, size, orient, tracemode, nullptr ); FlashPadOval( center, size, orient.AsTenthsOfADegree(), tracemode, nullptr );
} }

View File

@ -1092,11 +1092,8 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadNets()
{ {
secondPt = false; secondPt = false;
EDA_ANGLE wireAngle( last - pt );
VECTOR2I kiLast = last; fixNetLabelsAndSheetPins( wireAngle.AsTenthsOfADegree(), conn.StartNode );
VECTOR2I kiCurrent = pt;
double wireangleDeciDeg = getPolarAngle( kiLast - kiCurrent );
fixNetLabelsAndSheetPins( wireangleDeciDeg, conn.StartNode );
} }
wire = new SCH_LINE(); wire = new SCH_LINE();
@ -1116,10 +1113,8 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadNets()
//Fix labels on the end wire //Fix labels on the end wire
if( wire ) if( wire )
{ {
VECTOR2I kiLast = wire->GetEndPoint(); EDA_ANGLE wireAngle( wire->GetEndPoint() - wire->GetStartPoint() );
VECTOR2I kiCurrent = wire->GetStartPoint(); fixNetLabelsAndSheetPins( wireAngle.AsTenthsOfADegree(), conn.EndNode );
double wireangleDeciDeg = getPolarAngle( kiLast - kiCurrent );
fixNetLabelsAndSheetPins( wireangleDeciDeg, conn.EndNode );
} }
} }
@ -2059,18 +2054,18 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices(
case VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE: case VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE:
case VERTEX_TYPE::ANTICLOCKWISE_ARC: case VERTEX_TYPE::ANTICLOCKWISE_ARC:
{ {
double arcStartAngle = getPolarAngle( startPoint - centerPoint ); EDA_ANGLE arcStartAngle( startPoint - centerPoint );
double arcEndAngle = getPolarAngle( endPoint - centerPoint ); EDA_ANGLE arcEndAngle( endPoint - centerPoint );
double arcAngleDeciDeg = arcEndAngle - arcStartAngle; EDA_ANGLE arcAngle = arcEndAngle - arcStartAngle;
if( cw ) if( cw )
arcAngleDeciDeg = NormalizeAnglePos( arcAngleDeciDeg ); arcAngle = arcAngle.Normalize();
else else
arcAngleDeciDeg = NormalizeAngleNeg( arcAngleDeciDeg ); arcAngle = -arcAngle.Normalize();
// JEY TODO: Load as arc... // TODO: Load as arc...
SHAPE_ARC tempArc( centerPoint, startPoint, arcAngleDeciDeg / 10.0 ); SHAPE_ARC tempArc( centerPoint, startPoint, arcAngle );
SHAPE_LINE_CHAIN arcSegments = tempArc.ConvertToPolyline( Millimeter2iu( 0.1 ) ); SHAPE_LINE_CHAIN arcSegments = tempArc.ConvertToPolyline( Millimeter2iu( 0.1 ) );
// Load the arc as a series of piece-wise segments // Load the arc as a series of piece-wise segments
@ -3058,12 +3053,6 @@ VECTOR2I CADSTAR_SCH_ARCHIVE_LOADER::applyTransform(
} }
double CADSTAR_SCH_ARCHIVE_LOADER::getPolarAngle( const VECTOR2I& aPoint )
{
return NormalizeAnglePos( ArcTangente( aPoint.y, aPoint.x ) );
}
double CADSTAR_SCH_ARCHIVE_LOADER::getPolarRadius( const VECTOR2I& aPoint ) double CADSTAR_SCH_ARCHIVE_LOADER::getPolarRadius( const VECTOR2I& aPoint )
{ {
return sqrt( ( (double) aPoint.x * (double) aPoint.x ) return sqrt( ( (double) aPoint.x * (double) aPoint.x )

View File

@ -289,13 +289,6 @@ private:
* aAngleTenthDegree ); * aAngleTenthDegree );
} }
/**
* @brief
* @param aPoint
* @return Angle in decidegrees of the polar representation of the point, scaled 0..360
*/
double getPolarAngle( const VECTOR2I& aPoint );
/** /**
* @brief * @brief
* @param aPoint * @param aPoint

View File

@ -191,15 +191,15 @@ static const char* getPinShapeToken( GRAPHIC_PINSHAPE aShape )
} }
static float getPinAngle( int aOrientation ) static EDA_ANGLE getPinAngle( int aOrientation )
{ {
switch( aOrientation ) switch( aOrientation )
{ {
case PIN_RIGHT: return 0.0; case PIN_RIGHT: return ANGLE_0;
case PIN_LEFT: return 180.0; case PIN_LEFT: return ANGLE_180;
case PIN_UP: return 90.0; case PIN_UP: return ANGLE_90;
case PIN_DOWN: return 270.0; case PIN_DOWN: return ANGLE_270;
default: wxFAIL_MSG( "Missing symbol library pin orientation type" ); return 0.0; default: wxFAIL_MSG( "Missing symbol library pin orientation type" ); return ANGLE_0;
} }
} }
@ -222,21 +222,17 @@ static const char* getSheetPinShapeToken( LABEL_FLAG_SHAPE aShape )
} }
static double getSheetPinAngle( SHEET_SIDE aSide ) static EDA_ANGLE getSheetPinAngle( SHEET_SIDE aSide )
{ {
double retv;
switch( aSide ) switch( aSide )
{ {
case SHEET_SIDE::UNDEFINED: case SHEET_SIDE::UNDEFINED:
case SHEET_SIDE::LEFT: retv = 180.0; break; case SHEET_SIDE::LEFT: return ANGLE_180;
case SHEET_SIDE::RIGHT: retv = 0.0; break; case SHEET_SIDE::RIGHT: return ANGLE_0;
case SHEET_SIDE::TOP: retv = 90.0; break; case SHEET_SIDE::TOP: return ANGLE_90;
case SHEET_SIDE::BOTTOM: retv = 270.0; break; case SHEET_SIDE::BOTTOM: return ANGLE_270;
default: wxFAIL; retv = 0.0; break; default: wxFAIL; return ANGLE_0;
} }
return retv;
} }
@ -1038,17 +1034,17 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa
libName = "_NONAME_"; libName = "_NONAME_";
} }
double angle; EDA_ANGLE angle;
int orientation = aSymbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y ); int orientation = aSymbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y );
if( orientation == SYM_ORIENT_90 ) if( orientation == SYM_ORIENT_90 )
angle = 90.0; angle = ANGLE_90;
else if( orientation == SYM_ORIENT_180 ) else if( orientation == SYM_ORIENT_180 )
angle = 180.0; angle = ANGLE_180;
else if( orientation == SYM_ORIENT_270 ) else if( orientation == SYM_ORIENT_270 )
angle = 270.0; angle = ANGLE_270;
else else
angle = 0.0; angle = ANGLE_0;
m_out->Print( aNestLevel, "(symbol" ); m_out->Print( aNestLevel, "(symbol" );
@ -1062,7 +1058,7 @@ void SCH_SEXPR_PLUGIN::saveSymbol( SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheetPa
m_out->Quotew( aSymbol->GetLibId().Format().wx_str() ).c_str(), m_out->Quotew( aSymbol->GetLibId().Format().wx_str() ).c_str(),
FormatInternalUnits( aSymbol->GetPosition().x ).c_str(), FormatInternalUnits( aSymbol->GetPosition().x ).c_str(),
FormatInternalUnits( aSymbol->GetPosition().y ).c_str(), FormatInternalUnits( aSymbol->GetPosition().y ).c_str(),
FormatAngle( angle * 10.0 ).c_str() ); FormatAngle( angle ).c_str() );
bool mirrorX = aSymbol->GetOrientation() & SYM_MIRROR_X; bool mirrorX = aSymbol->GetOrientation() & SYM_MIRROR_X;
bool mirrorY = aSymbol->GetOrientation() & SYM_MIRROR_Y; bool mirrorY = aSymbol->GetOrientation() & SYM_MIRROR_Y;
@ -1157,7 +1153,7 @@ void SCH_SEXPR_PLUGIN::saveField( SCH_FIELD* aField, int aNestLevel )
aField->GetId(), aField->GetId(),
FormatInternalUnits( aField->GetPosition().x ).c_str(), FormatInternalUnits( aField->GetPosition().x ).c_str(),
FormatInternalUnits( aField->GetPosition().y ).c_str(), FormatInternalUnits( aField->GetPosition().y ).c_str(),
FormatAngle( aField->GetTextAngle().AsTenthsOfADegree() ).c_str() ); FormatAngle( aField->GetTextAngle() ).c_str() );
if( !aField->IsDefaultFormatting() if( !aField->IsDefaultFormatting()
|| ( aField->GetTextHeight() != Mils2iu( DEFAULT_SIZE_TEXT ) ) ) || ( aField->GetTextHeight() != Mils2iu( DEFAULT_SIZE_TEXT ) ) )
@ -1266,7 +1262,7 @@ void SCH_SEXPR_PLUGIN::saveSheet( SCH_SHEET* aSheet, int aNestLevel )
getSheetPinShapeToken( pin->GetShape() ), getSheetPinShapeToken( pin->GetShape() ),
FormatInternalUnits( pin->GetPosition().x ).c_str(), FormatInternalUnits( pin->GetPosition().x ).c_str(),
FormatInternalUnits( pin->GetPosition().y ).c_str(), FormatInternalUnits( pin->GetPosition().y ).c_str(),
FormatAngle( getSheetPinAngle( pin->GetSide() ) * 10.0 ).c_str() ); FormatAngle( getSheetPinAngle( pin->GetSide() ) ).c_str() );
pin->Format( m_out, aNestLevel + 1, 0 ); pin->Format( m_out, aNestLevel + 1, 0 );
@ -1445,7 +1441,7 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel )
m_out->Print( 0, " (at %s %s %s)", m_out->Print( 0, " (at %s %s %s)",
FormatInternalUnits( aText->GetPosition().x ).c_str(), FormatInternalUnits( aText->GetPosition().x ).c_str(),
FormatInternalUnits( aText->GetPosition().y ).c_str(), FormatInternalUnits( aText->GetPosition().y ).c_str(),
FormatAngle( aText->GetTextAngle().AsTenthsOfADegree() ).c_str() ); FormatAngle( aText->GetTextAngle() ).c_str() );
} }
else else
{ {
@ -1453,7 +1449,7 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel )
m_out->Print( aNestLevel + 1, "(at %s %s %s)", m_out->Print( aNestLevel + 1, "(at %s %s %s)",
FormatInternalUnits( aText->GetPosition().x ).c_str(), FormatInternalUnits( aText->GetPosition().x ).c_str(),
FormatInternalUnits( aText->GetPosition().y ).c_str(), FormatInternalUnits( aText->GetPosition().y ).c_str(),
FormatAngle( aText->GetTextAngle().AsTenthsOfADegree() ).c_str() ); FormatAngle( aText->GetTextAngle() ).c_str() );
} }
if( aText->GetFieldsAutoplaced() != FIELDS_AUTOPLACED_NO ) if( aText->GetFieldsAutoplaced() != FIELDS_AUTOPLACED_NO )
@ -2058,7 +2054,7 @@ void SCH_SEXPR_PLUGIN_CACHE::savePin( LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter
getPinShapeToken( aPin->GetShape() ), getPinShapeToken( aPin->GetShape() ),
FormatInternalUnits( aPin->GetPosition().x ).c_str(), FormatInternalUnits( aPin->GetPosition().x ).c_str(),
FormatInternalUnits( aPin->GetPosition().y ).c_str(), FormatInternalUnits( aPin->GetPosition().y ).c_str(),
FormatAngle( getPinAngle( aPin->GetOrientation() ) * 10.0 ).c_str(), FormatAngle( getPinAngle( aPin->GetOrientation() ) ).c_str(),
FormatInternalUnits( aPin->GetLength() ).c_str() ); FormatInternalUnits( aPin->GetLength() ).c_str() );
if( !aPin->IsVisible() ) if( !aPin->IsVisible() )

View File

@ -275,19 +275,18 @@ const EDA_RECT GERBER_DRAW_ITEM::GetBoundingBox() const
case GBR_ARC: case GBR_ARC:
{ {
double arc_angle = EDA_ANGLE angle( atan2( double( m_End.y - m_ArcCentre.y ),
atan2( double( m_End.y - m_ArcCentre.y ), double( m_End.x - m_ArcCentre.x ) ) double( m_End.x - m_ArcCentre.x ) )
- atan2( double( m_Start.y - m_ArcCentre.y ), double( m_Start.x - m_ArcCentre.x ) ); - atan2( double( m_Start.y - m_ArcCentre.y ),
double( m_Start.x - m_ArcCentre.x ) ),
arc_angle *= 180.0 / M_PI; RADIANS_T );
if( arc_angle < 0.0 )
arc_angle += 360.0;
if( m_End == m_Start ) // Arc with the end point = start point is expected to be a circle. if( m_End == m_Start ) // Arc with the end point = start point is expected to be a circle.
arc_angle = 360.0; angle = ANGLE_360;
else
angle.Normalize();
SHAPE_ARC arc( m_ArcCentre, m_Start, arc_angle ); SHAPE_ARC arc( m_ArcCentre, m_Start, angle );
BOX2I arc_bbox = arc.BBox( m_Size.x / 2 ); // m_Size.x is the line thickness BOX2I arc_bbox = arc.BBox( m_Size.x / 2 ); // m_Size.x is the line thickness
bbox.SetOrigin( arc_bbox.GetX(), arc_bbox.GetY() ); bbox.SetOrigin( arc_bbox.GetX(), arc_bbox.GetY() );
bbox.SetWidth( arc_bbox.GetWidth() ); bbox.SetWidth( arc_bbox.GetWidth() );

View File

@ -35,6 +35,7 @@
#include <string> #include <string>
#include <eda_units.h> #include <eda_units.h>
#include <eda_angle.h>
#include <convert_to_biu.h> #include <convert_to_biu.h>
#include <math/vector2d.h> #include <math/vector2d.h>
@ -194,7 +195,7 @@ std::string FormatInternalUnits( int aValue );
* @param aAngle A angle value to convert. * @param aAngle A angle value to convert.
* @return A std::string object containing the converted angle. * @return A std::string object containing the converted angle.
*/ */
std::string FormatAngle( double aAngle ); std::string FormatAngle( const EDA_ANGLE& aAngle );
std::string FormatInternalUnits( const wxPoint& aPoint ); std::string FormatInternalUnits( const wxPoint& aPoint );

View File

@ -23,6 +23,7 @@
#include <cassert> #include <cassert>
#include <cmath> #include <cmath>
#include <math/vector2d.h> // for VECTOR2I
enum EDA_ANGLE_T enum EDA_ANGLE_T
@ -36,11 +37,13 @@ enum EDA_ANGLE_T
class EDA_ANGLE class EDA_ANGLE
{ {
public: public:
// Angles can be created in degrees, 1/10ths of a degree, and radians, /**
// and read as any of the angle types * Angles can be created in degrees, 1/10ths of a degree, or radians, and read as any of
// * the angle types.
// Angle type must be explicitly specified at creation, because *
// there is no other way of knowing what an int or a double represents * 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 ) : EDA_ANGLE( int aValue, EDA_ANGLE_T aAngleType ) :
m_value( 0 ), m_value( 0 ),
m_radians( 0.0 ), m_radians( 0.0 ),
@ -75,6 +78,52 @@ public:
} }
} }
explicit EDA_ANGLE( const VECTOR2I& aVector ) :
m_value( 0 ),
m_radians( 0.0 ),
m_initial_type( TENTHS_OF_A_DEGREE_T )
{
/* 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;
else
m_value = -1800;
}
else if( aVector.x == 0 )
{
if( aVector.y >= 0 )
m_value = 900;
else
m_value = -900;
}
else if( aVector.x == aVector.y )
{
if( aVector.x >= 0 )
m_value = 450;
else
m_value = -1800 + 450;
}
else if( aVector.x == -aVector.y )
{
if( aVector.x >= 0 )
m_value = -450;
else
m_value = 1800 - 450;
}
else
{
m_value = atan2( (double) aVector.y, (double) aVector.x )
/ TENTHS_OF_A_DEGREE_TO_RADIANS;
}
}
EDA_ANGLE() : EDA_ANGLE() :
m_value( 0 ), m_value( 0 ),
m_radians( 0.0 ), m_radians( 0.0 ),
@ -149,11 +198,8 @@ public:
return EDA_ANGLE( newAngle, RADIANS_T ); return EDA_ANGLE( newAngle, RADIANS_T );
} }
// if both were not given in radians, addition is done using // if both were not given in radians, addition is done using 1/10ths of a degree, then
// 1/10ths of a degree, then converted to original angle type // converted to original angle type
// of this angle
//int newAngle = normalize( AsTenthsOfADegree() + aAngle.AsTenthsOfADegree(),
//TENTHS_OF_A_DEGREE_T );
int newAngle = AsTenthsOfADegree() + aAngle.AsTenthsOfADegree(); int newAngle = AsTenthsOfADegree() + aAngle.AsTenthsOfADegree();
switch( initialType ) switch( initialType )
@ -288,6 +334,30 @@ inline EDA_ANGLE operator+( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB )
} }
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 );
}
}
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 );
}
}
inline bool operator==( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB ) inline bool operator==( const EDA_ANGLE& aAngleA, const EDA_ANGLE& aAngleB )
{ {
return aAngleA.AsTenthsOfADegree() == aAngleB.AsTenthsOfADegree(); return aAngleA.AsTenthsOfADegree() == aAngleB.AsTenthsOfADegree();

View File

@ -165,7 +165,7 @@ public:
*/ */
void SetArcAngleAndEnd( double aAngle, bool aCheckNegativeAngle = false ); void SetArcAngleAndEnd( double aAngle, bool aCheckNegativeAngle = false );
double GetArcAngle() const; EDA_ANGLE GetArcAngle() const;
/** /**
* Have the start and end points been swapped since they were set? * Have the start and end points been swapped since they were set?

View File

@ -53,14 +53,14 @@ enum RECT_CHAMFER_POSITIONS : int
* @param aPolyline is a buffer to store the polyline. * @param aPolyline is a buffer to store the polyline.
* @param aCenter is the center of the arc. * @param aCenter is the center of the arc.
* @param aRadius is the radius of the arc. * @param aRadius is the radius of the arc.
* @param aStartAngleDeg is the starting point (in degrees) of the arc. * @param aStartAngleDeg is the starting point of the arc.
* @param aArcAngleDeg is the angle (in degrees) of the arc. * @param aArcAngleDeg is the angle of the arc.
* @param aError is the internal units allowed for error approximation. * @param aError is the internal units allowed for error approximation.
* @param aErrorLoc determines if the approximation error be placed outside or inside the polygon. * @param aErrorLoc determines if the approximation error be placed outside or inside the polygon.
*/ */
int ConvertArcToPolyline( SHAPE_LINE_CHAIN& aPolyline, VECTOR2I aCenter, int aRadius, int ConvertArcToPolyline( SHAPE_LINE_CHAIN& aPolyline, VECTOR2I aCenter, int aRadius,
double aStartAngleDeg, double aArcAngleDeg, double aAccuracy, const EDA_ANGLE& aStartAngleDeg, const EDA_ANGLE& aArcAngleDeg,
ERROR_LOC aErrorLoc ); double aAccuracy, ERROR_LOC aErrorLoc );
/** /**

View File

@ -32,7 +32,7 @@
#include <math.h> // for copysign #include <math.h> // for copysign
#include <stdlib.h> // for abs #include <stdlib.h> // for abs
#include <eda_angle.h>
#include <math/vector2d.h> #include <math/vector2d.h>
class EDA_RECT; class EDA_RECT;
@ -50,9 +50,9 @@ enum ERROR_LOC { ERROR_OUTSIDE, ERROR_INSIDE };
* @param aRadius is the radius od the circle or arc * @param aRadius is the radius od the circle or arc
* @param aErrorMax is the max error * @param aErrorMax is the max error
* This is the max distance between the middle of a segment and the circle. * This is the max distance between the middle of a segment and the circle.
* @param aArcAngleDegree is the arc angle in degrees * @param aArcAngleDegree is the arc angle
*/ */
int GetArcToSegmentCount( int aRadius, int aErrorMax, double aArcAngleDegree ); int GetArcToSegmentCount( int aRadius, int aErrorMax, const EDA_ANGLE& aArcAngle );
/** /**
* @return the radius diffence of the circle defined by segments inside the circle * @return the radius diffence of the circle defined by segments inside the circle

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2018 CERN * Copyright (C) 2018 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2019-2022 KiCad Developers, see AUTHORS.txt for contributors.
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -28,6 +28,7 @@
#include <geometry/shape.h> #include <geometry/shape.h>
#include <convert_to_biu.h> #include <convert_to_biu.h>
#include <eda_angle.h>
#include <math/vector2d.h> // for VECTOR2I #include <math/vector2d.h> // for VECTOR2I
class SHAPE_LINE_CHAIN; class SHAPE_LINE_CHAIN;
@ -49,11 +50,11 @@ public:
* *
* @param aArcCenter is the arc center. * @param aArcCenter is the arc center.
* @param aArcStartPoint is the arc start point. * @param aArcStartPoint is the arc start point.
* @param aCenterAngle is the arc angle in degrees. * @param aCenterAngle is the arc angle.
* @param aWidth is the arc line thickness. * @param aWidth is the arc line thickness.
*/ */
SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint, double aCenterAngle, SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint,
int aWidth = 0 ); const EDA_ANGLE& aCenterAngle, int aWidth = 0 );
/** /**
* @param aArcStart is the arc start point. * @param aArcStart is the arc start point.

View File

@ -43,7 +43,7 @@ void TransformCircleToPolygon( SHAPE_LINE_CHAIN& aCornerBuffer, const VECTOR2I&
int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount ) int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount )
{ {
VECTOR2I corner_position; VECTOR2I corner_position;
int numSegs = GetArcToSegmentCount( aRadius, aError, 360.0 ); int numSegs = GetArcToSegmentCount( aRadius, aError, FULL_CIRCLE );
numSegs = std::max( aMinSegCount, numSegs ); numSegs = std::max( aMinSegCount, numSegs );
// The shape will be built with a even number of segs. Reason: the horizontal // The shape will be built with a even number of segs. Reason: the horizontal
@ -82,7 +82,7 @@ void TransformCircleToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aC
int aError, ERROR_LOC aErrorLoc, int aMinSegCount ) int aError, ERROR_LOC aErrorLoc, int aMinSegCount )
{ {
VECTOR2I corner_position; VECTOR2I corner_position;
int numSegs = GetArcToSegmentCount( aRadius, aError, 360.0 ); int numSegs = GetArcToSegmentCount( aRadius, aError, FULL_CIRCLE );
numSegs = std::max( aMinSegCount, numSegs ); numSegs = std::max( aMinSegCount, numSegs );
// The shape will be built with a even number of segs. Reason: the horizontal // The shape will be built with a even number of segs. Reason: the horizontal
@ -133,7 +133,7 @@ void TransformOvalToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aSta
// so, later, we will clamp the polygonal shape with the bounding box // so, later, we will clamp the polygonal shape with the bounding box
// of the segment. // of the segment.
int radius = aWidth / 2; int radius = aWidth / 2;
int numSegs = GetArcToSegmentCount( radius, aError, 360.0 ); int numSegs = GetArcToSegmentCount( radius, aError, FULL_CIRCLE );
numSegs = std::max( aMinSegCount, numSegs ); numSegs = std::max( aMinSegCount, numSegs );
int delta = 3600 / numSegs; // rotate angle in 0.1 degree int delta = 3600 / numSegs; // rotate angle in 0.1 degree
@ -281,7 +281,7 @@ void CornerListToPolygon( SHAPE_POLY_SET& outline, std::vector<ROUNDED_CORNER>&
} }
// Ensure 16+ segments per 360deg and ensure first & last segment are the same size // Ensure 16+ segments per 360deg and ensure first & last segment are the same size
int numSegs = std::max( 16, GetArcToSegmentCount( radius, aError, 360.0 ) ); int numSegs = std::max( 16, GetArcToSegmentCount( radius, aError, FULL_CIRCLE ) );
int angDelta = 3600 / numSegs; int angDelta = 3600 / numSegs;
int lastSegLen = endAngle % angDelta; // or 0 if last seg length is angDelta int lastSegLen = endAngle % angDelta; // or 0 if last seg length is angDelta
int angPos = lastSegLen ? ( angDelta + lastSegLen ) / 2 : angDelta; int angPos = lastSegLen ? ( angDelta + lastSegLen ) / 2 : angDelta;
@ -501,29 +501,28 @@ void TransformRoundChamferedRectToPolygon( SHAPE_POLY_SET& aCornerBuffer, const
int ConvertArcToPolyline( SHAPE_LINE_CHAIN& aPolyline, VECTOR2I aCenter, int aRadius, int ConvertArcToPolyline( SHAPE_LINE_CHAIN& aPolyline, VECTOR2I aCenter, int aRadius,
double aStartAngleDeg, double aArcAngleDeg, double aAccuracy, const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aArcAngle,
ERROR_LOC aErrorLoc ) double aAccuracy, ERROR_LOC aErrorLoc )
{ {
double endAngle = aStartAngleDeg + aArcAngleDeg;
int n = 2; int n = 2;
if( aRadius >= aAccuracy ) if( aRadius >= aAccuracy )
n = GetArcToSegmentCount( aRadius, aAccuracy, aArcAngleDeg )+1; // n >= 3 n = GetArcToSegmentCount( aRadius, aAccuracy, aArcAngle ) + 1;
if( aErrorLoc == ERROR_OUTSIDE ) if( aErrorLoc == ERROR_OUTSIDE )
{ {
int seg360 = std::abs( KiROUND( n * 360.0 / aArcAngleDeg ) ); int seg360 = std::abs( KiROUND( n * 360.0 / aArcAngle.AsDegrees() ) );
int actual_delta_radius = CircleToEndSegmentDeltaRadius( aRadius, seg360 ); int actual_delta_radius = CircleToEndSegmentDeltaRadius( aRadius, seg360 );
aRadius += actual_delta_radius; aRadius += actual_delta_radius;
} }
for( int i = 0; i <= n ; i++ ) for( int i = 0; i <= n ; i++ )
{ {
double rot = aStartAngleDeg; EDA_ANGLE rot = aStartAngle;
rot += ( aArcAngleDeg * i ) / n; rot += ( aArcAngle * i ) / n;
double x = aCenter.x + aRadius * cos( rot * M_PI / 180.0 ); double x = aCenter.x + aRadius * cos( rot.AsRadians() );
double y = aCenter.y + aRadius * sin( rot * M_PI / 180.0 ); double y = aCenter.y + aRadius * sin( rot.AsRadians() );
aPolyline.Append( KiROUND( x ), KiROUND( y ) ); aPolyline.Append( KiROUND( x ), KiROUND( y ) );
} }
@ -589,11 +588,13 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aStar
polyshape.NewOutline(); polyshape.NewOutline();
ConvertArcToPolyline( polyshape.Outline(2), center, arc_outer_radius, ConvertArcToPolyline( polyshape.Outline(2), center, arc_outer_radius,
arc_angle_start_deg, arc_angle, aError, errorLocOuter ); EDA_ANGLE( arc_angle_start_deg, DEGREES_T ),
EDA_ANGLE( arc_angle, DEGREES_T ), aError, errorLocOuter );
if( arc_inner_radius > 0 ) if( arc_inner_radius > 0 )
ConvertArcToPolyline( polyshape.Outline(2), center, arc_inner_radius, ConvertArcToPolyline( polyshape.Outline(2), center, arc_inner_radius,
arc_angle_end_deg, -arc_angle, aError, errorLocInner ); EDA_ANGLE( arc_angle_end_deg, DEGREES_T ),
-EDA_ANGLE( arc_angle, DEGREES_T ), aError, errorLocInner );
else else
polyshape.Append( center ); polyshape.Append( center );
#else #else

View File

@ -188,7 +188,7 @@ const SHAPE_LINE_CHAIN DIRECTION_45::BuildInitialTrace( const VECTOR2I& aP0, con
{ {
// Negative tangentLength: arc goes at the start // Negative tangentLength: arc goes at the start
VECTOR2I arcCenter = aP0 + centerDir.Resize( arcRadius ); VECTOR2I arcCenter = aP0 + centerDir.Resize( arcRadius );
SHAPE_ARC ca( arcCenter, aP0, 45 * rotationSign ); SHAPE_ARC ca( arcCenter, aP0, ANGLE_45 * rotationSign );
// Constructing with a center can lead to imprecise endpoint. We need to guarantee // Constructing with a center can lead to imprecise endpoint. We need to guarantee
// tangency of the endpoint. // tangency of the endpoint.

View File

@ -40,7 +40,7 @@
// with a 0.01mm maximum deviation yields 11 segments.) // with a 0.01mm maximum deviation yields 11 segments.)
#define MIN_SEGCOUNT_FOR_CIRCLE 8 #define MIN_SEGCOUNT_FOR_CIRCLE 8
int GetArcToSegmentCount( int aRadius, int aErrorMax, double aArcAngleDegree ) int GetArcToSegmentCount( int aRadius, int aErrorMax, const EDA_ANGLE& aArcAngle )
{ {
// calculate the number of segments to approximate a circle by segments // calculate the number of segments to approximate a circle by segments
// given the max distance between the middle of a segment and the circle // given the max distance between the middle of a segment and the circle
@ -57,7 +57,7 @@ int GetArcToSegmentCount( int aRadius, int aErrorMax, double aArcAngleDegree )
// (360.0 degrees). For very small radius values, this is mandatory. // (360.0 degrees). For very small radius values, this is mandatory.
arc_increment = std::min( 360.0/MIN_SEGCOUNT_FOR_CIRCLE, arc_increment ); arc_increment = std::min( 360.0/MIN_SEGCOUNT_FOR_CIRCLE, arc_increment );
int segCount = KiROUND( fabs( aArcAngleDegree ) / arc_increment ); int segCount = KiROUND( fabs( aArcAngle.AsDegrees() ) / arc_increment );
// Ensure at least two segments are used for algorithmic safety // Ensure at least two segments are used for algorithmic safety
return std::max( segCount, 2 ); return std::max( segCount, 2 );

View File

@ -41,15 +41,16 @@ std::ostream& operator<<( std::ostream& aStream, const SHAPE_ARC& aArc )
SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint, SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint,
double aCenterAngle, int aWidth ) : const EDA_ANGLE& aCenterAngle, int aWidth ) :
SHAPE( SH_ARC ), m_width( aWidth ) SHAPE( SH_ARC ),
m_width( aWidth )
{ {
m_start = aArcStartPoint; m_start = aArcStartPoint;
m_mid = aArcStartPoint; m_mid = aArcStartPoint;
m_end = aArcStartPoint; m_end = aArcStartPoint;
RotatePoint( m_mid, aArcCenter, -aCenterAngle * 10.0 / 2.0 ); RotatePoint( m_mid, aArcCenter, -EDA_ANGLE( aCenterAngle.AsDegrees() / 2.0, DEGREES_T ) );
RotatePoint( m_end, aArcCenter, -aCenterAngle * 10.0 ); RotatePoint( m_end, aArcCenter, -aCenterAngle );
update_bbox(); update_bbox();
} }
@ -57,15 +58,18 @@ SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint
SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcStart, const VECTOR2I& aArcMid, SHAPE_ARC::SHAPE_ARC( const VECTOR2I& aArcStart, const VECTOR2I& aArcMid,
const VECTOR2I& aArcEnd, int aWidth ) : const VECTOR2I& aArcEnd, int aWidth ) :
SHAPE( SH_ARC ), m_start( aArcStart ), m_mid( aArcMid ), m_end( aArcEnd ), SHAPE( SH_ARC ),
m_width( aWidth ) m_start( aArcStart ),
m_mid( aArcMid ),
m_end( aArcEnd ),
m_width( aWidth )
{ {
update_bbox(); update_bbox();
} }
SHAPE_ARC::SHAPE_ARC( const SEG& aSegmentA, const SEG& aSegmentB, int aRadius, int aWidth ) SHAPE_ARC::SHAPE_ARC( const SEG& aSegmentA, const SEG& aSegmentB, int aRadius, int aWidth ) :
: SHAPE( SH_ARC ) SHAPE( SH_ARC )
{ {
m_width = aWidth; m_width = aWidth;
@ -135,18 +139,17 @@ SHAPE_ARC::SHAPE_ARC( const SEG& aSegmentA, const SEG& aSegmentB, int aRadius, i
if( pToB.EuclideanNorm() == 0 ) if( pToB.EuclideanNorm() == 0 )
pToB = aSegmentB.A - p.get(); pToB = aSegmentB.A - p.get();
double pToAangle = ArcTangente( pToA.y, pToA.x ); EDA_ANGLE pToAangle( pToA );
double pToBangle = ArcTangente( pToB.y, pToB.x ); EDA_ANGLE pToBangle( pToB );
double alpha = NormalizeAngle180( pToAangle - pToBangle ); EDA_ANGLE alpha = ( pToAangle - pToBangle ).Normalize180();
double distPC = (double) aRadius / abs( sin( DECIDEG2RAD( alpha / 2 ) ) ); double distPC = (double) aRadius / abs( sin( alpha.AsRadians() / 2 ) );
double angPC = pToAangle - alpha / 2; EDA_ANGLE angPC = pToAangle - alpha / 2;
VECTOR2I arcCenter;
VECTOR2I arcCenter; arcCenter.x = p.get().x + KiROUND( distPC * cos( angPC.AsRadians() ) );
arcCenter.y = p.get().y + KiROUND( distPC * sin( angPC.AsRadians() ) );
arcCenter.x = p.get().x + KiROUND( distPC * cos( DECIDEG2RAD( angPC ) ) );
arcCenter.y = p.get().y + KiROUND( distPC * sin( DECIDEG2RAD( angPC ) ) );
// The end points of the arc are the orthogonal projected lines from the line segments // The end points of the arc are the orthogonal projected lines from the line segments
// to the center of the arc // to the center of the arc
@ -157,10 +160,10 @@ SHAPE_ARC::SHAPE_ARC( const SEG& aSegmentA, const SEG& aSegmentB, int aRadius, i
VECTOR2I startVector = m_start - arcCenter; VECTOR2I startVector = m_start - arcCenter;
VECTOR2I endVector = m_end - arcCenter; VECTOR2I endVector = m_end - arcCenter;
double startAngle = ArcTangente( startVector.y, startVector.x ); EDA_ANGLE startAngle( startVector );
double endAngle = ArcTangente( endVector.y, endVector.x ); EDA_ANGLE endAngle( endVector );
EDA_ANGLE midPointRotAngle = ( startAngle - endAngle ).Normalize180() / 2;
double midPointRotAngle = NormalizeAngle180( startAngle - endAngle ) / 2;
m_mid = m_start; m_mid = m_start;
RotatePoint( m_mid, arcCenter, midPointRotAngle ); RotatePoint( m_mid, arcCenter, midPointRotAngle );
} }
@ -438,14 +441,11 @@ double SHAPE_ARC::GetLength() const
double SHAPE_ARC::GetCentralAngle() const double SHAPE_ARC::GetCentralAngle() const
{ {
VECTOR2I center = GetCenter(); VECTOR2I center = GetCenter();
VECTOR2I p0 = m_start - center; EDA_ANGLE angle1 = EDA_ANGLE( m_mid - center ) - EDA_ANGLE( m_start - center );
VECTOR2I p1 = m_mid - center; EDA_ANGLE angle2 = EDA_ANGLE( m_end - center ) - EDA_ANGLE( m_mid - center );
VECTOR2I p2 = m_end - center;
double angle1 = ArcTangente( p1.y, p1.x ) - ArcTangente( p0.y, p0.x );
double angle2 = ArcTangente( p2.y, p2.x ) - ArcTangente( p1.y, p1.x );
return ( NormalizeAngle180( angle1 ) + NormalizeAngle180( angle2 ) ) / 10.0; return ( angle1 + angle2 ).Normalize180().AsTenthsOfADegree();
} }
@ -481,7 +481,7 @@ const SHAPE_LINE_CHAIN SHAPE_ARC::ConvertToPolyline( double aAccuracy,
else else
{ {
double arc_angle = std::abs( ca ); double arc_angle = std::abs( ca );
n = GetArcToSegmentCount( external_radius, aAccuracy, arc_angle ); n = GetArcToSegmentCount( external_radius, aAccuracy, EDA_ANGLE( arc_angle, DEGREES_T ) );
// Recalculate the effective error of approximation, that can be < aAccuracy // Recalculate the effective error of approximation, that can be < aAccuracy
int seg360 = n * 360.0 / arc_angle; int seg360 = n * 360.0 / arc_angle;

View File

@ -1907,7 +1907,7 @@ const std::string SHAPE_LINE_CHAIN::Format() const
for( size_t i = 0; i < m_arcs.size(); i++ ) for( size_t i = 0; i < m_arcs.size(); i++ )
ss << m_arcs[i].GetCenter().x << " " << m_arcs[i].GetCenter().y << " " ss << m_arcs[i].GetCenter().x << " " << m_arcs[i].GetCenter().y << " "
<< m_arcs[i].GetP0().x << " " << m_arcs[i].GetP0().y << " " << m_arcs[i].GetP0().x << " " << m_arcs[i].GetP0().y << " "
<< m_arcs[i].GetCentralAngle(); << m_arcs[i].GetCentralAngle().AsDegrees();
return ss.str();*/ return ss.str();*/
} }
@ -1986,7 +1986,7 @@ bool SHAPE_LINE_CHAIN::Parse( std::stringstream& aStream )
aStream >> p0.y; aStream >> p0.y;
aStream >> angle; aStream >> angle;
m_arcs.emplace_back( pc, p0, angle ); m_arcs.emplace_back( pc, p0, EDA_ANGLE( angle, DEGREES_T ) );
} }
return true; return true;

View File

@ -2155,11 +2155,11 @@ SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::chamferFilletPolygon( CORNER_MODE aMode,
argument = 1; argument = 1;
double arcAngle = acos( argument ); double arcAngle = acos( argument );
double arcAngleDegrees = arcAngle * 180.0 / M_PI; int segments = GetArcToSegmentCount( radius, aErrorMax,
int segments = GetArcToSegmentCount( radius, aErrorMax, arcAngleDegrees ); EDA_ANGLE( arcAngle, RADIANS_T ) );
double deltaAngle = arcAngle / segments; double deltaAngle = arcAngle / segments;
double startAngle = atan2( -ys, xs ); double startAngle = atan2( -ys, xs );
// Flip arc for inner corners // Flip arc for inner corners
if( xa * yb - ya * xb <= 0 ) if( xa * yb - ya * xb <= 0 )

View File

@ -345,18 +345,7 @@ void AR_MATRIX::drawSegmentQcq( int ux0, int uy0, int ux1, int uy1, int lg, int
dx = ux1 - ux0; dx = ux1 - ux0;
dy = uy1 - uy0; dy = uy1 - uy0;
double angle; EDA_ANGLE angle( VECTOR2I( dx, dy ) );
if( dx )
{
angle = ArcTangente( dy, dx );
}
else
{
angle = 900;
if( dy < 0 )
angle = -900;
}
RotatePoint( &dx, &dy, angle ); // dx = length, dy = 0 RotatePoint( &dx, &dy, angle ); // dx = length, dy = 0
@ -789,7 +778,8 @@ void AR_MATRIX::TraceSegmentPcb( PCB_SHAPE* aShape, int aColor, int aMargin,
int ux1 = aShape->GetStart().x - GetBrdCoordOrigin().x; int ux1 = aShape->GetStart().x - GetBrdCoordOrigin().x;
int uy1 = aShape->GetStart().y - GetBrdCoordOrigin().y; int uy1 = aShape->GetStart().y - GetBrdCoordOrigin().y;
traceArc( ux0, uy0, ux1, uy1, aShape->GetArcAngle(), half_width, layer, aColor, op_logic ); traceArc( ux0, uy0, ux1, uy1, aShape->GetArcAngle().AsTenthsOfADegree(), half_width,
layer, aColor, op_logic );
} }
} }

View File

@ -189,18 +189,16 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
case SHAPE_T::ARC: case SHAPE_T::ARC:
{ {
VECTOR2I pstart = graphic->GetStart(); VECTOR2I pstart = graphic->GetStart();
VECTOR2I center = graphic->GetCenter(); VECTOR2I center = graphic->GetCenter();
double angle = -graphic->GetArcAngle(); EDA_ANGLE angle = -graphic->GetArcAngle();
double radius = graphic->GetRadius(); double radius = graphic->GetRadius();
int steps = GetArcToSegmentCount( radius, aErrorMax, angle / 10.0 ); int steps = GetArcToSegmentCount( radius, aErrorMax, angle );
VECTOR2I pt;
for( int step = 1; step<=steps; ++step ) for( int step = 1; step<=steps; ++step )
{ {
double rotation = ( angle * step ) / steps; EDA_ANGLE rotation = ( angle * step ) / steps;
VECTOR2I pt = pstart;
pt = pstart;
RotatePoint( pt, center, rotation ); RotatePoint( pt, center, rotation );
@ -410,12 +408,12 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
// We do not support arcs in polygons, so approximate an arc with a series of // We do not support arcs in polygons, so approximate an arc with a series of
// short lines and put those line segments into the !same! PATH. // short lines and put those line segments into the !same! PATH.
VECTOR2I pstart = graphic->GetStart(); VECTOR2I pstart = graphic->GetStart();
VECTOR2I pend = graphic->GetEnd(); VECTOR2I pend = graphic->GetEnd();
VECTOR2I pcenter = graphic->GetCenter(); VECTOR2I pcenter = graphic->GetCenter();
double angle = -graphic->GetArcAngle(); EDA_ANGLE angle = -graphic->GetArcAngle();
double radius = graphic->GetRadius(); double radius = graphic->GetRadius();
int steps = GetArcToSegmentCount( radius, aErrorMax, angle / 10.0 ); int steps = GetArcToSegmentCount( radius, aErrorMax, angle );
if( !close_enough( prevPt, pstart, aChainingEpsilon ) ) if( !close_enough( prevPt, pstart, aChainingEpsilon ) )
{ {
@ -428,8 +426,9 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
// Create intermediate points between start and end: // Create intermediate points between start and end:
for( int step = 1; step < steps; ++step ) for( int step = 1; step < steps; ++step )
{ {
double rotation = ( angle * step ) / steps; EDA_ANGLE rotation = ( angle * step ) / steps;
VECTOR2I pt = pstart; VECTOR2I pt = pstart;
RotatePoint( pt, pcenter, rotation ); RotatePoint( pt, pcenter, rotation );
aPolygons.Append( pt ); aPolygons.Append( pt );
@ -593,7 +592,7 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
double angle = 3600.0; double angle = 3600.0;
VECTOR2I start = center; VECTOR2I start = center;
int radius = graphic->GetRadius(); int radius = graphic->GetRadius();
int steps = GetArcToSegmentCount( radius, aErrorMax, 360.0 ); int steps = GetArcToSegmentCount( radius, aErrorMax, FULL_CIRCLE );
VECTOR2I nextPt; VECTOR2I nextPt;
start.x += radius; start.x += radius;
@ -665,12 +664,12 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
// We do not support arcs in polygons, so approximate an arc with a series of // We do not support arcs in polygons, so approximate an arc with a series of
// short lines and put those line segments into the !same! PATH. // short lines and put those line segments into the !same! PATH.
{ {
VECTOR2I pstart = graphic->GetStart(); VECTOR2I pstart = graphic->GetStart();
VECTOR2I pend = graphic->GetEnd(); VECTOR2I pend = graphic->GetEnd();
VECTOR2I pcenter = graphic->GetCenter(); VECTOR2I pcenter = graphic->GetCenter();
double angle = -graphic->GetArcAngle(); EDA_ANGLE angle = -graphic->GetArcAngle();
int radius = graphic->GetRadius(); int radius = graphic->GetRadius();
int steps = GetArcToSegmentCount( radius, aErrorMax, angle / 10.0 ); int steps = GetArcToSegmentCount( radius, aErrorMax, angle );
if( !close_enough( prevPt, pstart, aChainingEpsilon ) ) if( !close_enough( prevPt, pstart, aChainingEpsilon ) )
{ {
@ -683,8 +682,8 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
// Create intermediate points between start and end: // Create intermediate points between start and end:
for( int step = 1; step < steps; ++step ) for( int step = 1; step < steps; ++step )
{ {
double rotation = ( angle * step ) / steps; EDA_ANGLE rotation = ( angle * step ) / steps;
VECTOR2I pt = pstart; VECTOR2I pt = pstart;
RotatePoint( pt, pcenter, rotation ); RotatePoint( pt, pcenter, rotation );

View File

@ -228,7 +228,7 @@ bool DIALOG_GRAPHIC_ITEM_PROPERTIES::TransferDataToWindow()
case SHAPE_T::ARC: case SHAPE_T::ARC:
SetTitle( _( "Arc Properties" ) ); SetTitle( _( "Arc Properties" ) );
m_AngleValue = m_item->GetArcAngle() / 10.0; m_AngleValue = m_item->GetArcAngle().AsDegrees();
m_filledCtrl->Show( false ); m_filledCtrl->Show( false );
break; break;

View File

@ -119,7 +119,7 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow()
m_endY.SetValue( m_shape->GetCenter().y ); m_endY.SetValue( m_shape->GetCenter().y );
m_radiusLabel->SetLabel( _( "Angle:" ) ); m_radiusLabel->SetLabel( _( "Angle:" ) );
m_radius.SetUnits( EDA_UNITS::DEGREES ); m_radius.SetUnits( EDA_UNITS::DEGREES );
m_radius.SetValue( m_shape->GetArcAngle() ); m_radius.SetValue( m_shape->GetArcAngle().AsTenthsOfADegree() );
m_ctrl1X.Show( false, true ); m_ctrl1X.Show( false, true );
m_ctrl1Y.Show( false, true ); m_ctrl1Y.Show( false, true );
m_ctrl2X.Show( false, true ); m_ctrl2X.Show( false, true );

View File

@ -95,7 +95,7 @@ bool primitivesNeedUpdate( const std::shared_ptr<PCB_SHAPE>& a,
TEST( a->GetStart(), b->GetStart() ); TEST( a->GetStart(), b->GetStart() );
TEST( a->GetEnd(), b->GetEnd() ); TEST( a->GetEnd(), b->GetEnd() );
TEST( a->GetCenter(), b->GetCenter() ); TEST( a->GetCenter(), b->GetCenter() );
TEST( a->GetArcAngle(), b->GetArcAngle() ); TEST( a->GetArcAngle().AsTenthsOfADegree(), b->GetArcAngle().AsTenthsOfADegree() );
break; break;
case SHAPE_T::BEZIER: case SHAPE_T::BEZIER:
@ -198,7 +198,7 @@ bool shapesNeedUpdate( const FP_SHAPE* a, const FP_SHAPE* b )
TEST( a->GetStart0(), b->GetStart0() ); TEST( a->GetStart0(), b->GetStart0() );
TEST( a->GetEnd0(), b->GetEnd0() ); TEST( a->GetEnd0(), b->GetEnd0() );
TEST( a->GetCenter0(), b->GetCenter0() ); TEST( a->GetCenter0(), b->GetCenter0() );
TEST( a->GetArcAngle(), b->GetArcAngle() ); TEST( a->GetArcAngle().AsTenthsOfADegree(), b->GetArcAngle().AsTenthsOfADegree() );
break; break;
case SHAPE_T::BEZIER: case SHAPE_T::BEZIER:

View File

@ -317,18 +317,18 @@ bool DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::Run()
{ {
SHAPE_LINE_CHAIN asPoly; SHAPE_LINE_CHAIN asPoly;
VECTOR2I center = shape->GetCenter(); VECTOR2I center = shape->GetCenter();
double angle = -shape->GetArcAngle(); EDA_ANGLE angle = -shape->GetArcAngle();
double r = shape->GetRadius(); double r = shape->GetRadius();
int steps = GetArcToSegmentCount( r, errorMax, angle / 10.0 ); int steps = GetArcToSegmentCount( r, errorMax, angle );
asPoly.Append( shape->GetStart() ); asPoly.Append( shape->GetStart() );
for( int step = 1; step <= steps; ++step ) for( int step = 1; step <= steps; ++step )
{ {
double rotation = ( angle * step ) / steps; EDA_ANGLE rotation = ( angle * step ) / steps;
VECTOR2I pt = shape->GetStart();
VECTOR2I pt = shape->GetStart();
RotatePoint( pt, center, rotation ); RotatePoint( pt, center, rotation );
asPoly.Append( pt ); asPoly.Append( pt );
} }

View File

@ -210,7 +210,7 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::buildRTrees()
solderMask->GetFill( F_Mask )->Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); solderMask->GetFill( F_Mask )->Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
solderMask->GetFill( B_Mask )->Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); solderMask->GetFill( B_Mask )->Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
int numSegs = GetArcToSegmentCount( m_webWidth / 2, m_maxError, 360.0 ); int numSegs = GetArcToSegmentCount( m_webWidth / 2, m_maxError, FULL_CIRCLE );
solderMask->GetFill( F_Mask )->Deflate( m_webWidth / 2, numSegs ); solderMask->GetFill( F_Mask )->Deflate( m_webWidth / 2, numSegs );
solderMask->GetFill( B_Mask )->Deflate( m_webWidth / 2, numSegs ); solderMask->GetFill( B_Mask )->Deflate( m_webWidth / 2, numSegs );

View File

@ -1273,7 +1273,7 @@ static void FootprintWriteShape( FILE* aFile, FOOTPRINT* aFootprint, const wxStr
VECTOR2I start = shape->GetStart0(); VECTOR2I start = shape->GetStart0();
VECTOR2I end = shape->GetEnd0(); VECTOR2I end = shape->GetEnd0();
if( shape->GetArcAngle() > 0 ) if( shape->GetArcAngle() > ANGLE_0 )
std::swap( start, end ); std::swap( start, end );
fprintf( aFile, "ARC %g %g %g %g %g %g\n", fprintf( aFile, "ARC %g %g %g %g %g %g\n",

View File

@ -134,7 +134,7 @@ static void idf_export_outline( BOARD* aPcb, IDF3_BOARD& aIDFBoard )
sp.y = -graphic->GetCenter().y * scale + offY; sp.y = -graphic->GetCenter().y * scale + offY;
ep.x = graphic->GetStart().x * scale + offX; ep.x = graphic->GetStart().x * scale + offX;
ep.y = -graphic->GetStart().y * scale + offY; ep.y = -graphic->GetStart().y * scale + offY;
IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep, -graphic->GetArcAngle() / 10.0, true ); IDF_SEGMENT* seg = new IDF_SEGMENT( sp, ep, -graphic->GetArcAngle().AsDegrees(), true );
if( seg ) if( seg )
lines.push_back( seg ); lines.push_back( seg );

View File

@ -651,8 +651,8 @@ void EXPORTER_PCB_VRML::ExportVrmlViaHoles()
// Set the optimal number of segments to approximate a circle. // Set the optimal number of segments to approximate a circle.
// SetArcParams needs a count max, and the minimal and maximal length // SetArcParams needs a count max, and the minimal and maximal length
// of segments // of segments
int nsides = GetArcToSegmentCount( via->GetDrillValue(), int nsides = GetArcToSegmentCount( via->GetDrillValue(), Millimeter2iu( err_approx_max ),
Millimeter2iu( err_approx_max ), 360.0 ); FULL_CIRCLE );
double minSegLength = M_PI * 2.0 * hole_radius / nsides; double minSegLength = M_PI * 2.0 * hole_radius / nsides;
double maxSegLength = minSegLength*2.0; double maxSegLength = minSegLength*2.0;
@ -679,8 +679,8 @@ void EXPORTER_PCB_VRML::ExportVrmlPadHole( PAD* aPad )
// Export the hole on the edge layer // Export the hole on the edge layer
if( hole_drill > 0 ) if( hole_drill > 0 )
{ {
int nsides = GetArcToSegmentCount( hole_drill, int nsides = GetArcToSegmentCount( hole_drill, Millimeter2iu( err_approx_max ),
Millimeter2iu( err_approx_max ), 360.0 ); FULL_CIRCLE );
double minSegLength = M_PI * hole_drill / nsides; double minSegLength = M_PI * hole_drill / nsides;
double maxSegLength = minSegLength*2.0; double maxSegLength = minSegLength*2.0;

View File

@ -107,7 +107,7 @@ class FOOTPRINT : public BOARD_ITEM_CONTAINER
public: public:
FOOTPRINT( BOARD* parent ); FOOTPRINT( BOARD* parent );
FOOTPRINT( const FOOTPRINT& aFootprint ); FOOTPRINT( const FOOTPRINT& aFootprint );
// Move constructor and operator needed due to std containers inside the footprint // Move constructor and operator needed due to std containers inside the footprint
FOOTPRINT( FOOTPRINT&& aFootprint ); FOOTPRINT( FOOTPRINT&& aFootprint );

View File

@ -48,13 +48,13 @@
* @param a_ArcAngle = arc length in 0.1 degrees. * @param a_ArcAngle = arc length in 0.1 degrees.
*/ */
static void gen_arc( std::vector<VECTOR2I>& aBuffer, const VECTOR2I& aStartPoint, static void gen_arc( std::vector<VECTOR2I>& aBuffer, const VECTOR2I& aStartPoint,
const VECTOR2I& aCenter, int a_ArcAngle ) const VECTOR2I& aCenter, const EDA_ANGLE& a_ArcAngle )
{ {
auto first_point = aStartPoint - aCenter; auto first_point = aStartPoint - aCenter;
auto radius = KiROUND( EuclideanNorm( first_point ) ); auto radius = KiROUND( EuclideanNorm( first_point ) );
int seg_count = GetArcToSegmentCount( radius, ARC_HIGH_DEF, a_ArcAngle / 10.0 ); int seg_count = GetArcToSegmentCount( radius, ARC_HIGH_DEF, a_ArcAngle );
double increment_angle = (double) a_ArcAngle * M_PI / 1800 / seg_count; double increment_angle = a_ArcAngle.AsRadians() / seg_count;
// Creates nb_seg point to approximate arc by segments: // Creates nb_seg point to approximate arc by segments:
for( int ii = 1; ii <= seg_count; ii++ ) for( int ii = 1; ii <= seg_count; ii++ )
@ -138,12 +138,13 @@ static INDUCTOR_S_SHAPE_RESULT BuildCornersList_S_Shape( std::vector<VECTOR2I>&
// of 360/ADJUST_SIZE angle // of 360/ADJUST_SIZE angle
#define ADJUST_SIZE 0.988 #define ADJUST_SIZE 0.988
auto pt = aEndPoint - aStartPoint; auto pt = aEndPoint - aStartPoint;
double angle = -ArcTangente( pt.y, pt.x ); EDA_ANGLE angle( pt );
int min_len = KiROUND( EuclideanNorm( pt ) ); int min_len = KiROUND( EuclideanNorm( pt ) );
int segm_len = 0; // length of segments int segm_len = 0; // length of segments
int full_len; // full len of shape (sum of length of all segments + arcs) int full_len; // full len of shape (sum of length of all segments + arcs)
angle = -angle;
/* Note: calculations are made for a vertical coil (more easy calculations) /* Note: calculations are made for a vertical coil (more easy calculations)
* and after points are rotated to their actual position * and after points are rotated to their actual position
@ -228,7 +229,7 @@ static INDUCTOR_S_SHAPE_RESULT BuildCornersList_S_Shape( std::vector<VECTOR2I>&
auto centre = pt; auto centre = pt;
centre.x -= radius; centre.x -= radius;
gen_arc( aBuffer, pt, centre, -900 ); gen_arc( aBuffer, pt, centre, -ANGLE_90 );
pt = aBuffer.back(); pt = aBuffer.back();
int half_size_seg_len = segm_len / 2 - radius; int half_size_seg_len = segm_len / 2 - radius;
@ -246,17 +247,14 @@ static INDUCTOR_S_SHAPE_RESULT BuildCornersList_S_Shape( std::vector<VECTOR2I>&
for( ii = 0; ii < segm_count; ii++ ) for( ii = 0; ii < segm_count; ii++ )
{ {
int arc_angle;
if( ii & 1 ) // odd order arcs are greater than 0 if( ii & 1 ) // odd order arcs are greater than 0
sign = -1; sign = -1;
else else
sign = 1; sign = 1;
arc_angle = 1800 * sign;
centre = pt; centre = pt;
centre.y += radius; centre.y += radius;
gen_arc( aBuffer, pt, centre, arc_angle ); gen_arc( aBuffer, pt, centre, ANGLE_180 * sign );
pt = aBuffer.back(); pt = aBuffer.back();
pt.x += segm_len * sign; pt.x += segm_len * sign;
aBuffer.push_back( pt ); aBuffer.push_back( pt );
@ -272,15 +270,13 @@ static INDUCTOR_S_SHAPE_RESULT BuildCornersList_S_Shape( std::vector<VECTOR2I>&
pt = aBuffer.back(); pt = aBuffer.back();
centre = pt; centre = pt;
centre.y += radius; centre.y += radius;
gen_arc( aBuffer, pt, centre, 900 * sign ); gen_arc( aBuffer, pt, centre, ANGLE_90 * sign );
// Rotate point // Rotate point
angle += 900; angle += ANGLE_90;
for( unsigned jj = 0; jj < aBuffer.size(); jj++ ) for( unsigned jj = 0; jj < aBuffer.size(); jj++ )
{
RotatePoint( aBuffer[jj], aStartPoint, angle ); RotatePoint( aBuffer[jj], aStartPoint, angle );
}
// push last point (end point) // push last point (end point)
aBuffer.push_back( aEndPoint ); aBuffer.push_back( aEndPoint );

View File

@ -1570,7 +1570,7 @@ void PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
if( aClearanceValue ) if( aClearanceValue )
{ {
int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ), int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, FULL_CIRCLE ),
pad_min_seg_per_circle_count ); pad_min_seg_per_circle_count );
int clearance = aClearanceValue; int clearance = aClearanceValue;

View File

@ -648,12 +648,12 @@ void PCB_PAINTER::draw( const PCB_TRACK* aTrack, int aLayer )
void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer ) void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
{ {
VECTOR2D center( aArc->GetCenter() ); VECTOR2D center( aArc->GetCenter() );
int width = aArc->GetWidth(); int width = aArc->GetWidth();
COLOR4D color = m_pcbSettings.GetColor( aArc, aLayer ); COLOR4D color = m_pcbSettings.GetColor( aArc, aLayer );
double radius = aArc->GetRadius(); double radius = aArc->GetRadius();
double start_angle = DECIDEG2RAD( aArc->GetArcAngleStart() ); EDA_ANGLE start_angle = aArc->GetArcAngleStart();
double angle = DECIDEG2RAD( aArc->GetAngle() ); EDA_ANGLE angle = aArc->GetAngle();
if( IsNetnameLayer( aLayer ) ) if( IsNetnameLayer( aLayer ) )
{ {
@ -670,7 +670,8 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
m_gal->SetIsFill( not outline_mode ); m_gal->SetIsFill( not outline_mode );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth ); m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle, width, m_maxError ); m_gal->DrawArcSegment( center, radius, start_angle.AsRadians(),
( start_angle + angle ).AsRadians(), width, m_maxError );
} }
// Clearance lines // Clearance lines
@ -685,8 +686,9 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color ); m_gal->SetStrokeColor( color );
m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle, m_gal->DrawArcSegment( center, radius, start_angle.AsRadians(),
width + clearance * 2, m_maxError ); ( start_angle + angle ).AsRadians(), width + clearance * 2,
m_maxError );
} }
// Debug only: enable this code only to test the TransformArcToPolygon function // Debug only: enable this code only to test the TransformArcToPolygon function
@ -1211,7 +1213,7 @@ void PCB_PAINTER::draw( const PAD* aPad, int aLayer )
if( margin.x < 0 ) // The poly shape must be deflated if( margin.x < 0 ) // The poly shape must be deflated
{ {
int numSegs = GetArcToSegmentCount( -margin.x, m_maxError, 360.0 ); int numSegs = GetArcToSegmentCount( -margin.x, m_maxError, FULL_CIRCLE );
SHAPE_POLY_SET outline; SHAPE_POLY_SET outline;
outline.NewOutline(); outline.NewOutline();

View File

@ -845,20 +845,20 @@ bool PCB_ARC::HitTest( const VECTOR2I& aPosition, int aAccuracy ) const
if( std::abs( dist - radius ) > max_dist ) if( std::abs( dist - radius ) > max_dist )
return false; return false;
double arc_angle_start = GetArcAngleStart(); // Always 0.0 ... 360 deg, in 0.1 deg EDA_ANGLE arc_angle = GetAngle();
double arc_hittest = ArcTangente( relpos.y, relpos.x ); EDA_ANGLE arc_angle_start = GetArcAngleStart(); // Always 0.0 ... 360 deg
EDA_ANGLE arc_hittest( relpos );
// Calculate relative angle between the starting point of the arc, and the test point // Calculate relative angle between the starting point of the arc, and the test point
arc_hittest -= arc_angle_start; arc_hittest -= arc_angle_start;
// Normalise arc_hittest between 0 ... 360 deg // Normalise arc_hittest between 0 ... 360 deg
NORMALIZE_ANGLE_POS( arc_hittest ); arc_hittest.Normalize();
double arc_angle = GetAngle();
if( arc_angle < 0 ) if( arc_angle < ANGLE_0 )
return arc_hittest >= 3600 + arc_angle; return arc_hittest >= ANGLE_360 + arc_angle;
return arc_hittest <= arc_angle; return arc_hittest <= arc_angle;
} }
@ -969,34 +969,25 @@ double PCB_ARC::GetRadius() const
return GetLineLength( center, m_Start ); return GetLineLength( center, m_Start );
} }
double PCB_ARC::GetAngle() const EDA_ANGLE PCB_ARC::GetAngle() const
{ {
VECTOR2I center = GetPosition(); VECTOR2I center = GetPosition();
VECTOR2I p0 = m_Start - center; EDA_ANGLE angle1 = EDA_ANGLE( m_Mid - center ) - EDA_ANGLE( m_Start - center );
VECTOR2I p1 = m_Mid - center; EDA_ANGLE angle2 = EDA_ANGLE( m_End - center ) - EDA_ANGLE( m_Mid - center );
VECTOR2I p2 = m_End - center;
double angle1 = ArcTangente( p1.y, p1.x ) - ArcTangente( p0.y, p0.x );
double angle2 = ArcTangente( p2.y, p2.x ) - ArcTangente( p1.y, p1.x );
return NormalizeAngle180( angle1 ) + NormalizeAngle180( angle2 ); return angle1.Normalize180() + angle2.Normalize180();
} }
double PCB_ARC::GetArcAngleStart() const EDA_ANGLE PCB_ARC::GetArcAngleStart() const
{ {
VECTOR2I center = GetPosition(); EDA_ANGLE angleStart( m_Start - GetPosition() );
return angleStart.Normalize();
double angleStart = ArcTangente( m_Start.y - center.y,
m_Start.x - center.x );
return NormalizeAnglePos( angleStart );
} }
double PCB_ARC::GetArcAngleEnd() const EDA_ANGLE PCB_ARC::GetArcAngleEnd() const
{ {
VECTOR2I center = GetPosition(); EDA_ANGLE angleEnd( m_End - GetPosition() );
return angleEnd.Normalize();
double angleEnd = ArcTangente( m_End.y - center.y,
m_End.x - center.x );
return NormalizeAnglePos( angleEnd );
} }

View File

@ -280,9 +280,9 @@ public:
virtual VECTOR2I GetCenter() const override { return GetPosition(); } virtual VECTOR2I GetCenter() const override { return GetPosition(); }
double GetRadius() const; double GetRadius() const;
double GetAngle() const; EDA_ANGLE GetAngle() const;
double GetArcAngleStart() const; EDA_ANGLE GetArcAngleStart() const;
double GetArcAngleEnd() const; EDA_ANGLE GetArcAngleEnd() const;
virtual bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override; virtual bool HitTest( const VECTOR2I& aPosition, int aAccuracy = 0 ) const override;
virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override; virtual bool HitTest( const EDA_RECT& aRect, bool aContained = true, int aAccuracy = 0 ) const override;
@ -302,10 +302,7 @@ public:
*/ */
virtual double GetLength() const override virtual double GetLength() const override
{ {
double radius = GetRadius(); return GetRadius() * std::abs( GetAngle().AsRadians() );
double includedAngle = std::abs( GetAngle() );
return radius * M_PI * includedAngle / 1800.0;
} }
EDA_ITEM* Clone() const override; EDA_ITEM* Clone() const override;

View File

@ -373,7 +373,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
// Shape polygon can have holes so use InflateWithLinkedHoles(), not Inflate() // Shape polygon can have holes so use InflateWithLinkedHoles(), not Inflate()
// which can create bad shapes if margin.x is < 0 // which can create bad shapes if margin.x is < 0
int maxError = aBoard->GetDesignSettings().m_MaxError; int maxError = aBoard->GetDesignSettings().m_MaxError;
int numSegs = GetArcToSegmentCount( mask_clearance, maxError, 360.0 ); int numSegs = GetArcToSegmentCount( mask_clearance, maxError, FULL_CIRCLE );
outline.InflateWithLinkedHoles( mask_clearance, numSegs, outline.InflateWithLinkedHoles( mask_clearance, numSegs,
SHAPE_POLY_SET::PM_FAST ); SHAPE_POLY_SET::PM_FAST );
dummy.DeletePrimitivesList(); dummy.DeletePrimitivesList();
@ -421,7 +421,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
dummy.SetOrientation( ANGLE_0 ); dummy.SetOrientation( ANGLE_0 );
SHAPE_POLY_SET outline; SHAPE_POLY_SET outline;
int maxError = aBoard->GetDesignSettings().m_MaxError; int maxError = aBoard->GetDesignSettings().m_MaxError;
int numSegs = GetArcToSegmentCount( mask_clearance, maxError, 360.0 ); int numSegs = GetArcToSegmentCount( mask_clearance, maxError, FULL_CIRCLE );
dummy.TransformShapeWithClearanceToPolygon( outline, UNDEFINED_LAYER, 0, dummy.TransformShapeWithClearanceToPolygon( outline, UNDEFINED_LAYER, 0,
maxError, ERROR_INSIDE ); maxError, ERROR_INSIDE );
outline.InflateWithLinkedHoles( mask_clearance, numSegs, outline.InflateWithLinkedHoles( mask_clearance, numSegs,
@ -456,7 +456,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
// Shape polygon can have holes so use InflateWithLinkedHoles(), not Inflate() // Shape polygon can have holes so use InflateWithLinkedHoles(), not Inflate()
// which can create bad shapes if margin.x is < 0 // which can create bad shapes if margin.x is < 0
int maxError = aBoard->GetDesignSettings().m_MaxError; int maxError = aBoard->GetDesignSettings().m_MaxError;
int numSegs = GetArcToSegmentCount( mask_clearance, maxError, 360.0 ); int numSegs = GetArcToSegmentCount( mask_clearance, maxError, FULL_CIRCLE );
shape.InflateWithLinkedHoles( mask_clearance, numSegs, SHAPE_POLY_SET::PM_FAST ); shape.InflateWithLinkedHoles( mask_clearance, numSegs, SHAPE_POLY_SET::PM_FAST );
dummy.DeletePrimitivesList(); dummy.DeletePrimitivesList();
dummy.AddPrimitivePoly( shape, 0, true ); dummy.AddPrimitivePoly( shape, 0, true );
@ -578,14 +578,15 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
if( track->Type() == PCB_ARC_T ) if( track->Type() == PCB_ARC_T )
{ {
const PCB_ARC* arc = static_cast<const PCB_ARC*>( track ); const PCB_ARC* arc = static_cast<const PCB_ARC*>( track );
VECTOR2D center( arc->GetCenter() ); VECTOR2D center( arc->GetCenter() );
int radius = arc->GetRadius(); int radius = arc->GetRadius();
double start_angle = arc->GetArcAngleStart(); EDA_ANGLE start_angle = arc->GetArcAngleStart();
double end_angle = start_angle + arc->GetAngle(); EDA_ANGLE end_angle = start_angle + arc->GetAngle();
aPlotter->ThickArc( VECTOR2I( center.x, center.y ), -end_angle, -start_angle, aPlotter->ThickArc( VECTOR2I( center.x, center.y ), -end_angle.AsTenthsOfADegree(),
radius, width, plotMode, &gbr_metadata ); -start_angle.AsTenthsOfADegree(), radius, width, plotMode,
&gbr_metadata );
} }
else else
{ {
@ -934,7 +935,7 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
} }
} }
int numSegs = GetArcToSegmentCount( inflate, maxError, 360.0 ); int numSegs = GetArcToSegmentCount( inflate, maxError, FULL_CIRCLE );
// Merge all polygons: After deflating, not merged (not overlapping) polygons // Merge all polygons: After deflating, not merged (not overlapping) polygons
// will have the initial shape (with perhaps small changes due to deflating transform) // will have the initial shape (with perhaps small changes due to deflating transform)

View File

@ -639,19 +639,19 @@ void BRDITEMS_PLOTTER::PlotFootprintGraphicItem( const FP_SHAPE* aShape )
case SHAPE_T::ARC: case SHAPE_T::ARC:
{ {
radius = KiROUND( GetLineLength( aShape->GetCenter(), aShape->GetStart() ) ); radius = KiROUND( GetLineLength( aShape->GetCenter(), aShape->GetStart() ) );
double startAngle = ArcTangente( aShape->GetStart().y - aShape->GetCenter().y, EDA_ANGLE startAngle( aShape->GetStart() - aShape->GetCenter() );
aShape->GetStart().x - aShape->GetCenter().x ); EDA_ANGLE endAngle = startAngle + aShape->GetArcAngle();
double endAngle = startAngle + aShape->GetArcAngle();
// when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg // when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg
if( std::abs( aShape->GetArcAngle() ) == 3600.0 ) if( std::abs( aShape->GetArcAngle().AsDegrees() ) == 360.0 )
{ {
m_plotter->ThickCircle( aShape->GetCenter(), radius * 2, thickness, GetPlotMode(), m_plotter->ThickCircle( aShape->GetCenter(), radius * 2, thickness, GetPlotMode(),
&gbr_metadata ); &gbr_metadata );
} }
else else
{ {
m_plotter->ThickArc( aShape->GetCenter(), -endAngle, -startAngle, radius, thickness, m_plotter->ThickArc( aShape->GetCenter(), -endAngle.AsTenthsOfADegree(),
-startAngle.AsTenthsOfADegree(), radius, thickness,
GetPlotMode(), &gbr_metadata ); GetPlotMode(), &gbr_metadata );
} }
} }
@ -956,20 +956,20 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape )
case SHAPE_T::ARC: case SHAPE_T::ARC:
{ {
double startAngle = ArcTangente( aShape->GetStart().y - aShape->GetCenter().y, EDA_ANGLE startAngle( aShape->GetStart() - aShape->GetCenter() );
aShape->GetStart().x - aShape->GetCenter().x ); EDA_ANGLE endAngle = startAngle + aShape->GetArcAngle();
double endAngle = startAngle + aShape->GetArcAngle();
// when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg // when startAngle == endAngle ThickArc() doesn't know whether it's 0 deg and 360 deg
if( std::abs( aShape->GetArcAngle() ) == 3600.0 ) if( std::abs( aShape->GetArcAngle().AsDegrees() ) == 360.0 )
{ {
m_plotter->ThickCircle( aShape->GetCenter(), aShape->GetRadius() * 2, thickness, m_plotter->ThickCircle( aShape->GetCenter(), aShape->GetRadius() * 2, thickness,
GetPlotMode(), &gbr_metadata ); GetPlotMode(), &gbr_metadata );
} }
else else
{ {
m_plotter->ThickArc( aShape->GetCenter(), -endAngle, -startAngle, m_plotter->ThickArc( aShape->GetCenter(), -endAngle.AsTenthsOfADegree(),
aShape->GetRadius(), thickness, GetPlotMode(), &gbr_metadata ); -startAngle.AsTenthsOfADegree(), aShape->GetRadius(),
thickness, GetPlotMode(), &gbr_metadata );
} }
break; break;

View File

@ -176,7 +176,8 @@ void HelperShapeLineChainFromAltiumVertices( SHAPE_LINE_CHAIN& aLine,
{ {
if( vertex.isRound ) if( vertex.isRound )
{ {
double angle = NormalizeAngleDegreesPos( vertex.endangle - vertex.startangle ); EDA_ANGLE angle( vertex.endangle - vertex.startangle, DEGREES_T );
angle.Normalize();
double startradiant = DEG2RAD( vertex.startangle ); double startradiant = DEG2RAD( vertex.startangle );
double endradiant = DEG2RAD( vertex.endangle ); double endradiant = DEG2RAD( vertex.endangle );
@ -1990,17 +1991,18 @@ void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader,
if( klayer >= F_Cu && klayer <= B_Cu ) if( klayer >= F_Cu && klayer <= B_Cu )
{ {
double angle = -NormalizeAngleDegreesPos( elem.endangle - elem.startangle ); EDA_ANGLE angle( elem.startangle - elem.endangle, DEGREES_T );
angle.Normalize();
double startradiant = DEG2RAD( elem.startangle ); double startradiant = DEG2RAD( elem.startangle );
VECTOR2I arcStartOffset = VECTOR2I arcStartOffset = VECTOR2I( KiROUND( std::cos( startradiant ) * elem.radius ),
VECTOR2I( KiROUND( std::cos( startradiant ) * elem.radius ), -KiROUND( std::sin( startradiant ) * elem.radius ) );
-KiROUND( std::sin( startradiant ) * elem.radius ) );
arcStartOffset += elem.center; arcStartOffset += elem.center;
// If it's a circle then add two 180-degree arcs // If it's a circle then add two 180-degree arcs
if( elem.startangle == 0. && elem.endangle == 360. ) if( elem.startangle == 0.0 && elem.endangle == 360.0 )
angle = 180.; angle = ANGLE_180;
SHAPE_ARC shapeArc( elem.center, arcStartOffset, angle, elem.width ); SHAPE_ARC shapeArc( elem.center, arcStartOffset, angle, elem.width );
PCB_ARC* arc = new PCB_ARC( m_board, &shapeArc ); PCB_ARC* arc = new PCB_ARC( m_board, &shapeArc );

View File

@ -2805,7 +2805,6 @@ PCB_SHAPE* CADSTAR_PCB_ARCHIVE_LOADER::getShapeFromVertex( const POINT& aCadstar
{ {
PCB_SHAPE* shape = nullptr; PCB_SHAPE* shape = nullptr;
bool cw = false; bool cw = false;
double arcStartAngle, arcEndAngle, arcAngle;
VECTOR2I startPoint = getKiCadPoint( aCadstarStartPoint ); VECTOR2I startPoint = getKiCadPoint( aCadstarStartPoint );
VECTOR2I endPoint = getKiCadPoint( aCadstarVertex.End ); VECTOR2I endPoint = getKiCadPoint( aCadstarVertex.End );
@ -2842,7 +2841,7 @@ PCB_SHAPE* CADSTAR_PCB_ARCHIVE_LOADER::getShapeFromVertex( const POINT& aCadstar
case VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE: case VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE:
case VERTEX_TYPE::ANTICLOCKWISE_ARC: case VERTEX_TYPE::ANTICLOCKWISE_ARC:
{
if( isFootprint( aContainer ) ) if( isFootprint( aContainer ) )
shape = new FP_SHAPE((FOOTPRINT*) aContainer, SHAPE_T::ARC ); shape = new FP_SHAPE((FOOTPRINT*) aContainer, SHAPE_T::ARC );
else else
@ -2851,19 +2850,20 @@ PCB_SHAPE* CADSTAR_PCB_ARCHIVE_LOADER::getShapeFromVertex( const POINT& aCadstar
shape->SetCenter( centerPoint ); shape->SetCenter( centerPoint );
shape->SetStart( startPoint ); shape->SetStart( startPoint );
arcStartAngle = getPolarAngle( startPoint - centerPoint ); EDA_ANGLE arcStartAngle( startPoint - centerPoint );
arcEndAngle = getPolarAngle( endPoint - centerPoint ); EDA_ANGLE arcEndAngle( endPoint - centerPoint );
arcAngle = arcEndAngle - arcStartAngle; EDA_ANGLE arcAngle = arcEndAngle - arcStartAngle;
//TODO: detect if we are supposed to draw a circle instead (i.e. two SEMICIRCLEs //TODO: detect if we are supposed to draw a circle instead (i.e. two SEMICIRCLEs
// with opposite start/end points and same centre point) // with opposite start/end points and same centre point)
if( cw ) if( cw )
shape->SetArcAngleAndEnd( NormalizeAnglePos( arcAngle ) ); shape->SetArcAngleAndEnd( arcAngle.Normalize().AsTenthsOfADegree() );
else else
shape->SetArcAngleAndEnd( NormalizeAngleNeg( arcAngle ), true ); shape->SetArcAngleAndEnd( -arcAngle.Normalize().AsTenthsOfADegree(), true );
break; break;
} }
}
//Apply transforms //Apply transforms
if( aMirrorInvert ) if( aMirrorInvert )
@ -2992,7 +2992,7 @@ SHAPE_LINE_CHAIN CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromShapes( const std::
if( shape->GetClass() == wxT( "MGRAPHIC" ) ) if( shape->GetClass() == wxT( "MGRAPHIC" ) )
{ {
FP_SHAPE* fp_shape = (FP_SHAPE*) shape; FP_SHAPE* fp_shape = (FP_SHAPE*) shape;
SHAPE_ARC arc( fp_shape->GetCenter0(), fp_shape->GetStart0(), fp_shape->GetArcAngle() / 10.0 ); SHAPE_ARC arc( fp_shape->GetCenter0(), fp_shape->GetStart0(), fp_shape->GetArcAngle() );
if( shape->EndsSwapped() ) if( shape->EndsSwapped() )
arc.Reverse(); arc.Reverse();
@ -3001,7 +3001,7 @@ SHAPE_LINE_CHAIN CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromShapes( const std::
} }
else else
{ {
SHAPE_ARC arc( shape->GetCenter(), shape->GetStart(), shape->GetArcAngle() / 10.0 ); SHAPE_ARC arc( shape->GetCenter(), shape->GetStart(), shape->GetArcAngle() );
if( shape->EndsSwapped() ) if( shape->EndsSwapped() )
arc.Reverse(); arc.Reverse();
@ -3880,12 +3880,6 @@ VECTOR2I CADSTAR_PCB_ARCHIVE_LOADER::getKiCadPoint( const VECTOR2I& aCadstarPoin
} }
double CADSTAR_PCB_ARCHIVE_LOADER::getPolarAngle( const VECTOR2I& aPoint )
{
return NormalizeAnglePos( ArcTangente( aPoint.y, aPoint.x ) );
}
NETINFO_ITEM* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadNet( const NET_ID& aCadstarNetID ) NETINFO_ITEM* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadNet( const NET_ID& aCadstarNetID )
{ {
if( aCadstarNetID.IsEmpty() ) if( aCadstarNetID.IsEmpty() )

View File

@ -489,13 +489,6 @@ private:
return getAngleTenthDegree( aCadstarAngle ) / 10.0; return getAngleTenthDegree( aCadstarAngle ) / 10.0;
} }
/**
* @brief
* @param aPoint
* @return Angle in decidegrees of the polar representation of the point, scaled 0..360
*/
double getPolarAngle( const VECTOR2I& aPoint );
/** /**
* @brief Searches m_netMap and returns the NETINFO_ITEM pointer if exists. Otherwise * @brief Searches m_netMap and returns the NETINFO_ITEM pointer if exists. Otherwise
* creates a new one and adds it to m_board. * creates a new one and adds it to m_board.

View File

@ -1449,7 +1449,8 @@ ZONE* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode )
double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 ) double radius = sqrt( pow( center.x - kicad_x( v1.x ), 2 )
+ pow( center.y - kicad_y( v1.y ), 2 ) ); + pow( center.y - kicad_y( v1.y ), 2 ) );
int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF, *v1.curve ); int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF,
EDA_ANGLE( *v1.curve, DEGREES_T ) );
double delta_angle = angle / segCount; double delta_angle = angle / segCount;
for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle ); for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta_angle );
@ -2144,7 +2145,8 @@ void EAGLE_PLUGIN::packagePolygon( FOOTPRINT* aFootprint, wxXmlNode* aTree ) con
if( KiROUND( radius ) == 0 ) if( KiROUND( radius ) == 0 )
radius = 1.0; radius = 1.0;
int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF, *v1.curve ); int segCount = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF,
EDA_ANGLE( *v1.curve, DEGREES_T ) );
double delta = angle / segCount; double delta = angle / segCount;
for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta ); a -= delta ) for( double a = end_angle + angle; fabs( a - end_angle ) > fabs( delta ); a -= delta )
@ -2584,7 +2586,7 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
pow( center.y - kicad_y( w.y1 ), 2 ) ); pow( center.y - kicad_y( w.y1 ), 2 ) );
int segs = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF, int segs = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF,
*w.curve ); EDA_ANGLE( *w.curve, DEGREES_T ) );
delta_angle = angle / segs; delta_angle = angle / segs;
} }

View File

@ -4577,7 +4577,8 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
case T_gr_arc: case T_gr_arc:
dummyShape = parsePCB_SHAPE(); dummyShape = parsePCB_SHAPE();
pad->AddPrimitiveArc( dummyShape->GetCenter(), dummyShape->GetStart(), pad->AddPrimitiveArc( dummyShape->GetCenter(), dummyShape->GetStart(),
dummyShape->GetArcAngle(), dummyShape->GetWidth() ); dummyShape->GetArcAngle().AsTenthsOfADegree(),
dummyShape->GetWidth() );
break; break;
case T_gr_line: case T_gr_line:

View File

@ -530,7 +530,7 @@ void PCB_PLUGIN::formatRenderCache( const EDA_TEXT* aText, int aNestLevel ) cons
m_out->Print( aNestLevel, "(render_cache %s %s\n", m_out->Print( aNestLevel, "(render_cache %s %s\n",
m_out->Quotew( shownText ).c_str(), m_out->Quotew( shownText ).c_str(),
FormatAngle( aText->GetDrawRotation().AsTenthsOfADegree() ).c_str() ); FormatAngle( aText->GetDrawRotation() ).c_str() );
for( const std::unique_ptr<KIFONT::GLYPH>& baseGlyph : *cache ) for( const std::unique_ptr<KIFONT::GLYPH>& baseGlyph : *cache )
{ {
@ -1140,10 +1140,7 @@ void PCB_PLUGIN::format( const FOOTPRINT* aFootprint, int aNestLevel ) const
FormatInternalUnits( aFootprint->GetPosition() ).c_str() ); FormatInternalUnits( aFootprint->GetPosition() ).c_str() );
if( !aFootprint->GetOrientation().IsZero() ) if( !aFootprint->GetOrientation().IsZero() )
{ m_out->Print( 0, " %s", FormatAngle( aFootprint->GetOrientation() ).c_str() );
m_out->Print( 0, " %s",
FormatAngle( aFootprint->GetOrientation().AsTenthsOfADegree() ).c_str() );
}
m_out->Print( 0, ")\n" ); m_out->Print( 0, ")\n" );
} }
@ -1445,7 +1442,7 @@ void PCB_PLUGIN::format( const PAD* aPad, int aNestLevel ) const
m_out->Print( 0, " (at %s", FormatInternalUnits( aPad->GetPos0() ).c_str() ); m_out->Print( 0, " (at %s", FormatInternalUnits( aPad->GetPos0() ).c_str() );
if( !aPad->GetOrientation().IsZero() ) if( !aPad->GetOrientation().IsZero() )
m_out->Print( 0, " %s", FormatAngle( aPad->GetOrientation().AsTenthsOfADegree() ).c_str() ); m_out->Print( 0, " %s", FormatAngle( aPad->GetOrientation() ).c_str() );
m_out->Print( 0, ")" ); m_out->Print( 0, ")" );
@ -1598,7 +1595,7 @@ void PCB_PLUGIN::format( const PAD* aPad, int aNestLevel ) const
|| ( aPad->GetShape() != PAD_SHAPE::CIRCLE && aPad->GetThermalSpokeAngle() != ANGLE_90 ) ) || ( aPad->GetShape() != PAD_SHAPE::CIRCLE && aPad->GetThermalSpokeAngle() != ANGLE_90 ) )
{ {
StrPrintf( &output, " (thermal_bridge_angle %s)", StrPrintf( &output, " (thermal_bridge_angle %s)",
FormatAngle( aPad->GetThermalSpokeAngle().AsTenthsOfADegree() ).c_str() ); FormatAngle( aPad->GetThermalSpokeAngle() ).c_str() );
} }
if( aPad->GetThermalGap() != 0 ) if( aPad->GetThermalGap() != 0 )
@ -1722,7 +1719,7 @@ void PCB_PLUGIN::format( const PCB_TEXT* aText, int aNestLevel ) const
FormatInternalUnits( aText->GetTextPos() ).c_str() ); FormatInternalUnits( aText->GetTextPos() ).c_str() );
if( !aText->GetTextAngle().IsZero() ) if( !aText->GetTextAngle().IsZero() )
m_out->Print( 0, " %s", FormatAngle( aText->GetTextAngle().AsTenthsOfADegree() ).c_str() ); m_out->Print( 0, " %s", FormatAngle( aText->GetTextAngle() ).c_str() );
m_out->Print( 0, ")" ); m_out->Print( 0, ")" );
@ -1814,7 +1811,7 @@ void PCB_PLUGIN::format( const FP_TEXT* aText, int aNestLevel ) const
} }
if( !orient.IsZero() ) if( !orient.IsZero() )
m_out->Print( 0, " %s", FormatAngle( orient.AsTenthsOfADegree() ).c_str() ); m_out->Print( 0, " %s", FormatAngle( orient ).c_str() );
if( !aText->IsKeepUpright() ) if( !aText->IsKeepUpright() )
m_out->Print( 0, " unlocked" ); m_out->Print( 0, " unlocked" );

View File

@ -229,7 +229,7 @@ SHAPE_LINE_CHAIN MEANDER_SHAPE::makeMiterShape( const VECTOR2D& aP, const VECTOR
{ {
VECTOR2D center = aP + dir_v * ( aSide ? -1.0 : 1.0 ); VECTOR2D center = aP + dir_v * ( aSide ? -1.0 : 1.0 );
lc.Append( SHAPE_ARC( center, aP, ( aSide ? -90 : 90 ) ) ); lc.Append( SHAPE_ARC( center, aP, ( aSide ? -ANGLE_90 : ANGLE_90 ) ) );
} }
break; break;

View File

@ -752,7 +752,7 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, FOOTPRINT* aFootprint )
VECTOR2I circle_centre = graphic->GetStart0(); VECTOR2I circle_centre = graphic->GetStart0();
SHAPE_LINE_CHAIN polyline; SHAPE_LINE_CHAIN polyline;
ConvertArcToPolyline( polyline, VECTOR2I( circle_centre ), radius, 0.0, 360.0, ConvertArcToPolyline( polyline, VECTOR2I( circle_centre ), radius, ANGLE_0, ANGLE_360,
ARC_HIGH_DEF, ERROR_INSIDE ); ARC_HIGH_DEF, ERROR_INSIDE );
for( int ii = 0; ii < polyline.PointCount(); ++ii ) for( int ii = 0; ii < polyline.PointCount(); ++ii )
@ -802,29 +802,30 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, FOOTPRINT* aFootprint )
path->SetAperture( 0 );//scale( graphic->GetWidth() ) ); path->SetAperture( 0 );//scale( graphic->GetWidth() ) );
path->SetLayerId( "signal" ); path->SetLayerId( "signal" );
VECTOR2I arc_centre = graphic->GetCenter0(); VECTOR2I arc_centre = graphic->GetCenter0();
double radius = graphic->GetRadius() + graphic->GetWidth()/2; double radius = graphic->GetRadius() + graphic->GetWidth()/2;
double arcAngleDeg = graphic->GetArcAngle() / 10.0; EDA_ANGLE arcAngle = graphic->GetArcAngle();
VECTOR2I startRadial = graphic->GetStart() - graphic->GetCenter(); VECTOR2I startRadial = graphic->GetStart() - graphic->GetCenter();
double arcStartDeg = ArcTangente( startRadial.y, startRadial.x ) / 10; EDA_ANGLE arcStart( startRadial );
NORMALIZE_ANGLE_DEGREES_POS( arcStartDeg );
arcStart.Normalize();
// For some obscure reason, FreeRouter does not show the same polygonal // For some obscure reason, FreeRouter does not show the same polygonal
// shape for polygons CW and CCW. So used only the order of corners // shape for polygons CW and CCW. So used only the order of corners
// giving the best look. // giving the best look.
if( arcAngleDeg < 0 ) if( arcAngle < ANGLE_0 )
{ {
VECTOR2I endRadial = graphic->GetEnd() - graphic->GetCenter(); VECTOR2I endRadial = graphic->GetEnd() - graphic->GetCenter();
arcStartDeg = ArcTangente( endRadial.y, endRadial.x ) / 10; arcStart = EDA_ANGLE( endRadial );
NORMALIZE_ANGLE_DEGREES_POS( arcStartDeg ); arcStart.Normalize();
arcAngleDeg = -arcAngleDeg; arcAngle = -arcAngle;
} }
SHAPE_LINE_CHAIN polyline; SHAPE_LINE_CHAIN polyline;
ConvertArcToPolyline( polyline, VECTOR2I( arc_centre ), radius, arcStartDeg, ConvertArcToPolyline( polyline, VECTOR2I( arc_centre ), radius, arcStart, arcAngle,
arcAngleDeg, ARC_HIGH_DEF, ERROR_INSIDE ); ARC_HIGH_DEF, ERROR_INSIDE );
SHAPE_POLY_SET polyBuffer; SHAPE_POLY_SET polyBuffer;
polyBuffer.AddOutline( polyline ); polyBuffer.AddOutline( polyline );
@ -834,8 +835,8 @@ IMAGE* SPECCTRA_DB::makeIMAGE( BOARD* aBoard, FOOTPRINT* aFootprint )
if( radius > 0 ) if( radius > 0 )
{ {
polyline.Clear(); polyline.Clear();
ConvertArcToPolyline( polyline, VECTOR2I( arc_centre ), radius, arcStartDeg, ConvertArcToPolyline( polyline, VECTOR2I( arc_centre ), radius, arcStart, arcAngle,
arcAngleDeg, ARC_HIGH_DEF, ERROR_INSIDE ); ARC_HIGH_DEF, ERROR_INSIDE );
// Add points in reverse order, to create a closed polygon // Add points in reverse order, to create a closed polygon
for( int ii = polyline.PointCount() - 1; ii >= 0; --ii ) for( int ii = polyline.PointCount() - 1; ii >= 0; --ii )

View File

@ -318,7 +318,7 @@ int EDIT_TOOL::DragArcTrack( const TOOL_EVENT& aEvent )
return 0; return 0;
PCB_ARC* theArc = static_cast<PCB_ARC*>( selection.Front() ); PCB_ARC* theArc = static_cast<PCB_ARC*>( selection.Front() );
double arcAngleDegrees = std::abs( theArc->GetAngle() ) / 10.0; double arcAngleDegrees = std::abs( theArc->GetAngle().AsDegrees() );
if( arcAngleDegrees + ADVANCED_CFG::GetCfg().m_MaxTangentAngleDeviation >= 180.0 ) if( arcAngleDegrees + ADVANCED_CFG::GetCfg().m_MaxTangentAngleDeviation >= 180.0 )
{ {

View File

@ -1269,7 +1269,7 @@ void ZONE::TransformSmoothedOutlineToPolygon( SHAPE_POLY_SET& aCornerBuffer, int
if( board ) if( board )
maxError = board->GetDesignSettings().m_MaxError; maxError = board->GetDesignSettings().m_MaxError;
int segCount = GetArcToSegmentCount( aClearance, maxError, 360.0 ); int segCount = GetArcToSegmentCount( aClearance, maxError, FULL_CIRCLE );
polybuffer.Inflate( aClearance, segCount ); polybuffer.Inflate( aClearance, segCount );
} }
@ -1376,7 +1376,7 @@ void ZONE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
// Rebuild filled areas only if clearance is not 0 // Rebuild filled areas only if clearance is not 0
if( aClearance ) if( aClearance )
{ {
int numSegs = GetArcToSegmentCount( aClearance, aError, 360.0 ); int numSegs = GetArcToSegmentCount( aClearance, aError, FULL_CIRCLE );
aCornerBuffer.InflateWithLinkedHoles( aClearance, numSegs, SHAPE_POLY_SET::PM_FAST ); aCornerBuffer.InflateWithLinkedHoles( aClearance, numSegs, SHAPE_POLY_SET::PM_FAST );
} }
} }
@ -1406,7 +1406,7 @@ void ZONE::TransformSolidAreasShapesToPolygon( PCB_LAYER_ID aLayer, SHAPE_POLY_S
if( board ) if( board )
maxError = board->GetDesignSettings().m_MaxError; maxError = board->GetDesignSettings().m_MaxError;
int numSegs = GetArcToSegmentCount( GetMinThickness(), maxError, 360.0 ); int numSegs = GetArcToSegmentCount( GetMinThickness(), maxError, FULL_CIRCLE );
polys.InflateWithLinkedHoles( GetMinThickness()/2, numSegs, SHAPE_POLY_SET::PM_FAST ); polys.InflateWithLinkedHoles( GetMinThickness()/2, numSegs, SHAPE_POLY_SET::PM_FAST );

View File

@ -1064,7 +1064,7 @@ bool ZONE_FILLER::computeRawFilledArea( const ZONE* aZone,
// deflating/inflating. // deflating/inflating.
int half_min_width = aZone->GetMinThickness() / 2; int half_min_width = aZone->GetMinThickness() / 2;
int epsilon = Millimeter2iu( 0.001 ); int epsilon = Millimeter2iu( 0.001 );
int numSegs = GetArcToSegmentCount( half_min_width, m_maxError, 360.0 ); int numSegs = GetArcToSegmentCount( half_min_width, m_maxError, FULL_CIRCLE );
// Solid polygons are deflated and inflated during calculations. Deflating doesn't cause // Solid polygons are deflated and inflated during calculations. Deflating doesn't cause
// issues, but inflate is tricky as it can create excessively long and narrow spikes for // issues, but inflate is tricky as it can create excessively long and narrow spikes for
@ -1265,7 +1265,7 @@ bool ZONE_FILLER::fillSingleZone( ZONE* aZone, PCB_LAYER_ID aLayer, SHAPE_POLY_S
// deflating/inflating. // deflating/inflating.
int half_min_width = aZone->GetMinThickness() / 2; int half_min_width = aZone->GetMinThickness() / 2;
int epsilon = Millimeter2iu( 0.001 ); int epsilon = Millimeter2iu( 0.001 );
int numSegs = GetArcToSegmentCount( half_min_width, m_maxError, 360.0 ); int numSegs = GetArcToSegmentCount( half_min_width, m_maxError, FULL_CIRCLE );
smoothedPoly.Deflate( half_min_width - epsilon, numSegs ); smoothedPoly.Deflate( half_min_width - epsilon, numSegs );

View File

@ -327,7 +327,8 @@ BOOST_AUTO_TEST_CASE( BasicCPAGeom )
{ {
const auto this_arc = SHAPE_ARC{ c.m_geom.m_center_point, c.m_geom.m_start_point, const auto this_arc = SHAPE_ARC{ c.m_geom.m_center_point, c.m_geom.m_start_point,
c.m_geom.m_center_angle, c.m_width }; EDA_ANGLE( c.m_geom.m_center_angle, DEGREES_T ),
c.m_width };
CheckArc( this_arc, c.m_properties ); CheckArc( this_arc, c.m_properties );
} }
@ -599,7 +600,7 @@ BOOST_AUTO_TEST_CASE( CollidePt )
BOOST_TEST_CONTEXT( c.m_ctx_name ) BOOST_TEST_CONTEXT( c.m_ctx_name )
{ {
SHAPE_ARC arc( c.m_geom.m_center_point, c.m_geom.m_start_point, SHAPE_ARC arc( c.m_geom.m_center_point, c.m_geom.m_start_point,
c.m_geom.m_center_angle ); EDA_ANGLE( c.m_geom.m_center_angle, DEGREES_T ) );
// Test a zero width arc (distance should equal the clearance) // Test a zero width arc (distance should equal the clearance)
BOOST_TEST_CONTEXT( "Test Clearance" ) BOOST_TEST_CONTEXT( "Test Clearance" )
@ -664,7 +665,7 @@ BOOST_AUTO_TEST_CASE( CollideSeg )
BOOST_TEST_CONTEXT( c.m_ctx_name ) BOOST_TEST_CONTEXT( c.m_ctx_name )
{ {
SHAPE_ARC arc( c.m_geom.m_center_point, c.m_geom.m_start_point, SHAPE_ARC arc( c.m_geom.m_center_point, c.m_geom.m_start_point,
c.m_geom.m_center_angle ); EDA_ANGLE( c.m_geom.m_center_angle, DEGREES_T ) );
// Test a zero width arc (distance should equal the clearance) // Test a zero width arc (distance should equal the clearance)
BOOST_TEST_CONTEXT( "Test Clearance" ) BOOST_TEST_CONTEXT( "Test Clearance" )
@ -707,7 +708,7 @@ struct ARC_DATA_MM
{ {
SHAPE_ARC arc( VECTOR2D( PcbMm2iu( m_center_x ), PcbMm2iu( m_center_y ) ), SHAPE_ARC arc( VECTOR2D( PcbMm2iu( m_center_x ), PcbMm2iu( m_center_y ) ),
VECTOR2D( PcbMm2iu( m_start_x ), PcbMm2iu( m_start_y ) ), VECTOR2D( PcbMm2iu( m_start_x ), PcbMm2iu( m_start_y ) ),
m_center_angle, PcbMm2iu( m_width ) ); EDA_ANGLE( m_center_angle, DEGREES_T ), PcbMm2iu( m_width ) );
return arc; return arc;
} }
@ -877,16 +878,16 @@ BOOST_AUTO_TEST_CASE( CollideArcToShapeLineChain )
BOOST_AUTO_TEST_CASE( CollideArcToPolygonApproximation ) BOOST_AUTO_TEST_CASE( CollideArcToPolygonApproximation )
{ {
SHAPE_ARC arc( VECTOR2I( 73843527, 74355869 ), VECTOR2I( 71713528, 72965869 ), -76.36664803, SHAPE_ARC arc( VECTOR2I( 73843527, 74355869 ), VECTOR2I( 71713528, 72965869 ),
2000000 ); EDA_ANGLE( -76.36664803, DEGREES_T ), 2000000 );
// Create a polyset approximation from the arc - error outside (simulating the zone filler) // Create a polyset approximation from the arc - error outside (simulating the zone filler)
SHAPE_POLY_SET arcBuffer; SHAPE_POLY_SET arcBuffer;
int clearance = ( arc.GetWidth() * 3 ) / 2; int clearance = ( arc.GetWidth() * 3 ) / 2;
int polygonApproximationError = SHAPE_ARC::DefaultAccuracyForPCB(); int polygonApproximationError = SHAPE_ARC::DefaultAccuracyForPCB();
TransformArcToPolygon( arcBuffer, wxPoint( arc.GetP0() ), wxPoint( arc.GetArcMid() ), TransformArcToPolygon( arcBuffer, arc.GetP0(), arc.GetArcMid(), arc.GetP1(),
wxPoint( arc.GetP1() ), arc.GetWidth() + 2 * clearance, arc.GetWidth() + 2 * clearance,
polygonApproximationError, ERROR_OUTSIDE ); polygonApproximationError, ERROR_OUTSIDE );
BOOST_REQUIRE_EQUAL( arcBuffer.OutlineCount(), 1 ); BOOST_REQUIRE_EQUAL( arcBuffer.OutlineCount(), 1 );
@ -1027,7 +1028,7 @@ BOOST_AUTO_TEST_CASE( ArcToPolyline )
BOOST_TEST_CONTEXT( c.m_ctx_name ) BOOST_TEST_CONTEXT( c.m_ctx_name )
{ {
const SHAPE_ARC this_arc{ c.m_geom.m_center_point, c.m_geom.m_start_point, const SHAPE_ARC this_arc{ c.m_geom.m_center_point, c.m_geom.m_start_point,
c.m_geom.m_center_angle, width }; EDA_ANGLE( c.m_geom.m_center_angle, DEGREES_T ), width };
const SHAPE_LINE_CHAIN chain = this_arc.ConvertToPolyline( accuracy ); const SHAPE_LINE_CHAIN chain = this_arc.ConvertToPolyline( accuracy );

View File

@ -47,9 +47,9 @@ BOOST_AUTO_TEST_CASE( ArcToPolyline )
VECTOR2I( 1500, 0 ), VECTOR2I( 1500, 0 ),
} ); } );
SHAPE_LINE_CHAIN arc_insert1( SHAPE_ARC( VECTOR2I( 0, -100 ), VECTOR2I( 0, -200 ), 180.0 ) ); SHAPE_LINE_CHAIN arc_insert1( SHAPE_ARC( VECTOR2I( 0, -100 ), VECTOR2I( 0, -200 ), ANGLE_180 ) );
SHAPE_LINE_CHAIN arc_insert2( SHAPE_ARC( VECTOR2I( 0, 500 ), VECTOR2I( 0, 400 ), 180.0 ) ); SHAPE_LINE_CHAIN arc_insert2( SHAPE_ARC( VECTOR2I( 0, 500 ), VECTOR2I( 0, 400 ), ANGLE_180 ) );
BOOST_CHECK_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() ); BOOST_CHECK_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() );
BOOST_CHECK_EQUAL( arc_insert1.CShapes().size(), arc_insert1.CPoints().size() ); BOOST_CHECK_EQUAL( arc_insert1.CShapes().size(), arc_insert1.CPoints().size() );
@ -59,7 +59,7 @@ BOOST_AUTO_TEST_CASE( ArcToPolyline )
BOOST_CHECK( GEOM_TEST::IsOutlineValid( arc_insert1 ) ); BOOST_CHECK( GEOM_TEST::IsOutlineValid( arc_insert1 ) );
BOOST_CHECK( GEOM_TEST::IsOutlineValid( arc_insert2 ) ); BOOST_CHECK( GEOM_TEST::IsOutlineValid( arc_insert2 ) );
base_chain.Insert( 0, SHAPE_ARC( VECTOR2I( 0, -100 ), VECTOR2I( 0, -200 ), 1800 ) ); base_chain.Insert( 0, SHAPE_ARC( VECTOR2I( 0, -100 ), VECTOR2I( 0, -200 ), ANGLE_180 ) );
BOOST_CHECK( GEOM_TEST::IsOutlineValid( base_chain ) ); BOOST_CHECK( GEOM_TEST::IsOutlineValid( base_chain ) );
BOOST_CHECK_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() ); BOOST_CHECK_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() );
@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE( ArcToPolylineLargeCoords )
VECTOR2I( 1500000, 0 ), VECTOR2I( 1500000, 0 ),
} ); } );
base_chain.Append( SHAPE_ARC( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 100000 ), 180.0 ) ); base_chain.Append( SHAPE_ARC( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 100000 ), ANGLE_180 ) );
BOOST_CHECK( GEOM_TEST::IsOutlineValid( base_chain ) ); BOOST_CHECK( GEOM_TEST::IsOutlineValid( base_chain ) );
BOOST_CHECK_EQUAL( base_chain.PointCount(), 11 ); BOOST_CHECK_EQUAL( base_chain.PointCount(), 11 );
@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE( Split )
{ {
SEG seg1( VECTOR2I( 0, 100000 ), VECTOR2I( 50000, 0 ) ); SEG seg1( VECTOR2I( 0, 100000 ), VECTOR2I( 50000, 0 ) );
SEG seg2( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ) ); SEG seg2( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ) );
SHAPE_ARC arc( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ), 180.0 ); SHAPE_ARC arc( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ), ANGLE_180 );
// Start a chain with 2 points (seg1) // Start a chain with 2 points (seg1)
SHAPE_LINE_CHAIN chain( { seg1.A, seg1.B } ); SHAPE_LINE_CHAIN chain( { seg1.A, seg1.B } );
@ -271,8 +271,8 @@ BOOST_AUTO_TEST_CASE( Split )
BOOST_AUTO_TEST_CASE( Slice ) BOOST_AUTO_TEST_CASE( Slice )
{ {
SEG targetSegment( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ) ); SEG targetSegment( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ) );
SHAPE_ARC firstArc( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ), 180.0 ); SHAPE_ARC firstArc( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ), ANGLE_180 );
SHAPE_ARC secondArc( VECTOR2I( -200000, -200000 ), VECTOR2I( -300000, -100000 ), -180.0 ); SHAPE_ARC secondArc( VECTOR2I( -200000, -200000 ), VECTOR2I( -300000, -100000 ), -ANGLE_180 );
int tol = SHAPE_ARC::DefaultAccuracyForPCB(); // Tolerance for arc collisions int tol = SHAPE_ARC::DefaultAccuracyForPCB(); // Tolerance for arc collisions
// Start a chain with 3 points // Start a chain with 3 points
@ -433,7 +433,7 @@ BOOST_AUTO_TEST_CASE( NearestPointPt )
{ {
SEG seg1( VECTOR2I( 0, 100000 ), VECTOR2I( 50000, 0 ) ); SEG seg1( VECTOR2I( 0, 100000 ), VECTOR2I( 50000, 0 ) );
SEG seg2( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ) ); SEG seg2( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ) );
SHAPE_ARC arc( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ), 180.0 ); SHAPE_ARC arc( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ), ANGLE_180 );
// Start a chain with 2 points (seg1) // Start a chain with 2 points (seg1)
SHAPE_LINE_CHAIN chain( { seg1.A, seg1.B } ); SHAPE_LINE_CHAIN chain( { seg1.A, seg1.B } );