7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-20 00:21:31 +00:00

Re-balance file sizes.

This commit is contained in:
Jeff Young 2025-02-21 12:31:08 +00:00
parent 76a3d1c845
commit e483c48fe6
2 changed files with 180 additions and 179 deletions

View File

@ -26,8 +26,10 @@
#include <geometry/circle.h>
#include <geometry/half_line.h>
#include <geometry/shape_arc.h>
#include <geometry/shape_poly_set.h>
#include <geometry/shape_utils.h>
#include <geometry/vector_utils.h>
#include <geometry/geometry_utils.h>
#include <trigo.h>
namespace
@ -255,4 +257,181 @@ std::optional<DOGBONE_RESULT> ComputeDogbone( const SEG& aSegA, const SEG& aSegB
small_arc_mouth,
};
}
}
}
SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::chamferFilletPolygon( CORNER_MODE aMode,
unsigned int aDistance,
int aIndex, int aErrorMax )
{
// Null segments create serious issues in calculations. Remove them:
RemoveNullSegments();
SHAPE_POLY_SET::POLYGON currentPoly = Polygon( aIndex );
SHAPE_POLY_SET::POLYGON newPoly;
// If the chamfering distance is zero, then the polygon remain intact.
if( aDistance == 0 )
{
return currentPoly;
}
// Iterate through all the contours (outline and holes) of the polygon.
for( SHAPE_LINE_CHAIN& currContour : currentPoly )
{
// Generate a new contour in the new polygon
SHAPE_LINE_CHAIN newContour;
// Iterate through the vertices of the contour
for( int currVertex = 0; currVertex < currContour.PointCount(); currVertex++ )
{
// Current vertex
int x1 = currContour.CPoint( currVertex ).x;
int y1 = currContour.CPoint( currVertex ).y;
// Indices for previous and next vertices.
int prevVertex;
int nextVertex;
// Previous and next vertices indices computation. Necessary to manage the edge cases.
// Previous vertex is the last one if the current vertex is the first one
prevVertex = currVertex == 0 ? currContour.PointCount() - 1 : currVertex - 1;
// next vertex is the first one if the current vertex is the last one.
nextVertex = currVertex == currContour.PointCount() - 1 ? 0 : currVertex + 1;
// Previous vertex computation
double xa = currContour.CPoint( prevVertex ).x - x1;
double ya = currContour.CPoint( prevVertex ).y - y1;
// Next vertex computation
double xb = currContour.CPoint( nextVertex ).x - x1;
double yb = currContour.CPoint( nextVertex ).y - y1;
// Avoid segments that will generate nans below
if( std::abs( xa + xb ) < std::numeric_limits<double>::epsilon()
&& std::abs( ya + yb ) < std::numeric_limits<double>::epsilon() )
{
continue;
}
// Compute the new distances
double lena = hypot( xa, ya );
double lenb = hypot( xb, yb );
// Make the final computations depending on the mode selected, chamfered or filleted.
if( aMode == CORNER_MODE::CHAMFERED )
{
double distance = aDistance;
// Chamfer one half of an edge at most
if( 0.5 * lena < distance )
distance = 0.5 * lena;
if( 0.5 * lenb < distance )
distance = 0.5 * lenb;
int nx1 = KiROUND( distance * xa / lena );
int ny1 = KiROUND( distance * ya / lena );
newContour.Append( x1 + nx1, y1 + ny1 );
int nx2 = KiROUND( distance * xb / lenb );
int ny2 = KiROUND( distance * yb / lenb );
newContour.Append( x1 + nx2, y1 + ny2 );
}
else // CORNER_MODE = FILLETED
{
double cosine = ( xa * xb + ya * yb ) / ( lena * lenb );
double radius = aDistance;
double denom = sqrt( 2.0 / ( 1 + cosine ) - 1 );
// Do nothing in case of parallel edges
if( std::isinf( denom ) )
continue;
// Limit rounding distance to one half of an edge
if( 0.5 * lena * denom < radius )
radius = 0.5 * lena * denom;
if( 0.5 * lenb * denom < radius )
radius = 0.5 * lenb * denom;
// Calculate fillet arc absolute center point (xc, yx)
double k = radius / sqrt( .5 * ( 1 - cosine ) );
double lenab = sqrt( ( xa / lena + xb / lenb ) * ( xa / lena + xb / lenb ) +
( ya / lena + yb / lenb ) * ( ya / lena + yb / lenb ) );
double xc = x1 + k * ( xa / lena + xb / lenb ) / lenab;
double yc = y1 + k * ( ya / lena + yb / lenb ) / lenab;
// Calculate arc start and end vectors
k = radius / sqrt( 2 / ( 1 + cosine ) - 1 );
double xs = x1 + k * xa / lena - xc;
double ys = y1 + k * ya / lena - yc;
double xe = x1 + k * xb / lenb - xc;
double ye = y1 + k * yb / lenb - yc;
// Cosine of arc angle
double argument = ( xs * xe + ys * ye ) / ( radius * radius );
// Make sure the argument is in [-1,1], interval in which the acos function is
// defined
if( argument < -1 )
argument = -1;
else if( argument > 1 )
argument = 1;
double arcAngle = acos( argument );
int segments = GetArcToSegmentCount( radius, aErrorMax,
EDA_ANGLE( arcAngle, RADIANS_T ) );
double deltaAngle = arcAngle / segments;
double startAngle = atan2( -ys, xs );
// Flip arc for inner corners
if( xa * yb - ya * xb <= 0 )
deltaAngle *= -1;
double nx = xc + xs;
double ny = yc + ys;
if( std::isnan( nx ) || std::isnan( ny ) )
continue;
newContour.Append( KiROUND( nx ), KiROUND( ny ) );
// Store the previous added corner to make a sanity check
int prevX = KiROUND( nx );
int prevY = KiROUND( ny );
for( int j = 0; j < segments; j++ )
{
nx = xc + cos( startAngle + ( j + 1 ) * deltaAngle ) * radius;
ny = yc - sin( startAngle + ( j + 1 ) * deltaAngle ) * radius;
if( std::isnan( nx ) || std::isnan( ny ) )
continue;
// Sanity check: the rounding can produce repeated corners; do not add them.
if( KiROUND( nx ) != prevX || KiROUND( ny ) != prevY )
{
newContour.Append( KiROUND( nx ), KiROUND( ny ) );
prevX = KiROUND( nx );
prevY = KiROUND( ny );
}
}
}
}
// Close the current contour and add it the new polygon
newContour.SetClosed( true );
newPoly.push_back( newContour );
}
return newPoly;
}

