/* * Function Distance * Calculates the distance between a segment and a polygon (with holes): * param aStart is the starting point of the segment. * param aEnd is the ending point of the segment. * param aWidth is the width of the segment. * return distance between the segment and outline. * 0 if segment intersects or is inside */ int CPolyLine::Distance( wxPoint aStart, wxPoint aEnd, int aWidth ) { // We calculate the min dist between the segment and each outline segment // However, if the segment to test is inside the outline, and does not cross // any edge, it can be seen outside the polygon. // Therefore test if a segment end is inside ( testing only one end is enough ) if( TestPointInside( aStart.x, aStart.y ) ) return 0; int distance = INT_MAX; int polycount = GetContoursCount(); for( int icont = 0; icont < polycount; icont++ ) { int ic_start = GetContourStart( icont ); int ic_end = GetContourEnd( icont ); // now test spacing between area outline and segment for( int ic2 = ic_start; ic2 <= ic_end; ic2++ ) { int bx1 = GetX( ic2 ); int by1 = GetY( ic2 ); int bx2, by2; if( ic2 == ic_end ) { bx2 = GetX( ic_start ); by2 = GetY( ic_start ); } else { bx2 = GetX( ic2 + 1 ); by2 = GetY( ic2 + 1 ); } int d = GetClearanceBetweenSegments( bx1, by1, bx2, by2, 0, aStart.x, aStart.y, aEnd.x, aEnd.y, aWidth, 1, // min clearance, should be > 0 NULL, NULL ); if( distance > d ) distance = d; if( distance <= 0 ) return 0; } } return distance; }
/* * Function Distance * Calculates the distance between a point and polygon (with holes): * param aPoint is the coordinate of the point. * return distance between the point and outline. * 0 if the point is inside */ int CPolyLine::Distance( const wxPoint& aPoint ) { // We calculate the dist between the point and each outline segment // If the point is inside the outline, the dist is 0. if( TestPointInside( aPoint.x, aPoint.y ) ) return 0; int distance = INT_MAX; int polycount = GetContoursCount(); for( int icont = 0; icont < polycount; icont++ ) { int ic_start = GetContourStart( icont ); int ic_end = GetContourEnd( icont ); // now test spacing between area outline and segment for( int ic2 = ic_start; ic2 <= ic_end; ic2++ ) { int bx1 = GetX( ic2 ); int by1 = GetY( ic2 ); int bx2, by2; if( ic2 == ic_end ) { bx2 = GetX( ic_start ); by2 = GetY( ic_start ); } else { bx2 = GetX( ic2 + 1 ); by2 = GetY( ic2 + 1 ); } int d = KiROUND( GetPointToLineSegmentDistance( aPoint.x, aPoint.y, bx1, by1, bx2, by2 ) ); if( distance > d ) distance = d; if( distance <= 0 ) return 0; } } return distance; }
// Use the General Polygon Clipping Library to clip contours // If this results in new polygons, return them as CArray p // If bRetainArcs == TRUE, try to retain arcs in polys // Returns number of external contours, or -1 if error // int CPolyLine::NormalizeWithGpc( CArray<CPolyLine*> * pa, BOOL bRetainArcs ) { CArray<CArc> arc_array; if( bRetainArcs ) MakeGpcPoly( -1, &arc_array ); else MakeGpcPoly( -1, NULL ); Undraw(); // now, recreate poly // first, find outside contours and create new CPolyLines if necessary int n_ext_cont = 0; for( int ic=0; ic<m_gpc_poly->num_contours; ic++ ) { if( !(m_gpc_poly->hole)[ic] ) { if( n_ext_cont == 0 ) { // first external contour, replace this poly corner.RemoveAll(); side_style.RemoveAll(); m_ncorners = 0; for( int i=0; i<m_gpc_poly->contour[ic].num_vertices; i++ ) { int x = ((m_gpc_poly->contour)[ic].vertex)[i].x; int y = ((m_gpc_poly->contour)[ic].vertex)[i].y; if( i==0 ) Start( m_layer, m_w, m_sel_box, x, y, m_hatch, &m_id, m_ptr ); else AppendCorner( x, y, STRAIGHT, FALSE ); } Close(); n_ext_cont++; } else if( pa ) { // next external contour, create new poly CPolyLine * poly = new CPolyLine; pa->SetSize(n_ext_cont); // put in array (*pa)[n_ext_cont-1] = poly; for( int i=0; i<m_gpc_poly->contour[ic].num_vertices; i++ ) { int x = ((m_gpc_poly->contour)[ic].vertex)[i].x; int y = ((m_gpc_poly->contour)[ic].vertex)[i].y; if( i==0 ) poly->Start( m_layer, m_w, m_sel_box, x, y, m_hatch, &m_id, m_ptr ); else poly->AppendCorner( x, y, STRAIGHT, FALSE ); } poly->Close( STRAIGHT, FALSE ); n_ext_cont++; } } } // now add cutouts to the CPolyLine(s) for( int ic=0; ic<m_gpc_poly->num_contours; ic++ ) { if( (m_gpc_poly->hole)[ic] ) { CPolyLine * ext_poly = NULL; if( n_ext_cont == 1 ) { ext_poly = this; } else { // find the polygon that contains this hole for( int i=0; i<m_gpc_poly->contour[ic].num_vertices; i++ ) { int x = ((m_gpc_poly->contour)[ic].vertex)[i].x; int y = ((m_gpc_poly->contour)[ic].vertex)[i].y; if( TestPointInside( x, y ) ) ext_poly = this; else { for( int ext_ic=0; ext_ic<n_ext_cont-1; ext_ic++ ) { if( (*pa)[ext_ic]->TestPointInside( x, y ) ) { ext_poly = (*pa)[ext_ic]; break; } } } if( ext_poly ) break; } } if( !ext_poly ) ASSERT(0); for( int i=0; i<m_gpc_poly->contour[ic].num_vertices; i++ ) { int x = ((m_gpc_poly->contour)[ic].vertex)[i].x; int y = ((m_gpc_poly->contour)[ic].vertex)[i].y; ext_poly->AppendCorner( x, y, STRAIGHT, FALSE ); } ext_poly->Close( STRAIGHT, FALSE ); } } if( bRetainArcs ) RestoreArcs( &arc_array, pa ); FreeGpcPoly(); return n_ext_cont; }