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 );
return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, 360.0 );
return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, FULL_CIRCLE );
}

View File

@ -243,9 +243,9 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack );
VECTOR2D center( arc->GetCenter() );
double arc_angle = arc->GetAngle();
EDA_ANGLE arc_angle = arc->GetAngle();
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;
// We need a circle to segment count. However, the arc angle can be small, and the
@ -256,12 +256,13 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
}
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 ) );
}
transformArcToSegments( VECTOR2I( center.x, center.y ), arc->GetStart(), arc_angle,
circlesegcount, arc->GetWidth(), aDstContainer, *arc );
transformArcToSegments( VECTOR2I( center.x, center.y ), arc->GetStart(),
arc_angle.AsTenthsOfADegree(), circlesegcount, arc->GetWidth(),
aDstContainer, *arc );
break;
}
@ -658,8 +659,9 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aDstCo
{
unsigned int segCount = GetCircleSegmentCount( aShape->GetBoundingBox().GetSizeMax() );
transformArcToSegments( aShape->GetCenter(), aShape->GetStart(), aShape->GetArcAngle(),
segCount, linewidth, aDstContainer, *aShape );
transformArcToSegments( aShape->GetCenter(), aShape->GetStart(),
aShape->GetArcAngle().AsTenthsOfADegree(), segCount, linewidth,
aDstContainer, *aShape );
}
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];
int len;
len = snprintf( temp, sizeof(temp), "%.10g", aAngle / 10.0 );
len = snprintf( temp, sizeof(temp), "%.10g", aAngle.AsDegrees() );
return std::string( temp, len );
}

View File

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

View File

@ -126,7 +126,7 @@ double EDA_SHAPE::GetLength() const
return length;
case SHAPE_T::ARC:
return 2 * M_PI * GetRadius() * ( GetArcAngle() / 3600.0 );
return GetRadius() * GetArcAngle().AsRadians();
default:
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 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:
aList.emplace_back( shape, _( "Arc" ) );
msg.Printf( wxT( "%.1f" ), GetArcAngle() / 10.0 );
msg.Printf( wxT( "%.1f" ), GetArcAngle().AsDegrees() );
aList.emplace_back( _( "Angle" ), msg );
msg = MessageTextFromValue( units, GetRadius() );
@ -1078,7 +1078,7 @@ std::vector<SHAPE*> EDA_SHAPE::MakeEffectiveShapes( bool aEdgeOnly ) const
switch( m_shape )
{
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() ) );
break;
@ -1109,7 +1109,7 @@ std::vector<SHAPE*> EDA_SHAPE::MakeEffectiveShapes( bool aEdgeOnly ) const
effectiveShapes.emplace_back( new SHAPE_CIRCLE( getCenter(), GetRadius() ) );
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;
}
@ -1345,11 +1345,10 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
{
// Keep center clockwise from chord while drawing
VECTOR2I chordVector = m_end - m_start;
double chordAngle = ArcTangente( chordVector.y, chordVector.x );
NORMALIZE_ANGLE_POS( chordAngle );
EDA_ANGLE chordAngle( chordVector );
VECTOR2I c1Test = c1;
RotatePoint( c1Test, m_start, -chordAngle );
RotatePoint( c1Test, m_start, -chordAngle.Normalize() );
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
m_arcCenter = GetLineLength( c1, aPosition ) < GetLineLength( c2, aPosition ) ? c1 : c2;
if( GetArcAngle() > 1800 )
if( GetArcAngle() > ANGLE_180 )
std::swap( m_start, m_end );
break;

View File

@ -889,7 +889,7 @@ void OPENGL_GAL::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadius,
SWAP( aStartAngle, >, aEndAngle );
// 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 );
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 dx = x2 - x1;
int dy = y2 - y1;
double angle = -ArcTangente( dy, dx );
EDA_ANGLE angle( VECTOR2I( dx, dy ) );
angle = -angle;
VECTOR2I start;
VECTOR2I end;
VECTOR2I org( x1, y1 );

View File

@ -464,19 +464,12 @@ void PLOTTER::segmentAsOval( const VECTOR2I& start, const VECTOR2I& end, int wid
{
VECTOR2I center( ( start.x + end.x ) / 2, ( start.y + end.y ) / 2 );
VECTOR2I size( end.x - start.x, end.y - start.y );
double orient;
if( size.y == 0 )
orient = 0;
else if( size.x == 0 )
orient = 900;
else
orient = -ArcTangente( size.y, size.x );
EDA_ANGLE orient( size );
size.x = KiROUND( EuclideanNorm( size ) ) + 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;
VECTOR2I kiLast = last;
VECTOR2I kiCurrent = pt;
double wireangleDeciDeg = getPolarAngle( kiLast - kiCurrent );
fixNetLabelsAndSheetPins( wireangleDeciDeg, conn.StartNode );
EDA_ANGLE wireAngle( last - pt );
fixNetLabelsAndSheetPins( wireAngle.AsTenthsOfADegree(), conn.StartNode );
}
wire = new SCH_LINE();
@ -1116,10 +1113,8 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadNets()
//Fix labels on the end wire
if( wire )
{
VECTOR2I kiLast = wire->GetEndPoint();
VECTOR2I kiCurrent = wire->GetStartPoint();
double wireangleDeciDeg = getPolarAngle( kiLast - kiCurrent );
fixNetLabelsAndSheetPins( wireangleDeciDeg, conn.EndNode );
EDA_ANGLE wireAngle( wire->GetEndPoint() - wire->GetStartPoint() );
fixNetLabelsAndSheetPins( wireAngle.AsTenthsOfADegree(), conn.EndNode );
}
}
@ -2059,18 +2054,18 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadShapeVertices(
case VERTEX_TYPE::ANTICLOCKWISE_SEMICIRCLE:
case VERTEX_TYPE::ANTICLOCKWISE_ARC:
{
double arcStartAngle = getPolarAngle( startPoint - centerPoint );
double arcEndAngle = getPolarAngle( endPoint - centerPoint );
double arcAngleDeciDeg = arcEndAngle - arcStartAngle;
EDA_ANGLE arcStartAngle( startPoint - centerPoint );
EDA_ANGLE arcEndAngle( endPoint - centerPoint );
EDA_ANGLE arcAngle = arcEndAngle - arcStartAngle;
if( cw )
arcAngleDeciDeg = NormalizeAnglePos( arcAngleDeciDeg );
arcAngle = arcAngle.Normalize();
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 ) );
// 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 )
{
return sqrt( ( (double) aPoint.x * (double) aPoint.x )

View File

@ -289,13 +289,6 @@ private:
* aAngleTenthDegree );
}
/**
* @brief
* @param aPoint
* @return Angle in decidegrees of the polar representation of the point, scaled 0..360
*/
double getPolarAngle( const VECTOR2I& aPoint );
/**
* @brief
* @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 )
{
case PIN_RIGHT: return 0.0;
case PIN_LEFT: return 180.0;
case PIN_UP: return 90.0;
case PIN_DOWN: return 270.0;
default: wxFAIL_MSG( "Missing symbol library pin orientation type" ); return 0.0;
case PIN_RIGHT: return ANGLE_0;
case PIN_LEFT: return ANGLE_180;
case PIN_UP: return ANGLE_90;
case PIN_DOWN: return ANGLE_270;
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 )
{
case SHEET_SIDE::UNDEFINED:
case SHEET_SIDE::LEFT: retv = 180.0; break;
case SHEET_SIDE::RIGHT: retv = 0.0; break;
case SHEET_SIDE::TOP: retv = 90.0; break;
case SHEET_SIDE::BOTTOM: retv = 270.0; break;
default: wxFAIL; retv = 0.0; break;
case SHEET_SIDE::LEFT: return ANGLE_180;
case SHEET_SIDE::RIGHT: return ANGLE_0;
case SHEET_SIDE::TOP: return ANGLE_90;
case SHEET_SIDE::BOTTOM: return ANGLE_270;
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_";
}
double angle;
EDA_ANGLE angle;
int orientation = aSymbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y );
if( orientation == SYM_ORIENT_90 )
angle = 90.0;
angle = ANGLE_90;
else if( orientation == SYM_ORIENT_180 )
angle = 180.0;
angle = ANGLE_180;
else if( orientation == SYM_ORIENT_270 )
angle = 270.0;
angle = ANGLE_270;
else
angle = 0.0;
angle = ANGLE_0;
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(),
FormatInternalUnits( aSymbol->GetPosition().x ).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 mirrorY = aSymbol->GetOrientation() & SYM_MIRROR_Y;
@ -1157,7 +1153,7 @@ void SCH_SEXPR_PLUGIN::saveField( SCH_FIELD* aField, int aNestLevel )
aField->GetId(),
FormatInternalUnits( aField->GetPosition().x ).c_str(),
FormatInternalUnits( aField->GetPosition().y ).c_str(),
FormatAngle( aField->GetTextAngle().AsTenthsOfADegree() ).c_str() );
FormatAngle( aField->GetTextAngle() ).c_str() );
if( !aField->IsDefaultFormatting()
|| ( aField->GetTextHeight() != Mils2iu( DEFAULT_SIZE_TEXT ) ) )
@ -1266,7 +1262,7 @@ void SCH_SEXPR_PLUGIN::saveSheet( SCH_SHEET* aSheet, int aNestLevel )
getSheetPinShapeToken( pin->GetShape() ),
FormatInternalUnits( pin->GetPosition().x ).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 );
@ -1445,7 +1441,7 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel )
m_out->Print( 0, " (at %s %s %s)",
FormatInternalUnits( aText->GetPosition().x ).c_str(),
FormatInternalUnits( aText->GetPosition().y ).c_str(),
FormatAngle( aText->GetTextAngle().AsTenthsOfADegree() ).c_str() );
FormatAngle( aText->GetTextAngle() ).c_str() );
}
else
{
@ -1453,7 +1449,7 @@ void SCH_SEXPR_PLUGIN::saveText( SCH_TEXT* aText, int aNestLevel )
m_out->Print( aNestLevel + 1, "(at %s %s %s)",
FormatInternalUnits( aText->GetPosition().x ).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 )
@ -2058,7 +2054,7 @@ void SCH_SEXPR_PLUGIN_CACHE::savePin( LIB_PIN* aPin, OUTPUTFORMATTER& aFormatter
getPinShapeToken( aPin->GetShape() ),
FormatInternalUnits( aPin->GetPosition().x ).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() );
if( !aPin->IsVisible() )

View File

@ -275,19 +275,18 @@ const EDA_RECT GERBER_DRAW_ITEM::GetBoundingBox() const
case GBR_ARC:
{
double arc_angle =
atan2( double( m_End.y - m_ArcCentre.y ), double( m_End.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;
if( arc_angle < 0.0 )
arc_angle += 360.0;
EDA_ANGLE angle( atan2( double( m_End.y - m_ArcCentre.y ),
double( m_End.x - m_ArcCentre.x ) )
- atan2( double( m_Start.y - m_ArcCentre.y ),
double( m_Start.x - m_ArcCentre.x ) ),
RADIANS_T );
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
bbox.SetOrigin( arc_bbox.GetX(), arc_bbox.GetY() );
bbox.SetWidth( arc_bbox.GetWidth() );

View File

@ -35,6 +35,7 @@
#include <string>
#include <eda_units.h>
#include <eda_angle.h>
#include <convert_to_biu.h>
#include <math/vector2d.h>
@ -194,7 +195,7 @@ std::string FormatInternalUnits( int aValue );
* @param aAngle A angle value to convert.
* @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 );

View File

@ -23,6 +23,7 @@
#include <cassert>
#include <cmath>
#include <math/vector2d.h> // for VECTOR2I
enum EDA_ANGLE_T
@ -36,11 +37,13 @@ enum EDA_ANGLE_T
class EDA_ANGLE
{
public:
// Angles can be created in degrees, 1/10ths of a degree, and 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
/**
* 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.
*/
EDA_ANGLE( int aValue, EDA_ANGLE_T aAngleType ) :
m_value( 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() :
m_value( 0 ),
m_radians( 0.0 ),
@ -149,11 +198,8 @@ public:
return EDA_ANGLE( newAngle, RADIANS_T );
}
// if both were not given in radians, addition is done using
// 1/10ths of a degree, then converted to original angle type
// of this angle
//int newAngle = normalize( AsTenthsOfADegree() + aAngle.AsTenthsOfADegree(),
//TENTHS_OF_A_DEGREE_T );
// if both were not given in radians, addition is done using 1/10ths of a degree, then
// converted to original angle type
int newAngle = AsTenthsOfADegree() + aAngle.AsTenthsOfADegree();
switch( initialType )
@ -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 )
{
return aAngleA.AsTenthsOfADegree() == aAngleB.AsTenthsOfADegree();

View File

@ -165,7 +165,7 @@ public:
*/
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?

View File

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

View File

@ -32,7 +32,7 @@
#include <math.h> // for copysign
#include <stdlib.h> // for abs
#include <eda_angle.h>
#include <math/vector2d.h>
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 aErrorMax is the max error
* 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

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2018 CERN
* Copyright (C) 2019-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>
*
* This program is free software; you can redistribute it and/or
@ -28,6 +28,7 @@
#include <geometry/shape.h>
#include <convert_to_biu.h>
#include <eda_angle.h>
#include <math/vector2d.h> // for VECTOR2I
class SHAPE_LINE_CHAIN;
@ -49,11 +50,11 @@ public:
*
* @param aArcCenter is the arc center.
* @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.
*/
SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint, double aCenterAngle,
int aWidth = 0 );
SHAPE_ARC( const VECTOR2I& aArcCenter, const VECTOR2I& aArcStartPoint,
const EDA_ANGLE& aCenterAngle, int aWidth = 0 );
/**
* @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 )
{
VECTOR2I corner_position;
int numSegs = GetArcToSegmentCount( aRadius, aError, 360.0 );
int numSegs = GetArcToSegmentCount( aRadius, aError, FULL_CIRCLE );
numSegs = std::max( aMinSegCount, numSegs );
// 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 )
{
VECTOR2I corner_position;
int numSegs = GetArcToSegmentCount( aRadius, aError, 360.0 );
int numSegs = GetArcToSegmentCount( aRadius, aError, FULL_CIRCLE );
numSegs = std::max( aMinSegCount, numSegs );
// 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
// of the segment.
int radius = aWidth / 2;
int numSegs = GetArcToSegmentCount( radius, aError, 360.0 );
int numSegs = GetArcToSegmentCount( radius, aError, FULL_CIRCLE );
numSegs = std::max( aMinSegCount, numSegs );
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
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 lastSegLen = endAngle % angDelta; // or 0 if last seg length is 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,
double aStartAngleDeg, double aArcAngleDeg, double aAccuracy,
ERROR_LOC aErrorLoc )
const EDA_ANGLE& aStartAngle, const EDA_ANGLE& aArcAngle,
double aAccuracy, ERROR_LOC aErrorLoc )
{
double endAngle = aStartAngleDeg + aArcAngleDeg;
int n = 2;
if( aRadius >= aAccuracy )
n = GetArcToSegmentCount( aRadius, aAccuracy, aArcAngleDeg )+1; // n >= 3
n = GetArcToSegmentCount( aRadius, aAccuracy, aArcAngle ) + 1;
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 );
aRadius += actual_delta_radius;
}
for( int i = 0; i <= n ; i++ )
{
double rot = aStartAngleDeg;
rot += ( aArcAngleDeg * i ) / n;
EDA_ANGLE rot = aStartAngle;
rot += ( aArcAngle * i ) / n;
double x = aCenter.x + aRadius * cos( rot * M_PI / 180.0 );
double y = aCenter.y + aRadius * sin( rot * M_PI / 180.0 );
double x = aCenter.x + aRadius * cos( rot.AsRadians() );
double y = aCenter.y + aRadius * sin( rot.AsRadians() );
aPolyline.Append( KiROUND( x ), KiROUND( y ) );
}
@ -589,11 +588,13 @@ void TransformArcToPolygon( SHAPE_POLY_SET& aCornerBuffer, const VECTOR2I& aStar
polyshape.NewOutline();
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 )
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
polyshape.Append( center );
#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
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
// tangency of the endpoint.

View File

@ -40,7 +40,7 @@
// with a 0.01mm maximum deviation yields 11 segments.)
#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
// 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.
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
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,
double aCenterAngle, int aWidth ) :
SHAPE( SH_ARC ), m_width( aWidth )
const EDA_ANGLE& aCenterAngle, int aWidth ) :
SHAPE( SH_ARC ),
m_width( aWidth )
{
m_start = aArcStartPoint;
m_mid = aArcStartPoint;
m_end = aArcStartPoint;
RotatePoint( m_mid, aArcCenter, -aCenterAngle * 10.0 / 2.0 );
RotatePoint( m_end, aArcCenter, -aCenterAngle * 10.0 );
RotatePoint( m_mid, aArcCenter, -EDA_ANGLE( aCenterAngle.AsDegrees() / 2.0, DEGREES_T ) );
RotatePoint( m_end, aArcCenter, -aCenterAngle );
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,
const VECTOR2I& aArcEnd, int aWidth ) :
SHAPE( SH_ARC ), m_start( aArcStart ), m_mid( aArcMid ), m_end( aArcEnd ),
SHAPE( SH_ARC ),
m_start( aArcStart ),
m_mid( aArcMid ),
m_end( aArcEnd ),
m_width( aWidth )
{
update_bbox();
}
SHAPE_ARC::SHAPE_ARC( const SEG& aSegmentA, const SEG& aSegmentB, int aRadius, int aWidth )
: SHAPE( SH_ARC )
SHAPE_ARC::SHAPE_ARC( const SEG& aSegmentA, const SEG& aSegmentB, int aRadius, int aWidth ) :
SHAPE( SH_ARC )
{
m_width = aWidth;
@ -135,18 +139,17 @@ SHAPE_ARC::SHAPE_ARC( const SEG& aSegmentA, const SEG& aSegmentB, int aRadius, i
if( pToB.EuclideanNorm() == 0 )
pToB = aSegmentB.A - p.get();
double pToAangle = ArcTangente( pToA.y, pToA.x );
double pToBangle = ArcTangente( pToB.y, pToB.x );
EDA_ANGLE pToAangle( pToA );
EDA_ANGLE pToBangle( pToB );
double alpha = NormalizeAngle180( pToAangle - pToBangle );
double distPC = (double) aRadius / abs( sin( DECIDEG2RAD( alpha / 2 ) ) );
double angPC = pToAangle - alpha / 2;
EDA_ANGLE alpha = ( pToAangle - pToBangle ).Normalize180();
double distPC = (double) aRadius / abs( sin( alpha.AsRadians() / 2 ) );
EDA_ANGLE angPC = pToAangle - alpha / 2;
VECTOR2I arcCenter;
arcCenter.x = p.get().x + KiROUND( distPC * cos( DECIDEG2RAD( angPC ) ) );
arcCenter.y = p.get().y + KiROUND( distPC * sin( DECIDEG2RAD( angPC ) ) );
arcCenter.x = p.get().x + KiROUND( distPC * cos( angPC.AsRadians() ) );
arcCenter.y = p.get().y + KiROUND( distPC * sin( angPC.AsRadians() ) );
// The end points of the arc are the orthogonal projected lines from the line segments
// 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 endVector = m_end - arcCenter;
double startAngle = ArcTangente( startVector.y, startVector.x );
double endAngle = ArcTangente( endVector.y, endVector.x );
EDA_ANGLE startAngle( startVector );
EDA_ANGLE endAngle( endVector );
EDA_ANGLE midPointRotAngle = ( startAngle - endAngle ).Normalize180() / 2;
double midPointRotAngle = NormalizeAngle180( startAngle - endAngle ) / 2;
m_mid = m_start;
RotatePoint( m_mid, arcCenter, midPointRotAngle );
}
@ -439,13 +442,10 @@ double SHAPE_ARC::GetLength() const
double SHAPE_ARC::GetCentralAngle() const
{
VECTOR2I center = GetCenter();
VECTOR2I p0 = m_start - center;
VECTOR2I p1 = 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 );
EDA_ANGLE angle1 = EDA_ANGLE( m_mid - center ) - EDA_ANGLE( m_start - center );
EDA_ANGLE angle2 = EDA_ANGLE( m_end - center ) - EDA_ANGLE( m_mid - center );
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
{
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
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++ )
ss << m_arcs[i].GetCenter().x << " " << m_arcs[i].GetCenter().y << " "
<< m_arcs[i].GetP0().x << " " << m_arcs[i].GetP0().y << " "
<< m_arcs[i].GetCentralAngle();
<< m_arcs[i].GetCentralAngle().AsDegrees();
return ss.str();*/
}
@ -1986,7 +1986,7 @@ bool SHAPE_LINE_CHAIN::Parse( std::stringstream& aStream )
aStream >> p0.y;
aStream >> angle;
m_arcs.emplace_back( pc, p0, angle );
m_arcs.emplace_back( pc, p0, EDA_ANGLE( angle, DEGREES_T ) );
}
return true;

View File

@ -2155,8 +2155,8 @@ SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::chamferFilletPolygon( CORNER_MODE aMode,
argument = 1;
double arcAngle = acos( argument );
double arcAngleDegrees = arcAngle * 180.0 / M_PI;
int segments = GetArcToSegmentCount( radius, aErrorMax, arcAngleDegrees );
int segments = GetArcToSegmentCount( radius, aErrorMax,
EDA_ANGLE( arcAngle, RADIANS_T ) );
double deltaAngle = arcAngle / segments;
double startAngle = atan2( -ys, xs );

View File

@ -345,18 +345,7 @@ void AR_MATRIX::drawSegmentQcq( int ux0, int uy0, int ux1, int uy1, int lg, int
dx = ux1 - ux0;
dy = uy1 - uy0;
double angle;
if( dx )
{
angle = ArcTangente( dy, dx );
}
else
{
angle = 900;
if( dy < 0 )
angle = -900;
}
EDA_ANGLE angle( VECTOR2I( dx, dy ) );
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 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

@ -191,16 +191,14 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
{
VECTOR2I pstart = graphic->GetStart();
VECTOR2I center = graphic->GetCenter();
double angle = -graphic->GetArcAngle();
EDA_ANGLE angle = -graphic->GetArcAngle();
double radius = graphic->GetRadius();
int steps = GetArcToSegmentCount( radius, aErrorMax, angle / 10.0 );
VECTOR2I pt;
int steps = GetArcToSegmentCount( radius, aErrorMax, angle );
for( int step = 1; step<=steps; ++step )
{
double rotation = ( angle * step ) / steps;
pt = pstart;
EDA_ANGLE rotation = ( angle * step ) / steps;
VECTOR2I pt = pstart;
RotatePoint( pt, center, rotation );
@ -413,9 +411,9 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
VECTOR2I pstart = graphic->GetStart();
VECTOR2I pend = graphic->GetEnd();
VECTOR2I pcenter = graphic->GetCenter();
double angle = -graphic->GetArcAngle();
EDA_ANGLE angle = -graphic->GetArcAngle();
double radius = graphic->GetRadius();
int steps = GetArcToSegmentCount( radius, aErrorMax, angle / 10.0 );
int steps = GetArcToSegmentCount( radius, aErrorMax, angle );
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:
for( int step = 1; step < steps; ++step )
{
double rotation = ( angle * step ) / steps;
EDA_ANGLE rotation = ( angle * step ) / steps;
VECTOR2I pt = pstart;
RotatePoint( pt, pcenter, rotation );
aPolygons.Append( pt );
@ -593,7 +592,7 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
double angle = 3600.0;
VECTOR2I start = center;
int radius = graphic->GetRadius();
int steps = GetArcToSegmentCount( radius, aErrorMax, 360.0 );
int steps = GetArcToSegmentCount( radius, aErrorMax, FULL_CIRCLE );
VECTOR2I nextPt;
start.x += radius;
@ -668,9 +667,9 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
VECTOR2I pstart = graphic->GetStart();
VECTOR2I pend = graphic->GetEnd();
VECTOR2I pcenter = graphic->GetCenter();
double angle = -graphic->GetArcAngle();
EDA_ANGLE angle = -graphic->GetArcAngle();
int radius = graphic->GetRadius();
int steps = GetArcToSegmentCount( radius, aErrorMax, angle / 10.0 );
int steps = GetArcToSegmentCount( radius, aErrorMax, angle );
if( !close_enough( prevPt, pstart, aChainingEpsilon ) )
{
@ -683,7 +682,7 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aSegList, SHAPE_POLY_SET&
// Create intermediate points between start and end:
for( int step = 1; step < steps; ++step )
{
double rotation = ( angle * step ) / steps;
EDA_ANGLE rotation = ( angle * step ) / steps;
VECTOR2I pt = pstart;
RotatePoint( pt, pcenter, rotation );

View File

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

View File

@ -119,7 +119,7 @@ bool DIALOG_PAD_PRIMITIVES_PROPERTIES::TransferDataToWindow()
m_endY.SetValue( m_shape->GetCenter().y );
m_radiusLabel->SetLabel( _( "Angle:" ) );
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_ctrl1Y.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->GetEnd(), b->GetEnd() );
TEST( a->GetCenter(), b->GetCenter() );
TEST( a->GetArcAngle(), b->GetArcAngle() );
TEST( a->GetArcAngle().AsTenthsOfADegree(), b->GetArcAngle().AsTenthsOfADegree() );
break;
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->GetEnd0(), b->GetEnd0() );
TEST( a->GetCenter0(), b->GetCenter0() );
TEST( a->GetArcAngle(), b->GetArcAngle() );
TEST( a->GetArcAngle().AsTenthsOfADegree(), b->GetArcAngle().AsTenthsOfADegree() );
break;
case SHAPE_T::BEZIER:

View File

@ -318,17 +318,17 @@ bool DRC_TEST_PROVIDER_MECHANICAL_CLEARANCE::Run()
SHAPE_LINE_CHAIN asPoly;
VECTOR2I center = shape->GetCenter();
double angle = -shape->GetArcAngle();
EDA_ANGLE angle = -shape->GetArcAngle();
double r = shape->GetRadius();
int steps = GetArcToSegmentCount( r, errorMax, angle / 10.0 );
int steps = GetArcToSegmentCount( r, errorMax, angle );
asPoly.Append( shape->GetStart() );
for( int step = 1; step <= steps; ++step )
{
double rotation = ( angle * step ) / steps;
EDA_ANGLE rotation = ( angle * step ) / steps;
VECTOR2I pt = shape->GetStart();
RotatePoint( pt, center, rotation );
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( 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( 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 end = shape->GetEnd0();
if( shape->GetArcAngle() > 0 )
if( shape->GetArcAngle() > ANGLE_0 )
std::swap( start, end );
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;
ep.x = graphic->GetStart().x * scale + offX;
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 )
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.
// SetArcParams needs a count max, and the minimal and maximal length
// of segments
int nsides = GetArcToSegmentCount( via->GetDrillValue(),
Millimeter2iu( err_approx_max ), 360.0 );
int nsides = GetArcToSegmentCount( via->GetDrillValue(), Millimeter2iu( err_approx_max ),
FULL_CIRCLE );
double minSegLength = M_PI * 2.0 * hole_radius / nsides;
double maxSegLength = minSegLength*2.0;
@ -679,8 +679,8 @@ void EXPORTER_PCB_VRML::ExportVrmlPadHole( PAD* aPad )
// Export the hole on the edge layer
if( hole_drill > 0 )
{
int nsides = GetArcToSegmentCount( hole_drill,
Millimeter2iu( err_approx_max ), 360.0 );
int nsides = GetArcToSegmentCount( hole_drill, Millimeter2iu( err_approx_max ),
FULL_CIRCLE );
double minSegLength = M_PI * hole_drill / nsides;
double maxSegLength = minSegLength*2.0;

View File

@ -48,13 +48,13 @@
* @param a_ArcAngle = arc length in 0.1 degrees.
*/
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 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:
for( int ii = 1; ii <= seg_count; ii++ )
@ -139,11 +139,12 @@ static INDUCTOR_S_SHAPE_RESULT BuildCornersList_S_Shape( std::vector<VECTOR2I>&
#define ADJUST_SIZE 0.988
auto pt = aEndPoint - aStartPoint;
double angle = -ArcTangente( pt.y, pt.x );
EDA_ANGLE angle( pt );
int min_len = KiROUND( EuclideanNorm( pt ) );
int segm_len = 0; // length of segments
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)
* 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;
centre.x -= radius;
gen_arc( aBuffer, pt, centre, -900 );
gen_arc( aBuffer, pt, centre, -ANGLE_90 );
pt = aBuffer.back();
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++ )
{
int arc_angle;
if( ii & 1 ) // odd order arcs are greater than 0
sign = -1;
else
sign = 1;
arc_angle = 1800 * sign;
centre = pt;
centre.y += radius;
gen_arc( aBuffer, pt, centre, arc_angle );
gen_arc( aBuffer, pt, centre, ANGLE_180 * sign );
pt = aBuffer.back();
pt.x += segm_len * sign;
aBuffer.push_back( pt );
@ -272,15 +270,13 @@ static INDUCTOR_S_SHAPE_RESULT BuildCornersList_S_Shape( std::vector<VECTOR2I>&
pt = aBuffer.back();
centre = pt;
centre.y += radius;
gen_arc( aBuffer, pt, centre, 900 * sign );
gen_arc( aBuffer, pt, centre, ANGLE_90 * sign );
// Rotate point
angle += 900;
angle += ANGLE_90;
for( unsigned jj = 0; jj < aBuffer.size(); jj++ )
{
RotatePoint( aBuffer[jj], aStartPoint, angle );
}
// push last point (end point)
aBuffer.push_back( aEndPoint );

View File

@ -1570,7 +1570,7 @@ void PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
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 );
int clearance = aClearanceValue;

View File

@ -652,8 +652,8 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
int width = aArc->GetWidth();
COLOR4D color = m_pcbSettings.GetColor( aArc, aLayer );
double radius = aArc->GetRadius();
double start_angle = DECIDEG2RAD( aArc->GetArcAngleStart() );
double angle = DECIDEG2RAD( aArc->GetAngle() );
EDA_ANGLE start_angle = aArc->GetArcAngleStart();
EDA_ANGLE angle = aArc->GetAngle();
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->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
@ -685,8 +686,9 @@ void PCB_PAINTER::draw( const PCB_ARC* aArc, int aLayer )
m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( color );
m_gal->DrawArcSegment( center, radius, start_angle, start_angle + angle,
width + clearance * 2, m_maxError );
m_gal->DrawArcSegment( center, radius, start_angle.AsRadians(),
( start_angle + angle ).AsRadians(), width + clearance * 2,
m_maxError );
}
// 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
{
int numSegs = GetArcToSegmentCount( -margin.x, m_maxError, 360.0 );
int numSegs = GetArcToSegmentCount( -margin.x, m_maxError, FULL_CIRCLE );
SHAPE_POLY_SET outline;
outline.NewOutline();

View File

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

View File

@ -280,9 +280,9 @@ public:
virtual VECTOR2I GetCenter() const override { return GetPosition(); }
double GetRadius() const;
double GetAngle() const;
double GetArcAngleStart() const;
double GetArcAngleEnd() const;
EDA_ANGLE GetAngle() const;
EDA_ANGLE GetArcAngleStart() const;
EDA_ANGLE GetArcAngleEnd() const;
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;
@ -302,10 +302,7 @@ public:
*/
virtual double GetLength() const override
{
double radius = GetRadius();
double includedAngle = std::abs( GetAngle() );
return radius * M_PI * includedAngle / 1800.0;
return GetRadius() * std::abs( GetAngle().AsRadians() );
}
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()
// which can create bad shapes if margin.x is < 0
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,
SHAPE_POLY_SET::PM_FAST );
dummy.DeletePrimitivesList();
@ -421,7 +421,7 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
dummy.SetOrientation( ANGLE_0 );
SHAPE_POLY_SET outline;
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,
maxError, ERROR_INSIDE );
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()
// which can create bad shapes if margin.x is < 0
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 );
dummy.DeletePrimitivesList();
dummy.AddPrimitivePoly( shape, 0, true );
@ -581,11 +581,12 @@ void PlotStandardLayer( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
const PCB_ARC* arc = static_cast<const PCB_ARC*>( track );
VECTOR2D center( arc->GetCenter() );
int radius = arc->GetRadius();
double start_angle = arc->GetArcAngleStart();
double end_angle = start_angle + arc->GetAngle();
EDA_ANGLE start_angle = arc->GetArcAngleStart();
EDA_ANGLE end_angle = start_angle + arc->GetAngle();
aPlotter->ThickArc( VECTOR2I( center.x, center.y ), -end_angle, -start_angle,
radius, width, plotMode, &gbr_metadata );
aPlotter->ThickArc( VECTOR2I( center.x, center.y ), -end_angle.AsTenthsOfADegree(),
-start_angle.AsTenthsOfADegree(), radius, width, plotMode,
&gbr_metadata );
}
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
// 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:
{
radius = KiROUND( GetLineLength( aShape->GetCenter(), aShape->GetStart() ) );
double startAngle = ArcTangente( aShape->GetStart().y - aShape->GetCenter().y,
aShape->GetStart().x - aShape->GetCenter().x );
double endAngle = startAngle + aShape->GetArcAngle();
EDA_ANGLE startAngle( aShape->GetStart() - aShape->GetCenter() );
EDA_ANGLE endAngle = startAngle + aShape->GetArcAngle();
// 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(),
&gbr_metadata );
}
else
{
m_plotter->ThickArc( aShape->GetCenter(), -endAngle, -startAngle, radius, thickness,
m_plotter->ThickArc( aShape->GetCenter(), -endAngle.AsTenthsOfADegree(),
-startAngle.AsTenthsOfADegree(), radius, thickness,
GetPlotMode(), &gbr_metadata );
}
}
@ -956,20 +956,20 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape )
case SHAPE_T::ARC:
{
double startAngle = ArcTangente( aShape->GetStart().y - aShape->GetCenter().y,
aShape->GetStart().x - aShape->GetCenter().x );
double endAngle = startAngle + aShape->GetArcAngle();
EDA_ANGLE startAngle( aShape->GetStart() - aShape->GetCenter() );
EDA_ANGLE endAngle = startAngle + aShape->GetArcAngle();
// 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,
GetPlotMode(), &gbr_metadata );
}
else
{
m_plotter->ThickArc( aShape->GetCenter(), -endAngle, -startAngle,
aShape->GetRadius(), thickness, GetPlotMode(), &gbr_metadata );
m_plotter->ThickArc( aShape->GetCenter(), -endAngle.AsTenthsOfADegree(),
-startAngle.AsTenthsOfADegree(), aShape->GetRadius(),
thickness, GetPlotMode(), &gbr_metadata );
}
break;

View File

@ -176,7 +176,8 @@ void HelperShapeLineChainFromAltiumVertices( SHAPE_LINE_CHAIN& aLine,
{
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 endradiant = DEG2RAD( vertex.endangle );
@ -1990,17 +1991,18 @@ void ALTIUM_PCB::ParseArcs6Data( const CFB::CompoundFileReader& aReader,
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 );
VECTOR2I arcStartOffset =
VECTOR2I( KiROUND( std::cos( startradiant ) * elem.radius ),
VECTOR2I arcStartOffset = VECTOR2I( KiROUND( std::cos( startradiant ) * elem.radius ),
-KiROUND( std::sin( startradiant ) * elem.radius ) );
arcStartOffset += elem.center;
// If it's a circle then add two 180-degree arcs
if( elem.startangle == 0. && elem.endangle == 360. )
angle = 180.;
if( elem.startangle == 0.0 && elem.endangle == 360.0 )
angle = ANGLE_180;
SHAPE_ARC shapeArc( elem.center, arcStartOffset, angle, elem.width );
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;
bool cw = false;
double arcStartAngle, arcEndAngle, arcAngle;
VECTOR2I startPoint = getKiCadPoint( aCadstarStartPoint );
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_ARC:
{
if( isFootprint( aContainer ) )
shape = new FP_SHAPE((FOOTPRINT*) aContainer, SHAPE_T::ARC );
else
@ -2851,19 +2850,20 @@ PCB_SHAPE* CADSTAR_PCB_ARCHIVE_LOADER::getShapeFromVertex( const POINT& aCadstar
shape->SetCenter( centerPoint );
shape->SetStart( startPoint );
arcStartAngle = getPolarAngle( startPoint - centerPoint );
arcEndAngle = getPolarAngle( endPoint - centerPoint );
arcAngle = arcEndAngle - arcStartAngle;
EDA_ANGLE arcStartAngle( startPoint - centerPoint );
EDA_ANGLE arcEndAngle( endPoint - centerPoint );
EDA_ANGLE arcAngle = arcEndAngle - arcStartAngle;
//TODO: detect if we are supposed to draw a circle instead (i.e. two SEMICIRCLEs
// with opposite start/end points and same centre point)
if( cw )
shape->SetArcAngleAndEnd( NormalizeAnglePos( arcAngle ) );
shape->SetArcAngleAndEnd( arcAngle.Normalize().AsTenthsOfADegree() );
else
shape->SetArcAngleAndEnd( NormalizeAngleNeg( arcAngle ), true );
shape->SetArcAngleAndEnd( -arcAngle.Normalize().AsTenthsOfADegree(), true );
break;
}
}
//Apply transforms
if( aMirrorInvert )
@ -2992,7 +2992,7 @@ SHAPE_LINE_CHAIN CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromShapes( const std::
if( shape->GetClass() == wxT( "MGRAPHIC" ) )
{
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() )
arc.Reverse();
@ -3001,7 +3001,7 @@ SHAPE_LINE_CHAIN CADSTAR_PCB_ARCHIVE_LOADER::getLineChainFromShapes( const std::
}
else
{
SHAPE_ARC arc( shape->GetCenter(), shape->GetStart(), shape->GetArcAngle() / 10.0 );
SHAPE_ARC arc( shape->GetCenter(), shape->GetStart(), shape->GetArcAngle() );
if( shape->EndsSwapped() )
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 )
{
if( aCadstarNetID.IsEmpty() )

View File

@ -489,13 +489,6 @@ private:
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
* 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 )
+ 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;
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 )
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;
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 ) );
int segs = GetArcToSegmentCount( KiROUND( radius ), ARC_HIGH_DEF,
*w.curve );
EDA_ANGLE( *w.curve, DEGREES_T ) );
delta_angle = angle / segs;
}

View File

@ -4577,7 +4577,8 @@ PAD* PCB_PARSER::parsePAD( FOOTPRINT* aParent )
case T_gr_arc:
dummyShape = parsePCB_SHAPE();
pad->AddPrimitiveArc( dummyShape->GetCenter(), dummyShape->GetStart(),
dummyShape->GetArcAngle(), dummyShape->GetWidth() );
dummyShape->GetArcAngle().AsTenthsOfADegree(),
dummyShape->GetWidth() );
break;
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->Quotew( shownText ).c_str(),
FormatAngle( aText->GetDrawRotation().AsTenthsOfADegree() ).c_str() );
FormatAngle( aText->GetDrawRotation() ).c_str() );
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() );
if( !aFootprint->GetOrientation().IsZero() )
{
m_out->Print( 0, " %s",
FormatAngle( aFootprint->GetOrientation().AsTenthsOfADegree() ).c_str() );
}
m_out->Print( 0, " %s", FormatAngle( aFootprint->GetOrientation() ).c_str() );
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() );
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, ")" );
@ -1598,7 +1595,7 @@ void PCB_PLUGIN::format( const PAD* aPad, int aNestLevel ) const
|| ( aPad->GetShape() != PAD_SHAPE::CIRCLE && aPad->GetThermalSpokeAngle() != ANGLE_90 ) )
{
StrPrintf( &output, " (thermal_bridge_angle %s)",
FormatAngle( aPad->GetThermalSpokeAngle().AsTenthsOfADegree() ).c_str() );
FormatAngle( aPad->GetThermalSpokeAngle() ).c_str() );
}
if( aPad->GetThermalGap() != 0 )
@ -1722,7 +1719,7 @@ void PCB_PLUGIN::format( const PCB_TEXT* aText, int aNestLevel ) const
FormatInternalUnits( aText->GetTextPos() ).c_str() );
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, ")" );
@ -1814,7 +1811,7 @@ void PCB_PLUGIN::format( const FP_TEXT* aText, int aNestLevel ) const
}
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() )
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 );
lc.Append( SHAPE_ARC( center, aP, ( aSide ? -90 : 90 ) ) );
lc.Append( SHAPE_ARC( center, aP, ( aSide ? -ANGLE_90 : ANGLE_90 ) ) );
}
break;