View File

@ -57,9 +57,6 @@
#include <geometry/shape_segment.h>
#include <geometry/shape_circle.h>
// Do not keep this for release. Only for testing clipper
#include <advanced_config.h>
#include <wx/log.h>
// ADVANCED_CFG::GetCfg() cannot be used on msys2/mingw builds (link failure)
@ -2708,181 +2705,6 @@ SHAPE_POLY_SET SHAPE_POLY_SET::Fillet( int aRadius, int aErrorMax )
}
SHAPE_POLY_SET::POLYGON SHAPE_POLY_SET::chamferFilletPolygon( CORNER_MODE aMode,
unsigned int aDistance,
int aIndex, int aErrorMax )
{
// Null segments create serious issues in calculations. Remove them:
RemoveNullSegments();
SHAPE_POLY_SET::POLYGON currentPoly = Polygon( aIndex );
SHAPE_POLY_SET::POLYGON newPoly;
// If the chamfering distance is zero, then the polygon remain intact.
if( aDistance == 0 )
{
return currentPoly;
}
// Iterate through all the contours (outline and holes) of the polygon.
for( SHAPE_LINE_CHAIN& currContour : currentPoly )
{
// Generate a new contour in the new polygon
SHAPE_LINE_CHAIN newContour;
// Iterate through the vertices of the contour
for( int currVertex = 0; currVertex < currContour.PointCount(); currVertex++ )
{
// Current vertex
int x1 = currContour.CPoint( currVertex ).x;
int y1 = currContour.CPoint( currVertex ).y;
// Indices for previous and next vertices.
int prevVertex;
int nextVertex;
// Previous and next vertices indices computation. Necessary to manage the edge cases.
// Previous vertex is the last one if the current vertex is the first one
prevVertex = currVertex == 0 ? currContour.PointCount() - 1 : currVertex - 1;
// next vertex is the first one if the current vertex is the last one.
nextVertex = currVertex == currContour.PointCount() - 1 ? 0 : currVertex + 1;
// Previous vertex computation
double xa = currContour.CPoint( prevVertex ).x - x1;
double ya = currContour.CPoint( prevVertex ).y - y1;
// Next vertex computation
double xb = currContour.CPoint( nextVertex ).x - x1;
double yb = currContour.CPoint( nextVertex ).y - y1;
// Avoid segments that will generate nans below
if( std::abs( xa + xb ) < std::numeric_limits<double>::epsilon()
&& std::abs( ya + yb ) < std::numeric_limits<double>::epsilon() )
{
continue;
}
// Compute the new distances
double lena = hypot( xa, ya );
double lenb = hypot( xb, yb );
// Make the final computations depending on the mode selected, chamfered or filleted.
if( aMode == CORNER_MODE::CHAMFERED )
{
double distance = aDistance;
// Chamfer one half of an edge at most
if( 0.5 * lena < distance )
distance = 0.5 * lena;
if( 0.5 * lenb < distance )
distance = 0.5 * lenb;
int nx1 = KiROUND( distance * xa / lena );
int ny1 = KiROUND( distance * ya / lena );
newContour.Append( x1 + nx1, y1 + ny1 );
int nx2 = KiROUND( distance * xb / lenb );
int ny2 = KiROUND( distance * yb / lenb );
newContour.Append( x1 + nx2, y1 + ny2 );
}
else // CORNER_MODE = FILLETED
{
double cosine = ( xa * xb + ya * yb ) / ( lena * lenb );
double radius = aDistance;
double denom = sqrt( 2.0 / ( 1 + cosine ) - 1 );
// Do nothing in case of parallel edges
if( std::isinf( denom ) )
continue;
// Limit rounding distance to one half of an edge
if( 0.5 * lena * denom < radius )
radius = 0.5 * lena * denom;
if( 0.5 * lenb * denom < radius )
radius = 0.5 * lenb * denom;
// Calculate fillet arc absolute center point (xc, yx)
double k = radius / sqrt( .5 * ( 1 - cosine ) );
double lenab = sqrt( ( xa / lena + xb / lenb ) * ( xa / lena + xb / lenb ) +
( ya / lena + yb / lenb ) * ( ya / lena + yb / lenb ) );
double xc = x1 + k * ( xa / lena + xb / lenb ) / lenab;
double yc = y1 + k * ( ya / lena + yb / lenb ) / lenab;
// Calculate arc start and end vectors
k = radius / sqrt( 2 / ( 1 + cosine ) - 1 );
double xs = x1 + k * xa / lena - xc;
double ys = y1 + k * ya / lena - yc;
double xe = x1 + k * xb / lenb - xc;
double ye = y1 + k * yb / lenb - yc;
// Cosine of arc angle
double argument = ( xs * xe + ys * ye ) / ( radius * radius );
// Make sure the argument is in [-1,1], interval in which the acos function is
// defined
if( argument < -1 )
argument = -1;
else if( argument > 1 )
argument = 1;
double arcAngle = acos( argument );
int segments = GetArcToSegmentCount( radius, aErrorMax,
EDA_ANGLE( arcAngle, RADIANS_T ) );
double deltaAngle = arcAngle / segments;
double startAngle = atan2( -ys, xs );
// Flip arc for inner corners
if( xa * yb - ya * xb <= 0 )
deltaAngle *= -1;
double nx = xc + xs;
double ny = yc + ys;
if( std::isnan( nx ) || std::isnan( ny ) )
continue;
newContour.Append( KiROUND( nx ), KiROUND( ny ) );
// Store the previous added corner to make a sanity check
int prevX = KiROUND( nx );
int prevY = KiROUND( ny );
for( int j = 0; j < segments; j++ )
{
nx = xc + cos( startAngle + ( j + 1 ) * deltaAngle ) * radius;
ny = yc - sin( startAngle + ( j + 1 ) * deltaAngle ) * radius;
if( std::isnan( nx ) || std::isnan( ny ) )
continue;
// Sanity check: the rounding can produce repeated corners; do not add them.
if( KiROUND( nx ) != prevX || KiROUND( ny ) != prevY )
{
newContour.Append( KiROUND( nx ), KiROUND( ny ) );
prevX = KiROUND( nx );
prevY = KiROUND( ny );
}
}
}
}
// Close the current contour and add it the new polygon
newContour.SetClosed( true );
newPoly.push_back( newContour );
}
return newPoly;
}
SHAPE_POLY_SET &SHAPE_POLY_SET::operator=( const SHAPE_POLY_SET& aOther )
{
SHAPE::operator=( aOther );