mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-11 10:00:13 +00:00
More EDA_ANGLE.
This commit is contained in:
parent
1b19ff5f42
commit
07013d00e1
3d-viewer/3d_canvas
common
eeschema/sch_plugins
gerbview
include
libs/kimath
include
src
pcbnew
autorouter
convert_shape_list_to_polygon.cppdialogs
drc
drc_test_provider_library_parity.cppdrc_test_provider_mechanical_clearance.cppdrc_test_provider_solder_mask.cpp
exporters
footprint.hmicrowave
pad.cpppcb_painter.cpppcb_track.cpppcb_track.hplot_board_layers.cppplot_brditems_plotter.cppplugins
altium
cadstar
eagle
kicad
router
specctra_import_export
tools
zone.cppzone_filler.cppqa/libs/kimath/geometry
@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -242,11 +242,11 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
|
||||
{
|
||||
const PCB_ARC* arc = static_cast<const PCB_ARC*>( aTrack );
|
||||
|
||||
VECTOR2D center( arc->GetCenter() );
|
||||
double arc_angle = arc->GetAngle();
|
||||
double radius = arc->GetRadius();
|
||||
int arcsegcount = GetArcToSegmentCount( radius, ARC_HIGH_DEF, arc_angle / 10 );
|
||||
int circlesegcount;
|
||||
VECTOR2D center( arc->GetCenter() );
|
||||
EDA_ANGLE arc_angle = arc->GetAngle();
|
||||
double radius = arc->GetRadius();
|
||||
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
|
||||
// radius very big. so we calculate a reasonable value for circlesegcount.
|
||||
@ -256,12 +256,13 @@ void BOARD_ADAPTER::createTrack( const PCB_TRACK* aTrack, CONTAINER_2D_BASE* aDs
|
||||
}
|
||||
else
|
||||
{
|
||||
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,19 +76,19 @@ 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 == true, clamp between +/- full_circle_upper
|
||||
*/
|
||||
/*
|
||||
* if n720 == false, clamp between 0..full_circle_upper
|
||||
* if n720 == true, clamp between +/- full_circle_upper
|
||||
*/
|
||||
int full_circle_lower = n720 ? 0 : -full_circle_upper;
|
||||
|
||||
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;
|
||||
@ -101,9 +101,9 @@ double EDA_ANGLE::normalize( double aValue, EDA_ANGLE_T aAngleType, bool n720 )
|
||||
|
||||
switch( aAngleType )
|
||||
{
|
||||
case DEGREES_T: full_circle_upper = DEGREES_FULL_CIRCLE; break;
|
||||
case DEGREES_T: full_circle_upper = DEGREES_FULL_CIRCLE; break;
|
||||
case TENTHS_OF_A_DEGREE_T: full_circle_upper = TENTHS_OF_A_DEGREE_FULL_CIRCLE; break;
|
||||
case RADIANS_T: full_circle_upper = RADIANS_FULL_CIRCLE; break;
|
||||
case RADIANS_T: full_circle_upper = RADIANS_FULL_CIRCLE; break;
|
||||
}
|
||||
|
||||
double full_circle_lower = n720 ? 0 : -full_circle_upper;
|
||||
@ -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;
|
||||
}
|
||||
@ -1344,12 +1344,11 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
||||
case 1:
|
||||
{
|
||||
// Keep center clockwise from chord while drawing
|
||||
VECTOR2I chordVector = m_end - m_start;
|
||||
double chordAngle = ArcTangente( chordVector.y, chordVector.x );
|
||||
NORMALIZE_ANGLE_POS( chordAngle );
|
||||
VECTOR2I chordVector = m_end - m_start;
|
||||
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 );
|
||||
|
@ -462,21 +462,14 @@ void PLOTTER::Marker( const VECTOR2I& position, int diametre, unsigned aShapeId
|
||||
void PLOTTER::segmentAsOval( const VECTOR2I& start, const VECTOR2I& end, int width,
|
||||
OUTLINE_MODE tracemode )
|
||||
{
|
||||
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 );
|
||||
VECTOR2I center( ( start.x + end.x ) / 2, ( start.y + end.y ) / 2 );
|
||||
VECTOR2I size( end.x - start.x, end.y - start.y );
|
||||
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;
|
||||
int orientation = aSymbol->GetOrientation() & ~( SYM_MIRROR_X | SYM_MIRROR_Y );
|
||||
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 ),
|
||||
m_width( aWidth )
|
||||
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 );
|
||||
EDA_ANGLE alpha = ( pToAangle - pToBangle ).Normalize180();
|
||||
|
||||
double distPC = (double) aRadius / abs( sin( DECIDEG2RAD( alpha / 2 ) ) );
|
||||
double angPC = pToAangle - alpha / 2;
|
||||
double distPC = (double) aRadius / abs( sin( alpha.AsRadians() / 2 ) );
|
||||
EDA_ANGLE angPC = pToAangle - alpha / 2;
|
||||
VECTOR2I arcCenter;
|
||||
|
||||
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 );
|
||||
}
|
||||
@ -438,14 +441,11 @@ 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 );
|
||||
VECTOR2I center = GetCenter();
|
||||
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,11 +2155,11 @@ 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 );
|
||||
double deltaAngle = arcAngle / segments;
|
||||
double startAngle = atan2( -ys, xs );
|
||||
|
||||
// Flip arc for inner corners
|
||||
if( xa * yb - ya * xb <= 0 )
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user