Commit b9b8bf2f authored by charras's avatar charras

In zones filling better shape around rectangular pads (patch from Vesa Solonen)

parent 3c27f847
...@@ -346,27 +346,52 @@ void AddPadWithClearancePolygon( Bool_Engine* aBooleng, ...@@ -346,27 +346,52 @@ void AddPadWithClearancePolygon( Bool_Engine* aBooleng,
break; break;
} }
case PAD_RECT: case PAD_RECT: // Easy implementation for rectangular cutouts with rounded corners
angle = aPad.m_Orient; angle = aPad.m_Orient;
corner_position = wxPoint( -dx, -dy ); int rounding_radius = (int) (aClearanceValue * s_Correction); // Corner rounding radius
RotatePoint( &corner_position, angle ); int angle_pg; // Polygon increment angle
corner_position += PadShapePos;
aBooleng->AddPoint( corner_position.x, corner_position.y );
corner_position = wxPoint( -dx, +dy ); for( int i = 0; i < s_CircleToSegmentsCount / 4 + 1; i++ )
{
corner_position = wxPoint( 0, -rounding_radius );
angle_pg = i * delta;
RotatePoint( &corner_position, angle_pg ); // Rounding vector rotation
corner_position -= aPad.m_Size/2 ; // Rounding vector + Pad corner offset
RotatePoint( &corner_position, angle ); // Rotate according to module orientation
corner_position += PadShapePos; // Shift origin to position
aBooleng->AddPoint( corner_position.x, corner_position.y );
}
for( int i = 0; i < s_CircleToSegmentsCount / 4 + 1; i++ )
{
corner_position = wxPoint( -rounding_radius, 0 );
angle_pg = i * delta;
RotatePoint( &corner_position, angle_pg );
corner_position -= wxPoint( aPad.m_Size.x/2, -aPad.m_Size.y/2 );
RotatePoint( &corner_position, angle ); RotatePoint( &corner_position, angle );
corner_position += aPad.ReturnShapePos(); corner_position += PadShapePos;
aBooleng->AddPoint( corner_position.x, corner_position.y ); aBooleng->AddPoint( corner_position.x, corner_position.y );
}
corner_position = wxPoint( +dx, +dy ); for( int i = 0; i < s_CircleToSegmentsCount / 4 + 1; i++ )
{
corner_position = wxPoint( 0, rounding_radius );
angle_pg = i * delta;
RotatePoint( &corner_position, angle_pg );
corner_position += aPad.m_Size/2 ;
RotatePoint( &corner_position, angle ); RotatePoint( &corner_position, angle );
corner_position += PadShapePos; corner_position += PadShapePos;
aBooleng->AddPoint( corner_position.x, corner_position.y ); aBooleng->AddPoint( corner_position.x, corner_position.y );
}
corner_position = wxPoint( +dx, -dy ); for( int i = 0; i < s_CircleToSegmentsCount / 4 + 1; i++ )
{
corner_position = wxPoint( rounding_radius, 0 );
angle_pg = i * delta;
RotatePoint( &corner_position, angle_pg );
corner_position -= wxPoint( -aPad.m_Size.x/2, aPad.m_Size.y/2 );
RotatePoint( &corner_position, angle ); RotatePoint( &corner_position, angle );
corner_position += PadShapePos; corner_position += PadShapePos;
aBooleng->AddPoint( corner_position.x, corner_position.y ); aBooleng->AddPoint( corner_position.x, corner_position.y );
}
break; break;
} }
...@@ -376,7 +401,7 @@ void AddPadWithClearancePolygon( Bool_Engine* aBooleng, ...@@ -376,7 +401,7 @@ void AddPadWithClearancePolygon( Bool_Engine* aBooleng,
/** function AddThermalReliefPadPolygon /** function AddThermalReliefPadPolygon
* Add holes around a pad to create a thermal relief * Add holes around a pad to create a thermal relief
* copper tickness is min (dx/2, aCopperWitdh) or min (dy/2, aCopperWitdh) * copper thickness is min (dx/2, aCopperWitdh) or min (dy/2, aCopperWitdh)
* @param aBooleng = current Bool_Engine * @param aBooleng = current Bool_Engine
* @param aPad = the current pad used to create the thermal shape * @param aPad = the current pad used to create the thermal shape
* @param aThermalGap = gap in thermal shape * @param aThermalGap = gap in thermal shape
...@@ -417,7 +442,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng, ...@@ -417,7 +442,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
wxPoint PadShapePos = aPad.ReturnShapePos(); /* Note: for pad having a shape offset, wxPoint PadShapePos = aPad.ReturnShapePos(); /* Note: for pad having a shape offset,
* the pad position is NOT the shape position */ * the pad position is NOT the shape position */
int angle = 0; int angle = 0;
wxSize copper_tickness; wxSize copper_thickness;
int dx = aPad.m_Size.x / 2; int dx = aPad.m_Size.x / 2;
int dy = aPad.m_Size.y / 2; int dy = aPad.m_Size.y / 2;
...@@ -430,15 +455,15 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng, ...@@ -430,15 +455,15 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
aThermalGap += aMinThicknessValue / 2; aThermalGap += aMinThicknessValue / 2;
/* Keep in account the polygon outline thickness /* Keep in account the polygon outline thickness
* copper_tickness must be decreased by aMinThicknessValue because drawing outlines * copper_thickness must be decreased by aMinThicknessValue because drawing outlines
* with a thickness of aMinThicknessValue will increase real thickness by aMinThicknessValue * with a thickness of aMinThicknessValue will increase real thickness by aMinThicknessValue
*/ */
aCopperThickness -= aMinThicknessValue; aCopperThickness -= aMinThicknessValue;
if( aCopperThickness < 0 ) if( aCopperThickness < 0 )
aCopperThickness = 0; aCopperThickness = 0;
copper_tickness.x = min( dx, aCopperThickness ); copper_thickness.x = min( dx, aCopperThickness );
copper_tickness.y = min( dy, aCopperThickness ); copper_thickness.y = min( dy, aCopperThickness );
switch( aPad.m_PadShape ) switch( aPad.m_PadShape )
{ {
...@@ -464,16 +489,16 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng, ...@@ -464,16 +489,16 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
int outer_radius = dx + aThermalGap; // The radius of the outer arc is pad radius + aThermalGap int outer_radius = dx + aThermalGap; // The radius of the outer arc is pad radius + aThermalGap
// Crosspoint of thermal spoke sides, the first point of polygon buffer // Crosspoint of thermal spoke sides, the first point of polygon buffer
corners_buffer.push_back( wxPoint( copper_tickness.x / 2, copper_tickness.y / 2 ) ); corners_buffer.push_back( wxPoint( copper_thickness.x / 2, copper_thickness.y / 2 ) );
// Add an intermediate point on spoke sides, to allow a > 90 deg angle between side and first seg of arc approx // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side and first seg of arc approx
corner.x = copper_tickness.x / 2; corner.x = copper_thickness.x / 2;
int y = outer_radius - (aThermalGap / 4); int y = outer_radius - (aThermalGap / 4);
corner.y = (int) sqrt( ( ( (double) y * y ) - (double) corner.x * corner.x ) ); corner.y = (int) sqrt( ( ( (double) y * y ) - (double) corner.x * corner.x ) );
corners_buffer.push_back( corner ); corners_buffer.push_back( corner );
// calculate the starting point of the outter arc // calculate the starting point of the outter arc
corner.x = copper_tickness.x / 2; corner.x = copper_thickness.x / 2;
double dtmp = double dtmp =
sqrt( ( (double) outer_radius * outer_radius ) - ( (double) corner.x * corner.x ) ); sqrt( ( (double) outer_radius * outer_radius ) - ( (double) corner.x * corner.x ) );
corner.y = (int) dtmp; corner.y = (int) dtmp;
...@@ -543,7 +568,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng, ...@@ -543,7 +568,7 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
{ {
EXCHG( dx, dy ); EXCHG( dx, dy );
supp_angle = 900; supp_angle = 900;
EXCHG( copper_tickness.x, copper_tickness.y ); EXCHG( copper_thickness.x, copper_thickness.y );
} }
int deltasize = dx - dy; // = distance between shape position and the 2 demi-circle ends centre int deltasize = dx - dy; // = distance between shape position and the 2 demi-circle ends centre
// here we have dx > dy // here we have dx > dy
...@@ -554,12 +579,12 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng, ...@@ -554,12 +579,12 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
shape_offset = wxPoint( deltasize, 0 ); shape_offset = wxPoint( deltasize, 0 );
// Crosspoint of thermal spoke sides, the first point of polygon buffer // Crosspoint of thermal spoke sides, the first point of polygon buffer
corners_buffer.push_back( wxPoint( copper_tickness.x / 2, copper_tickness.y / 2 ) ); corners_buffer.push_back( wxPoint( copper_thickness.x / 2, copper_thickness.y / 2 ) );
// Arc start point calculation, the intersecting point of cutout arc and thermal spoke edge // Arc start point calculation, the intersecting point of cutout arc and thermal spoke edge
if( copper_tickness.x > deltasize ) // If copper thickness is more than shape offset, we need to calculate arc intercept point. if( copper_thickness.x > deltasize ) // If copper thickness is more than shape offset, we need to calculate arc intercept point.
{ {
corner.x = copper_tickness.x / 2; corner.x = copper_thickness.x / 2;
corner.y = corner.y =
(int) sqrt( ( (double) outer_radius * outer_radius ) - (int) sqrt( ( (double) outer_radius * outer_radius ) -
( (double) ( corner.x - delta ) * ( corner.x - deltasize ) ) ); ( (double) ( corner.x - delta ) * ( corner.x - deltasize ) ) );
...@@ -575,21 +600,21 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng, ...@@ -575,21 +600,21 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
} }
else else
{ {
corner.x = copper_tickness.x / 2; corner.x = copper_thickness.x / 2;
corner.y = outer_radius; corner.y = outer_radius;
corners_buffer.push_back( corner ); corners_buffer.push_back( corner );
corner.x = ( deltasize - copper_tickness.x ) / 2; corner.x = ( deltasize - copper_thickness.x ) / 2;
} }
// Add an intermediate point on spoke sides, to allow a > 90 deg angle between side and first seg of arc approx // Add an intermediate point on spoke sides, to allow a > 90 deg angle between side and first seg of arc approx
wxPoint last_corner; wxPoint last_corner;
last_corner.y = copper_tickness.y / 2; last_corner.y = copper_thickness.y / 2;
int px = outer_radius - (aThermalGap / 4); int px = outer_radius - (aThermalGap / 4);
last_corner.x = last_corner.x =
(int) sqrt( ( ( (double) px * px ) - (double) last_corner.y * last_corner.y ) ); (int) sqrt( ( ( (double) px * px ) - (double) last_corner.y * last_corner.y ) );
// Arc stop point calculation, the intersecting point of cutout arc and thermal spoke edge // Arc stop point calculation, the intersecting point of cutout arc and thermal spoke edge
corner_end.y = copper_tickness.y / 2; corner_end.y = copper_thickness.y / 2;
corner_end.x = corner_end.x =
(int) sqrt( ( (double) outer_radius * (int) sqrt( ( (double) outer_radius *
outer_radius ) - ( (double) corner_end.y * corner_end.y ) ); outer_radius ) - ( (double) corner_end.y * corner_end.y ) );
...@@ -680,26 +705,42 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng, ...@@ -680,26 +705,42 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
// | | // | |
// | | // | |
// 1 -------4 // 1 -------4
wxPoint corners_hole[4]; // buffer for 4 corners
// Create 1 hole, for a pad centered at 0,0, orient 0
// Calculate coordinates for corner 1 to corner 4:
corners_hole[0] = wxPoint( copper_tickness.x / 2, -copper_tickness.y / 2 );
corners_hole[1] = wxPoint( (copper_tickness.x / 2), -dy - aThermalGap );
corners_hole[2] = wxPoint( dx + aThermalGap, -dy - aThermalGap );
corners_hole[3] = wxPoint( dx + aThermalGap, -(copper_tickness.y / 2) );
/* Create 2 holes, rotated by pad rotation. // Modified rectangles with one corner rounded. TODO: merging with oval thermals and possibly round too.
*/
std::vector <wxPoint> corners_buffer; // Polygon buffer as vector
int dx = (aPad.m_Size.x / 2) + aThermalGap; // Cutout radius x
int dy = (aPad.m_Size.y / 2) + aThermalGap; // Cutout radius y
// The first point of polygon buffer is left lower corner, second the crosspoint of thermal spoke sides,
// the third is upper right corner and the rest are rounding vertices going anticlockwise. Note the inveted Y-axis in CG.
corners_buffer.push_back( wxPoint( -dx, -copper_thickness.y / 2 ) );
corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -copper_thickness.y / 2 ) );
corners_buffer.push_back( wxPoint( -copper_thickness.x / 2, -dy ) );
angle = aPad.m_Orient; angle = aPad.m_Orient;
int rounding_radius = (int) (aThermalGap * s_Correction); // Corner rounding radius
int angle_pg; // Polygon increment angle
for( int i = 0; i < s_CircleToSegmentsCount / 4 + 1; i++ )
{
wxPoint corner_position = wxPoint( 0, -rounding_radius );
angle_pg = i * delta;
RotatePoint( &corner_position, angle_pg ); // Rounding vector rotation
corner_position -= aPad.m_Size/2 ; // Rounding vector + Pad corner offset
corners_buffer.push_back( wxPoint( corner_position.x, corner_position.y ) );
}
for( int irect = 0; irect < 2; irect++ ) for( int irect = 0; irect < 2; irect++ )
{ {
if( aBooleng->StartPolygonAdd( GROUP_B ) ) if( aBooleng->StartPolygonAdd( GROUP_B ) )
{ {
for( int ic = 0; ic < 4; ic++ ) for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
{ {
wxPoint cpos = corners_hole[ic]; wxPoint cpos = corners_buffer[ic];
RotatePoint( &cpos, angle ); RotatePoint( &cpos, angle ); // Rotate according to module orientation
cpos += PadShapePos; cpos += PadShapePos; // Shift origin to position
aBooleng->AddPoint( cpos.x, cpos.y ); aBooleng->AddPoint( cpos.x, cpos.y );
} }
...@@ -710,21 +751,22 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng, ...@@ -710,21 +751,22 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
} }
} }
// Create a holes, that is the mirrored of the previous hole // Create holes, that are the mirrored from the previous holes
corners_hole[0].x = -corners_hole[0].x; for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
corners_hole[1].x = -corners_hole[1].x; {
corners_hole[2].x = -corners_hole[2].x; wxPoint swap = corners_buffer[ic];
corners_hole[3].x = -corners_hole[3].x; swap.x = -swap.x;
corners_buffer[ic] = swap;
}
// Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg // Now add corner 4 and 2 (2 is the corner 4 rotated by 180 deg
angle = aPad.m_Orient;
for( int irect = 0; irect < 2; irect++ ) for( int irect = 0; irect < 2; irect++ )
{ {
if( aBooleng->StartPolygonAdd( GROUP_B ) ) if( aBooleng->StartPolygonAdd( GROUP_B ) )
{ {
for( int ic = 0; ic < 4; ic++ ) for( unsigned ic = 0; ic < corners_buffer.size(); ic++ )
{ {
wxPoint cpos = corners_hole[ic]; wxPoint cpos = corners_buffer[ic];
RotatePoint( &cpos, angle ); RotatePoint( &cpos, angle );
cpos += PadShapePos; cpos += PadShapePos;
aBooleng->AddPoint( cpos.x, cpos.y ); aBooleng->AddPoint( cpos.x, cpos.y );
...@@ -736,9 +778,9 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng, ...@@ -736,9 +778,9 @@ void AddThermalReliefPadPolygon( Bool_Engine* aBooleng,
angle -= 3600; angle -= 3600;
} }
} }
}
break; break;
} }
}
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment