Loading pcbnew/zones_by_polygon.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -65,7 +65,7 @@ void WinEDA_PcbFrame::Add_Similar_Zone( wxDC* DC, ZONE_CONTAINER* zone_container // Use the general event handle to set others params (like toolbar) */ // Use the general event handle to set others params (like toolbar) */ wxCommandEvent evt; wxCommandEvent evt; evt.SetId( ID_PCB_ZONES_BUTT ); evt.SetId( ID_PCB_ZONES_BUTT ); Process_Special_Functions( evt ); OnSelectTool( evt ); } } Loading @@ -91,7 +91,7 @@ void WinEDA_PcbFrame::Add_Zone_Cutout( wxDC* DC, ZONE_CONTAINER* zone_container // Use the general event handle to set others params (like toolbar) */ // Use the general event handle to set others params (like toolbar) */ wxCommandEvent evt; wxCommandEvent evt; evt.SetId( ID_PCB_ZONES_BUTT ); evt.SetId( ID_PCB_ZONES_BUTT ); Process_Special_Functions( evt ); OnSelectTool( evt ); } } Loading polygon/PolyLine.cpp +153 −222 Original line number Original line Diff line number Diff line Loading @@ -907,141 +907,159 @@ void CPolyLine::RemoveContour( int icont ) } } int CPolyLine::Chamfer( unsigned int aIndex, unsigned int aDistance ) CPolyLine* CPolyLine::Chamfer( unsigned int aDistance ) { { int x1, y1; CPolyLine* newPoly = new CPolyLine; long xa, ya, xb, yb, nx, ny; if( !aDistance ) if( !aDistance ) return 0; { newPoly->Copy( this ); return newPoly; } x1 = corner[aIndex].x; for( int contour = 0; contour < GetNumContours(); contour++ ) y1 = corner[aIndex].y; { unsigned int startIndex = GetContourStart( contour ); unsigned int endIndex = GetContourEnd( contour ); for( unsigned int index = startIndex; index <= endIndex; index++ ) { int x1, y1, nx, ny; long long xa, ya, xb, yb; if( aIndex == 0 ) x1 = corner[index].x; y1 = corner[index].y; if( index == startIndex ) { { xa = corner[corner.size()-1].x - x1; xa = corner[endIndex].x - x1; ya = corner[corner.size()-1].y - y1; ya = corner[endIndex].y - y1; } } else else { { xa = corner[aIndex-1].x - x1; xa = corner[index-1].x - x1; ya = corner[aIndex-1].y - y1; ya = corner[index-1].y - y1; } } if( aIndex == corner.size()-1 ) if( index == endIndex ) { { xb = corner[0].x - x1; xb = corner[startIndex].x - x1; yb = corner[0].y - y1; yb = corner[startIndex].y - y1; } } else else { { xb = corner[aIndex+1].x - x1; xb = corner[index+1].x - x1; yb = corner[aIndex+1].y - y1; yb = corner[index+1].y - y1; } } // Move the first vertex into new position unsigned int lena = (unsigned int)sqrt( (double)(xa*xa + ya*ya) ); nx = (long) ( (double) (aDistance*xa)/sqrt( (double) (xa*xa + ya*ya) ) ); unsigned int lenb = (unsigned int)sqrt( (double)(xb*xb + yb*yb) ); ny = (long) ( (double) (aDistance*ya)/sqrt( (double) (xa*xa + ya*ya) ) ); unsigned int distance = aDistance; corner[aIndex].x = x1 + nx; corner[aIndex].y = y1 + ny; // Add one new vertex nx = (long) ( (double) (aDistance*xb)/sqrt( (double) (xb*xb + yb*yb) ) ); ny = (long) ( (double) (aDistance*yb)/sqrt( (double) (xb*xb + yb*yb) ) ); InsertCorner( aIndex, x1 + nx, y1 + ny ); return 1; // Added one vertex // 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; CPolyLine* CPolyLine::Chamfer( unsigned int aDistance ) nx = (int) ( (double) (distance*xa)/sqrt( (double) (xa*xa + ya*ya) ) ); { ny = (int) ( (double) (distance*ya)/sqrt( (double) (xa*xa + ya*ya) ) ); CPolyLine* newPoly = new CPolyLine; unsigned int lena, lenb; newPoly->Copy( this ); for( unsigned int i = 0, index = 0; i < corner.size(); i++, index++ ) if( index == startIndex ) { newPoly->Start( GetLayer(), x1 + nx, y1 + ny, GetHatchStyle() ); if( i == 0 ) lena = GetEdgeLength( corner.size()-1 ); else else lena = GetEdgeLength( i - 1 ); newPoly->AppendCorner( x1 + nx, y1 + ny ); lenb = GetEdgeLength( i ); unsigned int distance = aDistance; nx = (int) ( (double) (distance*xb)/sqrt( (double) (xb*xb + yb*yb) ) ); ny = (int) ( (double) (distance*yb)/sqrt( (double) (xb*xb + yb*yb) ) ); newPoly->AppendCorner( x1 + nx, y1 + ny ); } newPoly->Close(); } // Chamfer one half of an edge at most return newPoly; if( 0.5*lena < distance ) } distance = (unsigned int) 0.5*lena; if( 0.5*lenb < distance ) distance = (unsigned int) 0.5*lenb; // Chamfer this corner and keep tract of added vertices CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) index += newPoly->Chamfer( index, distance ); { } CPolyLine* newPoly = new CPolyLine; if( !aRadius ) { newPoly->Copy( this ); return newPoly; return newPoly; } } for( int contour = 0; contour < GetNumContours(); contour++ ) { unsigned int startIndex = GetContourStart( contour ); unsigned int endIndex = GetContourEnd( contour ); int CPolyLine::Fillet( unsigned int aIndex, unsigned int aRadius, for( unsigned int index = startIndex; index <= endIndex; index++ ) unsigned int aSegments ) { { int x1, y1; // Current vertex int x1, y1; // Current vertex int xa, ya; // Previous vertex long long xa, ya; // Previous vertex int xb, yb; // Next vertex long long xb, yb; // Next vertex double nx, ny; double nx, ny; if( !aRadius ) x1 = corner[index].x; return 0; y1 = corner[index].y; x1 = corner[aIndex].x; y1 = corner[aIndex].y; if( aIndex == 0 ) if( index == startIndex ) { { xa = corner[corner.size()-1].x - x1; xa = corner[endIndex].x - x1; ya = corner[corner.size()-1].y - y1; ya = corner[endIndex].y - y1; } } else else { { xa = corner[aIndex-1].x - x1; xa = corner[index-1].x - x1; ya = corner[aIndex-1].y - y1; ya = corner[index-1].y - y1; } } if( aIndex == corner.size()-1 ) if( index == endIndex ) { { xb = corner[0].x - x1; xb = corner[startIndex].x - x1; yb = corner[0].y - y1; yb = corner[startIndex].y - y1; } } else else { { xb = corner[aIndex+1].x - x1; xb = corner[index+1].x - x1; yb = corner[aIndex+1].y - y1; yb = corner[index+1].y - y1; } } double lena = sqrt( (double) (xa*xa + ya*ya) ); double lena = sqrt( (double) (xa*xa + ya*ya) ); double lenb = sqrt( (double) (xb*xb + yb*yb) ); double lenb = sqrt( (double) (xb*xb + yb*yb) ); double cosine = ( xa*xb + ya*yb )/( lena*lenb ); double cosine = ( xa*xb + ya*yb )/( lena*lenb ); unsigned int radius = aRadius; double denom = sqrt( 2.0/( 1+cosine )-1 ); // 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) // Calculate fillet arc absolute center point (xc, yx) double k = aRadius / sqrt( .5*( 1-cosine ) ); double k = radius / sqrt( .5*( 1-cosine ) ); double lenab = sqrt( ( xa/lena + xb/lenb )*( xa/lena + xb/lenb ) + double lenab = sqrt( ( xa/lena + xb/lenb )*( xa/lena + xb/lenb ) + ( ya/lena + yb/lenb )*( ya/lena + yb/lenb ) ); ( ya/lena + yb/lenb )*( ya/lena + yb/lenb ) ); double xc = x1 + k*( xa/lena + xb/lenb )/lenab; double xc = x1 + k*( xa/lena + xb/lenb )/lenab; double yc = y1 + k*( ya/lena + yb/lenb )/lenab; double yc = y1 + k*( ya/lena + yb/lenb )/lenab; // Calculate arc start and end vectors // Calculate arc start and end vectors k = aRadius / sqrt( 2/( 1+cosine )-1 ); k = radius / sqrt( 2/( 1+cosine )-1 ); double xs = x1 + k*xa/lena - xc; double xs = x1 + k*xa/lena - xc; double ys = y1 + k*ya/lena - yc; double ys = y1 + k*ya/lena - yc; double xe = x1 + k*xb/lenb - xc; double xe = x1 + k*xb/lenb - xc; double ye = y1 + k*yb/lenb - yc; double ye = y1 + k*yb/lenb - yc; // Cosine of arc angle // Cosine of arc angle double argument = ( xs*xe + ys*ye ) / ( aRadius*aRadius ); double argument = ( xs*xe + ys*ye ) / ( radius*radius ); if( argument < -1 ) // Just in case... if( argument < -1 ) // Just in case... argument = -1; argument = -1; Loading @@ -1055,63 +1073,33 @@ int CPolyLine::Fillet( unsigned int aIndex, unsigned int aRadius, if( tempSegments - (int)tempSegments > 0 ) if( tempSegments - (int)tempSegments > 0 ) tempSegments++; tempSegments++; aSegments = (unsigned int) tempSegments; unsigned int segments = (unsigned int) tempSegments; double deltaAngle = arcAngle / aSegments; double deltaAngle = arcAngle / segments; double startAngle = atan2( -ys, xs ); double startAngle = atan2( -ys, xs ); // Flip arc for inner corners // Flip arc for inner corners if( xa*yb - ya*xb <= 0 ) if( xa*yb - ya*xb <= 0 ) deltaAngle *= -1; deltaAngle *= -1; // Move first vertex into new position nx = xc + xs + 0.5; nx = xc + xs + 0.5; ny = yc + ys + 0.5; ny = yc + ys + 0.5; corner[aIndex].x = (int)nx; if( index == startIndex ) corner[aIndex].y = (int)ny; newPoly->Start( GetLayer(), (int)nx, (int)ny, GetHatchStyle() ); else newPoly->AppendCorner( (int)nx, (int)ny ); // Add new vertices unsigned int nVertices = 0; unsigned int nVertices = 0; for( unsigned int j = 0; j < aSegments; j++ ) for( unsigned int j = 0; j < segments; j++ ) { { nx = xc + cos( startAngle + (j+1)*deltaAngle )*aRadius + 0.5; nx = xc + cos( startAngle + (j+1)*deltaAngle )*radius + 0.5; ny = yc - sin( startAngle + (j+1)*deltaAngle )*aRadius + 0.5; ny = yc - sin( startAngle + (j+1)*deltaAngle )*radius + 0.5; InsertCorner( aIndex + nVertices, (int)nx, (int)ny ); newPoly->AppendCorner( (int)nx, (int)ny ); nVertices++; nVertices++; } } return nVertices; // Return the number of added vertices } } newPoly->Close(); CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) { CPolyLine* newPoly = new CPolyLine; unsigned int lena, lenb; newPoly->Copy( this ); for( unsigned int i = 0, index = 0; i < corner.size(); i++, index++ ) { if( i == 0 ) lena = GetEdgeLength( corner.size()-1 ); else lena = GetEdgeLength( i - 1 ); lenb = GetEdgeLength( i ); unsigned int radius = aRadius; double denom = sqrt( 2.0/( 1+GetCosine( i ) )-1 ); // Limit rounding distance to one half of an edge if( 0.5*lena*denom < radius ) radius = (unsigned int) ( 0.5 * (double) lena * denom ); if( 0.5*lenb*denom < radius ) radius = (unsigned int) ( 0.5 * (double) lenb * denom ); // Round this corner and keep tract of added vertices index += newPoly->Fillet( index, radius, aSegments ); } } return newPoly; return newPoly; } } Loading Loading @@ -1205,63 +1193,6 @@ int CPolyLine::GetEndContour( int ic ) } } unsigned int CPolyLine::GetEdgeLength( unsigned int aIndex ) { long xa, ya, xb, yb; xa = corner[aIndex].x; ya = corner[aIndex].y; if( aIndex == corner.size()-1 ) { xb = corner[0].x; yb = corner[0].y; } else { xb = corner[aIndex+1].x; yb = corner[aIndex+1].y; } return (unsigned int) sqrt( (double) (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) ); } double CPolyLine::GetCosine( unsigned int aIndex ) { int x1, y1; long xa, ya, xb, yb; x1 = corner[aIndex].x; y1 = corner[aIndex].y; if( aIndex == 0 ) { xa = corner[corner.size()-1].x - x1; ya = corner[corner.size()-1].y - y1; } else { xa = corner[aIndex-1].x - x1; ya = corner[aIndex-1].y - y1; } if( aIndex == corner.size() - 1 ) { xb = corner[0].x - x1; yb = corner[0].y - y1; } else { xb = corner[aIndex+1].x - x1; yb = corner[aIndex+1].y - y1; } double lena = sqrt( (double)xa*xa + ya*ya ); double lenb = sqrt( (double)xb*xb + yb*yb ); return ( xa*xb + ya*yb )/( lena*lenb ); } CRect CPolyLine::GetBounds() CRect CPolyLine::GetBounds() { { CRect r = GetCornerBounds(); CRect r = GetCornerBounds(); Loading polygon/PolyLine.h +4 −40 Original line number Original line Diff line number Diff line Loading @@ -132,15 +132,6 @@ public: void Close( int style = STRAIGHT, bool bDraw = false ); void Close( int style = STRAIGHT, bool bDraw = false ); void RemoveContour( int icont ); void RemoveContour( int icont ); /** * Function Chamfer * chamfers a corner. * @param aIndex is the corner index. * @param aDistance is the chamfering distance. * @return int - The number of segments added. */ int Chamfer( unsigned int aIndex, unsigned int aDistance ); /** /** * Function Chamfer * Function Chamfer * returns a chamfered version of a polygon. * returns a chamfered version of a polygon. Loading @@ -149,17 +140,6 @@ public: */ */ CPolyLine* Chamfer( unsigned int aDistance ); CPolyLine* Chamfer( unsigned int aDistance ); /** * Function Fillet * rounds a corner. * @param aIndex is the corner index. * @param aDistance is the fillet radius. * @param aSegments is the number of segments / 360 degrees. * @return int - The number of segments added. */ int Fillet( unsigned int aIndex, unsigned int aRadius, unsigned int aSegments ); /** /** * Function Fillet * Function Fillet * returns a filleted version of a polygon. * returns a filleted version of a polygon. Loading Loading @@ -200,22 +180,6 @@ public: int GetY( int ic ); int GetY( int ic ); int GetEndContour( int ic ); int GetEndContour( int ic ); /** * Function GetEdgeLength * returns the length of the edge starting at given corner index. * @param aIndex is the corner index. * @return unsigned int - the length of the edge. */ unsigned int GetEdgeLength( unsigned int aIndex ); /** * Function GetCosine * returns the cosine between the two edge vectors at a corner. * @param aIndex is the corner index. * @return double - the cosine value. */ double GetCosine( unsigned int aIndex ); int GetUtility( int ic ) { return corner[ic].utility; }; int GetUtility( int ic ) { return corner[ic].utility; }; void SetUtility( int ic, int utility ) { corner[ic].utility = utility; }; void SetUtility( int ic, int utility ) { corner[ic].utility = utility; }; int GetSideStyle( int is ); int GetSideStyle( int is ); Loading Loading
pcbnew/zones_by_polygon.cpp +2 −2 Original line number Original line Diff line number Diff line Loading @@ -65,7 +65,7 @@ void WinEDA_PcbFrame::Add_Similar_Zone( wxDC* DC, ZONE_CONTAINER* zone_container // Use the general event handle to set others params (like toolbar) */ // Use the general event handle to set others params (like toolbar) */ wxCommandEvent evt; wxCommandEvent evt; evt.SetId( ID_PCB_ZONES_BUTT ); evt.SetId( ID_PCB_ZONES_BUTT ); Process_Special_Functions( evt ); OnSelectTool( evt ); } } Loading @@ -91,7 +91,7 @@ void WinEDA_PcbFrame::Add_Zone_Cutout( wxDC* DC, ZONE_CONTAINER* zone_container // Use the general event handle to set others params (like toolbar) */ // Use the general event handle to set others params (like toolbar) */ wxCommandEvent evt; wxCommandEvent evt; evt.SetId( ID_PCB_ZONES_BUTT ); evt.SetId( ID_PCB_ZONES_BUTT ); Process_Special_Functions( evt ); OnSelectTool( evt ); } } Loading
polygon/PolyLine.cpp +153 −222 Original line number Original line Diff line number Diff line Loading @@ -907,141 +907,159 @@ void CPolyLine::RemoveContour( int icont ) } } int CPolyLine::Chamfer( unsigned int aIndex, unsigned int aDistance ) CPolyLine* CPolyLine::Chamfer( unsigned int aDistance ) { { int x1, y1; CPolyLine* newPoly = new CPolyLine; long xa, ya, xb, yb, nx, ny; if( !aDistance ) if( !aDistance ) return 0; { newPoly->Copy( this ); return newPoly; } x1 = corner[aIndex].x; for( int contour = 0; contour < GetNumContours(); contour++ ) y1 = corner[aIndex].y; { unsigned int startIndex = GetContourStart( contour ); unsigned int endIndex = GetContourEnd( contour ); for( unsigned int index = startIndex; index <= endIndex; index++ ) { int x1, y1, nx, ny; long long xa, ya, xb, yb; if( aIndex == 0 ) x1 = corner[index].x; y1 = corner[index].y; if( index == startIndex ) { { xa = corner[corner.size()-1].x - x1; xa = corner[endIndex].x - x1; ya = corner[corner.size()-1].y - y1; ya = corner[endIndex].y - y1; } } else else { { xa = corner[aIndex-1].x - x1; xa = corner[index-1].x - x1; ya = corner[aIndex-1].y - y1; ya = corner[index-1].y - y1; } } if( aIndex == corner.size()-1 ) if( index == endIndex ) { { xb = corner[0].x - x1; xb = corner[startIndex].x - x1; yb = corner[0].y - y1; yb = corner[startIndex].y - y1; } } else else { { xb = corner[aIndex+1].x - x1; xb = corner[index+1].x - x1; yb = corner[aIndex+1].y - y1; yb = corner[index+1].y - y1; } } // Move the first vertex into new position unsigned int lena = (unsigned int)sqrt( (double)(xa*xa + ya*ya) ); nx = (long) ( (double) (aDistance*xa)/sqrt( (double) (xa*xa + ya*ya) ) ); unsigned int lenb = (unsigned int)sqrt( (double)(xb*xb + yb*yb) ); ny = (long) ( (double) (aDistance*ya)/sqrt( (double) (xa*xa + ya*ya) ) ); unsigned int distance = aDistance; corner[aIndex].x = x1 + nx; corner[aIndex].y = y1 + ny; // Add one new vertex nx = (long) ( (double) (aDistance*xb)/sqrt( (double) (xb*xb + yb*yb) ) ); ny = (long) ( (double) (aDistance*yb)/sqrt( (double) (xb*xb + yb*yb) ) ); InsertCorner( aIndex, x1 + nx, y1 + ny ); return 1; // Added one vertex // 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; CPolyLine* CPolyLine::Chamfer( unsigned int aDistance ) nx = (int) ( (double) (distance*xa)/sqrt( (double) (xa*xa + ya*ya) ) ); { ny = (int) ( (double) (distance*ya)/sqrt( (double) (xa*xa + ya*ya) ) ); CPolyLine* newPoly = new CPolyLine; unsigned int lena, lenb; newPoly->Copy( this ); for( unsigned int i = 0, index = 0; i < corner.size(); i++, index++ ) if( index == startIndex ) { newPoly->Start( GetLayer(), x1 + nx, y1 + ny, GetHatchStyle() ); if( i == 0 ) lena = GetEdgeLength( corner.size()-1 ); else else lena = GetEdgeLength( i - 1 ); newPoly->AppendCorner( x1 + nx, y1 + ny ); lenb = GetEdgeLength( i ); unsigned int distance = aDistance; nx = (int) ( (double) (distance*xb)/sqrt( (double) (xb*xb + yb*yb) ) ); ny = (int) ( (double) (distance*yb)/sqrt( (double) (xb*xb + yb*yb) ) ); newPoly->AppendCorner( x1 + nx, y1 + ny ); } newPoly->Close(); } // Chamfer one half of an edge at most return newPoly; if( 0.5*lena < distance ) } distance = (unsigned int) 0.5*lena; if( 0.5*lenb < distance ) distance = (unsigned int) 0.5*lenb; // Chamfer this corner and keep tract of added vertices CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) index += newPoly->Chamfer( index, distance ); { } CPolyLine* newPoly = new CPolyLine; if( !aRadius ) { newPoly->Copy( this ); return newPoly; return newPoly; } } for( int contour = 0; contour < GetNumContours(); contour++ ) { unsigned int startIndex = GetContourStart( contour ); unsigned int endIndex = GetContourEnd( contour ); int CPolyLine::Fillet( unsigned int aIndex, unsigned int aRadius, for( unsigned int index = startIndex; index <= endIndex; index++ ) unsigned int aSegments ) { { int x1, y1; // Current vertex int x1, y1; // Current vertex int xa, ya; // Previous vertex long long xa, ya; // Previous vertex int xb, yb; // Next vertex long long xb, yb; // Next vertex double nx, ny; double nx, ny; if( !aRadius ) x1 = corner[index].x; return 0; y1 = corner[index].y; x1 = corner[aIndex].x; y1 = corner[aIndex].y; if( aIndex == 0 ) if( index == startIndex ) { { xa = corner[corner.size()-1].x - x1; xa = corner[endIndex].x - x1; ya = corner[corner.size()-1].y - y1; ya = corner[endIndex].y - y1; } } else else { { xa = corner[aIndex-1].x - x1; xa = corner[index-1].x - x1; ya = corner[aIndex-1].y - y1; ya = corner[index-1].y - y1; } } if( aIndex == corner.size()-1 ) if( index == endIndex ) { { xb = corner[0].x - x1; xb = corner[startIndex].x - x1; yb = corner[0].y - y1; yb = corner[startIndex].y - y1; } } else else { { xb = corner[aIndex+1].x - x1; xb = corner[index+1].x - x1; yb = corner[aIndex+1].y - y1; yb = corner[index+1].y - y1; } } double lena = sqrt( (double) (xa*xa + ya*ya) ); double lena = sqrt( (double) (xa*xa + ya*ya) ); double lenb = sqrt( (double) (xb*xb + yb*yb) ); double lenb = sqrt( (double) (xb*xb + yb*yb) ); double cosine = ( xa*xb + ya*yb )/( lena*lenb ); double cosine = ( xa*xb + ya*yb )/( lena*lenb ); unsigned int radius = aRadius; double denom = sqrt( 2.0/( 1+cosine )-1 ); // 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) // Calculate fillet arc absolute center point (xc, yx) double k = aRadius / sqrt( .5*( 1-cosine ) ); double k = radius / sqrt( .5*( 1-cosine ) ); double lenab = sqrt( ( xa/lena + xb/lenb )*( xa/lena + xb/lenb ) + double lenab = sqrt( ( xa/lena + xb/lenb )*( xa/lena + xb/lenb ) + ( ya/lena + yb/lenb )*( ya/lena + yb/lenb ) ); ( ya/lena + yb/lenb )*( ya/lena + yb/lenb ) ); double xc = x1 + k*( xa/lena + xb/lenb )/lenab; double xc = x1 + k*( xa/lena + xb/lenb )/lenab; double yc = y1 + k*( ya/lena + yb/lenb )/lenab; double yc = y1 + k*( ya/lena + yb/lenb )/lenab; // Calculate arc start and end vectors // Calculate arc start and end vectors k = aRadius / sqrt( 2/( 1+cosine )-1 ); k = radius / sqrt( 2/( 1+cosine )-1 ); double xs = x1 + k*xa/lena - xc; double xs = x1 + k*xa/lena - xc; double ys = y1 + k*ya/lena - yc; double ys = y1 + k*ya/lena - yc; double xe = x1 + k*xb/lenb - xc; double xe = x1 + k*xb/lenb - xc; double ye = y1 + k*yb/lenb - yc; double ye = y1 + k*yb/lenb - yc; // Cosine of arc angle // Cosine of arc angle double argument = ( xs*xe + ys*ye ) / ( aRadius*aRadius ); double argument = ( xs*xe + ys*ye ) / ( radius*radius ); if( argument < -1 ) // Just in case... if( argument < -1 ) // Just in case... argument = -1; argument = -1; Loading @@ -1055,63 +1073,33 @@ int CPolyLine::Fillet( unsigned int aIndex, unsigned int aRadius, if( tempSegments - (int)tempSegments > 0 ) if( tempSegments - (int)tempSegments > 0 ) tempSegments++; tempSegments++; aSegments = (unsigned int) tempSegments; unsigned int segments = (unsigned int) tempSegments; double deltaAngle = arcAngle / aSegments; double deltaAngle = arcAngle / segments; double startAngle = atan2( -ys, xs ); double startAngle = atan2( -ys, xs ); // Flip arc for inner corners // Flip arc for inner corners if( xa*yb - ya*xb <= 0 ) if( xa*yb - ya*xb <= 0 ) deltaAngle *= -1; deltaAngle *= -1; // Move first vertex into new position nx = xc + xs + 0.5; nx = xc + xs + 0.5; ny = yc + ys + 0.5; ny = yc + ys + 0.5; corner[aIndex].x = (int)nx; if( index == startIndex ) corner[aIndex].y = (int)ny; newPoly->Start( GetLayer(), (int)nx, (int)ny, GetHatchStyle() ); else newPoly->AppendCorner( (int)nx, (int)ny ); // Add new vertices unsigned int nVertices = 0; unsigned int nVertices = 0; for( unsigned int j = 0; j < aSegments; j++ ) for( unsigned int j = 0; j < segments; j++ ) { { nx = xc + cos( startAngle + (j+1)*deltaAngle )*aRadius + 0.5; nx = xc + cos( startAngle + (j+1)*deltaAngle )*radius + 0.5; ny = yc - sin( startAngle + (j+1)*deltaAngle )*aRadius + 0.5; ny = yc - sin( startAngle + (j+1)*deltaAngle )*radius + 0.5; InsertCorner( aIndex + nVertices, (int)nx, (int)ny ); newPoly->AppendCorner( (int)nx, (int)ny ); nVertices++; nVertices++; } } return nVertices; // Return the number of added vertices } } newPoly->Close(); CPolyLine* CPolyLine::Fillet( unsigned int aRadius, unsigned int aSegments ) { CPolyLine* newPoly = new CPolyLine; unsigned int lena, lenb; newPoly->Copy( this ); for( unsigned int i = 0, index = 0; i < corner.size(); i++, index++ ) { if( i == 0 ) lena = GetEdgeLength( corner.size()-1 ); else lena = GetEdgeLength( i - 1 ); lenb = GetEdgeLength( i ); unsigned int radius = aRadius; double denom = sqrt( 2.0/( 1+GetCosine( i ) )-1 ); // Limit rounding distance to one half of an edge if( 0.5*lena*denom < radius ) radius = (unsigned int) ( 0.5 * (double) lena * denom ); if( 0.5*lenb*denom < radius ) radius = (unsigned int) ( 0.5 * (double) lenb * denom ); // Round this corner and keep tract of added vertices index += newPoly->Fillet( index, radius, aSegments ); } } return newPoly; return newPoly; } } Loading Loading @@ -1205,63 +1193,6 @@ int CPolyLine::GetEndContour( int ic ) } } unsigned int CPolyLine::GetEdgeLength( unsigned int aIndex ) { long xa, ya, xb, yb; xa = corner[aIndex].x; ya = corner[aIndex].y; if( aIndex == corner.size()-1 ) { xb = corner[0].x; yb = corner[0].y; } else { xb = corner[aIndex+1].x; yb = corner[aIndex+1].y; } return (unsigned int) sqrt( (double) (xb-xa)*(xb-xa) + (yb-ya)*(yb-ya) ); } double CPolyLine::GetCosine( unsigned int aIndex ) { int x1, y1; long xa, ya, xb, yb; x1 = corner[aIndex].x; y1 = corner[aIndex].y; if( aIndex == 0 ) { xa = corner[corner.size()-1].x - x1; ya = corner[corner.size()-1].y - y1; } else { xa = corner[aIndex-1].x - x1; ya = corner[aIndex-1].y - y1; } if( aIndex == corner.size() - 1 ) { xb = corner[0].x - x1; yb = corner[0].y - y1; } else { xb = corner[aIndex+1].x - x1; yb = corner[aIndex+1].y - y1; } double lena = sqrt( (double)xa*xa + ya*ya ); double lenb = sqrt( (double)xb*xb + yb*yb ); return ( xa*xb + ya*yb )/( lena*lenb ); } CRect CPolyLine::GetBounds() CRect CPolyLine::GetBounds() { { CRect r = GetCornerBounds(); CRect r = GetCornerBounds(); Loading
polygon/PolyLine.h +4 −40 Original line number Original line Diff line number Diff line Loading @@ -132,15 +132,6 @@ public: void Close( int style = STRAIGHT, bool bDraw = false ); void Close( int style = STRAIGHT, bool bDraw = false ); void RemoveContour( int icont ); void RemoveContour( int icont ); /** * Function Chamfer * chamfers a corner. * @param aIndex is the corner index. * @param aDistance is the chamfering distance. * @return int - The number of segments added. */ int Chamfer( unsigned int aIndex, unsigned int aDistance ); /** /** * Function Chamfer * Function Chamfer * returns a chamfered version of a polygon. * returns a chamfered version of a polygon. Loading @@ -149,17 +140,6 @@ public: */ */ CPolyLine* Chamfer( unsigned int aDistance ); CPolyLine* Chamfer( unsigned int aDistance ); /** * Function Fillet * rounds a corner. * @param aIndex is the corner index. * @param aDistance is the fillet radius. * @param aSegments is the number of segments / 360 degrees. * @return int - The number of segments added. */ int Fillet( unsigned int aIndex, unsigned int aRadius, unsigned int aSegments ); /** /** * Function Fillet * Function Fillet * returns a filleted version of a polygon. * returns a filleted version of a polygon. Loading Loading @@ -200,22 +180,6 @@ public: int GetY( int ic ); int GetY( int ic ); int GetEndContour( int ic ); int GetEndContour( int ic ); /** * Function GetEdgeLength * returns the length of the edge starting at given corner index. * @param aIndex is the corner index. * @return unsigned int - the length of the edge. */ unsigned int GetEdgeLength( unsigned int aIndex ); /** * Function GetCosine * returns the cosine between the two edge vectors at a corner. * @param aIndex is the corner index. * @return double - the cosine value. */ double GetCosine( unsigned int aIndex ); int GetUtility( int ic ) { return corner[ic].utility; }; int GetUtility( int ic ) { return corner[ic].utility; }; void SetUtility( int ic, int utility ) { corner[ic].utility = utility; }; void SetUtility( int ic, int utility ) { corner[ic].utility = utility; }; int GetSideStyle( int is ); int GetSideStyle( int is ); Loading