View File

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

View File

@ -1269,7 +1269,7 @@ void ZONE::TransformSmoothedOutlineToPolygon( SHAPE_POLY_SET& aCornerBuffer, int
if( board )
maxError = board->GetDesignSettings().m_MaxError;
int segCount = GetArcToSegmentCount( aClearance, maxError, 360.0 );
int segCount = GetArcToSegmentCount( aClearance, maxError, FULL_CIRCLE );
polybuffer.Inflate( aClearance, segCount );
}
@ -1376,7 +1376,7 @@ void ZONE::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
// Rebuild filled areas only if clearance is not 0
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 );
}
}
@ -1406,7 +1406,7 @@ void ZONE::TransformSolidAreasShapesToPolygon( PCB_LAYER_ID aLayer, SHAPE_POLY_S
if( board )
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 );

View File

@ -1064,7 +1064,7 @@ bool ZONE_FILLER::computeRawFilledArea( const ZONE* aZone,
// deflating/inflating.
int half_min_width = aZone->GetMinThickness() / 2;
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
// 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.
int half_min_width = aZone->GetMinThickness() / 2;
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 );

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,
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 );
}
@ -599,7 +600,7 @@ BOOST_AUTO_TEST_CASE( CollidePt )
BOOST_TEST_CONTEXT( c.m_ctx_name )
{
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)
BOOST_TEST_CONTEXT( "Test Clearance" )
@ -664,7 +665,7 @@ BOOST_AUTO_TEST_CASE( CollideSeg )
BOOST_TEST_CONTEXT( c.m_ctx_name )
{
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)
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 ) ),
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;
}
@ -877,16 +878,16 @@ BOOST_AUTO_TEST_CASE( CollideArcToShapeLineChain )
BOOST_AUTO_TEST_CASE( CollideArcToPolygonApproximation )
{
SHAPE_ARC arc( VECTOR2I( 73843527, 74355869 ), VECTOR2I( 71713528, 72965869 ), -76.36664803,
2000000 );
SHAPE_ARC arc( VECTOR2I( 73843527, 74355869 ), VECTOR2I( 71713528, 72965869 ),
EDA_ANGLE( -76.36664803, DEGREES_T ), 2000000 );
// Create a polyset approximation from the arc - error outside (simulating the zone filler)
SHAPE_POLY_SET arcBuffer;
int clearance = ( arc.GetWidth() * 3 ) / 2;
int polygonApproximationError = SHAPE_ARC::DefaultAccuracyForPCB();
TransformArcToPolygon( arcBuffer, wxPoint( arc.GetP0() ), wxPoint( arc.GetArcMid() ),
wxPoint( arc.GetP1() ), arc.GetWidth() + 2 * clearance,
TransformArcToPolygon( arcBuffer, arc.GetP0(), arc.GetArcMid(), arc.GetP1(),
arc.GetWidth() + 2 * clearance,
polygonApproximationError, ERROR_OUTSIDE );
BOOST_REQUIRE_EQUAL( arcBuffer.OutlineCount(), 1 );
@ -1027,7 +1028,7 @@ BOOST_AUTO_TEST_CASE( ArcToPolyline )
BOOST_TEST_CONTEXT( c.m_ctx_name )
{
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 );

View File

@ -47,9 +47,9 @@ BOOST_AUTO_TEST_CASE( ArcToPolyline )
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( 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_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_EQUAL( base_chain.CShapes().size(), base_chain.CPoints().size() );
@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE( ArcToPolylineLargeCoords )
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_EQUAL( base_chain.PointCount(), 11 );
@ -198,7 +198,7 @@ BOOST_AUTO_TEST_CASE( Split )
{
SEG seg1( VECTOR2I( 0, 100000 ), VECTOR2I( 50000, 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)
SHAPE_LINE_CHAIN chain( { seg1.A, seg1.B } );
@ -271,8 +271,8 @@ BOOST_AUTO_TEST_CASE( Split )
BOOST_AUTO_TEST_CASE( Slice )
{
SEG targetSegment( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ) );
SHAPE_ARC firstArc( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ), 180.0 );
SHAPE_ARC secondArc( VECTOR2I( -200000, -200000 ), VECTOR2I( -300000, -100000 ), -180.0 );
SHAPE_ARC firstArc( VECTOR2I( 200000, 0 ), VECTOR2I( 300000, 0 ), ANGLE_180 );
SHAPE_ARC secondArc( VECTOR2I( -200000, -200000 ), VECTOR2I( -300000, -100000 ), -ANGLE_180 );
int tol = SHAPE_ARC::DefaultAccuracyForPCB(); // Tolerance for arc collisions
// Start a chain with 3 points
@ -433,7 +433,7 @@ BOOST_AUTO_TEST_CASE( NearestPointPt )
{
SEG seg1( VECTOR2I( 0, 100000 ), VECTOR2I( 50000, 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)
SHAPE_LINE_CHAIN chain( { seg1.A, seg1.B } );