More EDA_ANGLE.
This commit is contained in:
parent
1b19ff5f42
commit
07013d00e1
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() )
|
||||
|
|
|
@ -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() );
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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() )
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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" );
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 } );
|
||||
|
|
Loading…
Reference in New Issue