From b3b9c1217335cd59cd78af113b9499cca8afc304 Mon Sep 17 00:00:00 2001 From: charras Date: Sun, 23 Nov 2008 16:31:35 +0000 Subject: [PATCH] code cleaning --- pcbnew/zones_polygons_test_connections.cpp | 2 - polygon/math_for_graphics.cpp | 451 --------------------- polygon/math_for_graphics.h | 54 --- polygon/polygon_test_point_inside.cpp | 82 ++-- 4 files changed, 42 insertions(+), 547 deletions(-) diff --git a/pcbnew/zones_polygons_test_connections.cpp b/pcbnew/zones_polygons_test_connections.cpp index 3130e4b454..70c60e4e86 100644 --- a/pcbnew/zones_polygons_test_connections.cpp +++ b/pcbnew/zones_polygons_test_connections.cpp @@ -153,7 +153,6 @@ void BOARD::Test_Connections_To_Copper_Areas( int aNetcode ) if( (old_subnet > 0) && (old_subnet != subnet) ) // Merge previous subnet with the current { -//printf(" merge subnets: %d et %d (%d)\n", old_subnet, subnet,item->Type()); for( unsigned jj = 0; jj < Candidates.size(); jj++ ) { BOARD_CONNECTED_ITEM* item_to_merge = Candidates[jj]; @@ -233,7 +232,6 @@ void Merge_SubNets_Connected_By_CopperAreas( BOARD* aPcb, int aNetcode ) if( !found ) // No zone with this netcode, therefore no connection by zone return; -printf(" Merge_SubNets net = %d\n", aNetcode); std::vector Candidates; // list of pads and tracks candidates to test. // Build a list of candidates connected to the net: diff --git a/polygon/math_for_graphics.cpp b/polygon/math_for_graphics.cpp index ccd5b182fe..81d3ad303f 100644 --- a/polygon/math_for_graphics.cpp +++ b/polygon/math_for_graphics.cpp @@ -13,143 +13,6 @@ using namespace std; #include "PolyLine.h" -// function to find inflection-pont to create a "dogleg" of two straight-line segments -// where one segment is vertical or horizontal and the other is at 45 degrees or 90 degrees -// enter with: -// pi = start point -// pf = end point -// mode = IM_90_45 or IM_45_90 or IM_90 -// -CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode ) -{ - CPoint p = pi; - if( mode == IM_NONE ) - return p; - - int dx = pf.x - pi.x; - int dy = pf.y - pi.y; - if( dx == 0 || dy == 0 || abs(dx) == abs(dy) ) - { - // only one segment needed - } - else - { - if( abs(dy) > abs(dx) ) - { - // vertical > horizontal - if( mode == IM_90 ) - { - p.x = pi.x; - p.y = pf.y; - } - else if( mode == IM_45_90 || mode == IM_90_45 ) - { - int vert; // length of vertical line needed - if( dy > 0 ) - vert = dy - abs(dx); // positive - else - vert = dy + abs(dx); // negative - if( mode == IM_90_45 ) - p.y = pi.y + vert; - else if( mode == IM_45_90 ) - { - p.y = pf.y - vert; - p.x = pf.x; - } - } - else - wxASSERT(0); - } - else - { - // horizontal > vertical - if( mode == IM_90 ) - { - p.x = pf.x; - p.y = pi.y; - } - else if( mode == IM_45_90 || mode == IM_90_45 ) - { - int hor; // length of horizontal line needed - if( dx > 0 ) - hor = dx - abs(dy); // positive - else - hor = dx + abs(dy); // negative - if( mode == IM_90_45 ) - p.x = pi.x + hor; - else if( mode == IM_45_90 ) - { - p.x = pf.x - hor; - p.y = pf.y; - } - } - else - wxASSERT(0); - } - } - return p; -} - -// -// function to rotate a point clockwise about another point -// currently, angle must be 0, 90, 180 or 270 -// -void RotatePoint( CPoint *p, int angle, CPoint org ) -{ - if( angle == 90 ) - { - int tempy = org.y + (org.x - p->x); - p->x = org.x + (p->y - org.y); - p->y = tempy; - } - else if( angle > 90 ) - { - for( int i=0; i<(angle/90); i++ ) - RotatePoint( p, 90, org ); - } -} - -// function to rotate a rectangle clockwise about a point -// angle must be 0, 90, 180 or 270 -// on exit, r->top > r.bottom, r.right > r.left -// -void RotateRect( CRect *r, int angle, CPoint org ) -{ - CRect tr; - if( angle == 90 ) - { - tr.left = org.x + (r->bottom - org.y); - tr.right = org.x + (r->top - org.y); - tr.top = org.y + (org.x - r->right); - tr.bottom = org.y + (org.x - r->left); - if( tr.left > tr.right ) - { - int temp = tr.right; - tr.left = tr.right; - tr.left = temp; - } - if( tr.left > tr.right ) - { - int temp = tr.right; - tr.left = tr.right; - tr.left = temp; - } - if( tr.bottom > tr.top ) - { - int temp = tr.bottom; - tr.bottom = tr.top; - tr.top = temp; - } - } - else if( angle > 90 ) - { - tr = *r; - for( int i=0; i<(angle/90); i++ ) - RotateRect( &tr, 90, org ); - } - *r = tr; -} - // test for hit on line segment // i.e. cursor within a given distance from segment // enter with: x,y = cursor coords @@ -206,15 +69,6 @@ int TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist ) } -// find intersection between y = a + bx and y = c + dx; -// -int FindLineIntersection( double a, double b, double c, double d, double * x, double * y ) -{ - *x = (c-a)/(b-d); - *y = a + b*(*x); - return 0; -} - // set EllipseKH struct to describe the ellipse for an arc // int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * el ) @@ -875,250 +729,6 @@ bool FindLineEllipseIntersections( double a, double b, double c, double d, doubl } -#if 0 -// draw a straight line or an arc between xi,yi and xf,yf -// -void DrawArc( CDC * pDC, int shape, int xxi, int yyi, int xxf, int yyf, bool bMeta ) -{ - int xi, yi, xf, yf; - if( shape == DL_LINE || xxi == xxf || yyi == yyf ) - { - // draw straight line - pDC->MoveTo( xxi, yyi ); - pDC->LineTo( xxf, yyf ); - } - else if( shape == DL_ARC_CCW || shape == DL_ARC_CW ) - { - // set endpoints so we can always draw counter-clockwise arc - if( shape == DL_ARC_CW ) - { - xi = xxf; - yi = yyf; - xf = xxi; - yf = yyi; - } - else - { - xi = xxi; - yi = yyi; - xf = xxf; - yf = yyf; - } - pDC->MoveTo( xi, yi ); - if( xf > xi && yf > yi ) - { - // quadrant 1 - int w = (xf-xi)*2; - int h = (yf-yi)*2; - if( !bMeta ) - pDC->Arc( xf-w, yi+h, xf, yi, - xi, yi, xf, yf ); - else - pDC->Arc( xf-w, yi, xf, yi+h, - xf, yf, xi, yi ); - } - else if( xf < xi && yf > yi ) - { - // quadrant 2 - int w = -(xf-xi)*2; - int h = (yf-yi)*2; - if( !bMeta ) - pDC->Arc( xi-w, yf, xi, yf-h, - xi, yi, xf, yf ); - else - pDC->Arc( xi-w, yf-h, xi, yf, - xf, yf, xi, yi ); - } - else if( xf < xi && yf < yi ) - { - // quadrant 3 - int w = -(xf-xi)*2; - int h = -(yf-yi)*2; - if( !bMeta ) - pDC->Arc( xf, yi, xf+w, yi-h, - xi, yi, xf, yf ); - else - pDC->Arc( xf, yi-h, xf+w, yi, - xf, yf, xi, yi ); - } - else if( xf > xi && yf < yi ) - { - // quadrant 4 - int w = (xf-xi)*2; - int h = -(yf-yi)*2; - if( !bMeta ) - pDC->Arc( xi, yf+h, xi+w, yf, - xi, yi, xf, yf ); - else - pDC->Arc( xi, yf, xi+w, yf+h, - xf, yf, xi, yi ); - } - pDC->MoveTo( xxf, yyf ); - } - else - wxASSERT(0); // oops -} - -#endif - -// Get arrays of circles, rects and line segments to represent pad -// for purposes of drawing pad or calculating clearances -// margins of circles and line segments represent pad outline -// circles and rects are used to find points inside pad -// -void GetPadElements( int type, int x, int y, int wid, int len, int radius, int angle, - int * nr, my_rect r[], int * nc, my_circle c[], int * ns, my_seg s[] ) -{ - *nc = 0; - *nr = 0; - *ns = 0; - if( type == PAD_ROUND ) - { - *nc = 1; - c[0] = my_circle(x,y,wid/2); - return; - } - if( type == PAD_SQUARE ) - { - *nr = 1; - r[0] = my_rect(x-wid/2, y-wid/2,x+wid/2, y+wid/2); - *ns = 4; - s[0] = my_seg(x-wid/2, y+wid/2,x+wid/2, y+wid/2); // top - s[1] = my_seg(x-wid/2, y-wid/2,x+wid/2, y-wid/2); // bottom - s[2] = my_seg(x-wid/2, y-wid/2,x-wid/2, y+wid/2); // left - s[3] = my_seg(x+wid/2, y-wid/2,x+wid/2, y+wid/2); // right - return; - } - if( type == PAD_OCTAGON ) - { - const double pi = 3.14159265359; - *nc = 1; // circle represents inside of polygon - c[0] = my_circle(x, y, wid/2); - *ns = 8; // now create sides of polygon - double theta = pi/8.0; - double radius = 0.5*(double)wid/cos(theta); - double last_x = x + radius*cos(theta); - double last_y = y + radius*sin(theta); - for( int is=0; is<8; is++ ) - { - theta += pi/4.0; - double dx = x + radius*cos(theta); - double dy = y + radius*sin(theta); - s[is] = my_seg((int) last_x, (int) last_y, x, y); - last_x = dx; - last_y = dy; - } - return; - } - // - int h; - int v; - if( angle == 90 || angle == 270 ) - { - h = wid; - v = len; - } - else - { - v = wid; - h = len; - } - if( type == PAD_RECT ) - { - *nr = 1; - r[0] = my_rect(x-h/2, y-v/2, x+h/2, y+v/2); - *ns = 4; - s[0] = my_seg(x-h/2, y+v/2,x+h/2, y+v/2); // top - s[1] = my_seg(x-h/2, y-v/2,x+h/2, y-v/2); // bottom - s[2] = my_seg(x-h/2, y-v/2,x-h/2, y+v/2); // left - s[3] = my_seg(x+h/2, y-v/2,x+h/2, y+v/2); // right - return; - } - if( type == PAD_RRECT ) - { - *nc = 4; - c[0] = my_circle(x-h/2+radius, y-v/2+radius, radius); // bottom left circle - c[1] = my_circle(x+h/2-radius, y-v/2+radius, radius); // bottom right circle - c[2] = my_circle(x-h/2+radius, y+v/2-radius, radius); // top left circle - c[3] = my_circle(x+h/2-radius, y+v/2-radius, radius); // top right circle - *ns = 4; - s[0] = my_seg(x-h/2+radius, y+v/2, x+h/2-radius, y+v/2); // top - s[1] = my_seg(x-h/2+radius, y-v/2, x+h/2-radius, y+v/2); // bottom - s[2] = my_seg(x-h/2, y-v/2+radius, x-h/2, y+v/2-radius); // left - s[3] = my_seg(x+h/2, y-v/2+radius, x+h/2, y+v/2-radius); // right - return; - } - if( type == PAD_OVAL ) - { - if( h > v ) - { - // horizontal - *nc = 2; - c[0] = my_circle(x-h/2+v/2, y, v/2); // left circle - c[1] = my_circle(x+h/2-v/2, y, v/2); // right circle - *nr = 1; - r[0] = my_rect(x-h/2+v/2, y-v/2, x+h/2-v/2, y+v/2); - *ns = 2; - s[0] = my_seg(x-h/2+v/2, y+v/2, x+h/2-v/2, y+v/2); // top - s[1] = my_seg(x-h/2+v/2, y-v/2, x+h/2-v/2, y-v/2); // bottom - } - else - { - // vertical - *nc = 2; - c[0] = my_circle(x, y+v/2-h/2, h/2); // top circle - c[1] = my_circle(x, y-v/2+h/2, h/2); // bottom circle - *nr = 1; - r[0] = my_rect(x-h/2, y-v/2+h/2, x+h/2, y+v/2-h/2); - *ns = 2; - s[0] = my_seg(x-h/2, y-v/2+h/2, x-h/2, y+v/2-h/2); // left - s[1] = my_seg(x+h/2, y-v/2+h/2, x+h/2, y+v/2-h/2); // left - } - return; - } - wxASSERT(0); -} - -// Find distance from a staright line segment to a pad -// -int GetClearanceBetweenSegmentAndPad( int x1, int y1, int x2, int y2, int w, - int type, int x, int y, int wid, int len, int radius, int angle ) -{ - if( type == PAD_NONE ) - return INT_MAX; - else - { - int nc, nr, ns; - my_circle c[4]; - my_rect r[2]; - my_seg s[8]; - GetPadElements( type, x, y, wid, len, radius, angle, - &nr, r, &nc, c, &ns, s ); - // first test for endpoints of line segment in rectangle - for( int ir=0; ir= r[ir].xlo && x1 <= r[ir].xhi && y1 >= r[ir].ylo && y1 <= r[ir].yhi ) - return 0; - if( x2 >= r[ir].xlo && x2 <= r[ir].xhi && y2 >= r[ir].ylo && y2 <= r[ir].yhi ) - return 0; - } - // now get distance from elements of pad outline - int dist = INT_MAX; - for( int ic=0; ic DBL_MAX/10, assume vertical line at x = a // returns closest point on line in xp, yp diff --git a/polygon/math_for_graphics.h b/polygon/math_for_graphics.h index 659dd03cc5..83340870a2 100644 --- a/polygon/math_for_graphics.h +++ b/polygon/math_for_graphics.h @@ -19,56 +19,10 @@ typedef struct EllipseTag double theta1, theta2; // start and end angle for arc } EllipseKH; -const CPoint zero(0,0); - -class my_circle { -public: - my_circle(){}; - my_circle( int xx, int yy, int rr ) - { - x = xx; - y = yy; - r = rr; - }; - int x, y, r; -}; - -class my_rect { -public: - my_rect(){}; - my_rect( int xi, int yi, int xf, int yf ) - { - xlo = MIN(xi,xf); - xhi = MAX(xi,xf); - ylo = MIN(yi,yf); - yhi = MAX(yi,yf); - }; - int xlo, ylo, xhi, yhi; -}; - -class my_seg { -public: - my_seg(){}; - my_seg( int xxi, int yyi, int xxf, int yyf ) - { - xi = xxi; - yi = yyi; - xf = xxf; - yf = yyf; - }; - int xi, yi, xf, yf; -}; // math stuff for graphics -#if 0 -void DrawArc( CDC * pDC, int shape, int xxi, int yyi, int xxf, int yyf, bool bMeta=FALSE ); -#endif - bool Quadratic( double a, double b, double c, double *x1, double *x2 ); -void RotatePoint( CPoint *p, int angle, CPoint org ); -void RotateRect( CRect *r, int angle, CPoint org ); int TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist ); -int FindLineIntersection( double a, double b, double c, double d, double * x, double * y ); int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int yf, int style, double * x1, double * y1, double * x2, double * y2, double * dist=NULL ); int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, @@ -79,13 +33,6 @@ bool FindVerticalLineEllipseIntersections( double a, double b, double x, double bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y1f, int x2i, int y2i, int x2f, int y2f, int * x=NULL, int * y=NULL, double * dist=NULL ); -void GetPadElements( int type, int x, int y, int wid, int len, int radius, int angle, - int * nr, my_rect r[], int * nc, my_circle c[], int * ns, my_seg s[] ); -int GetClearanceBetweenPads( int type1, int x1, int y1, int w1, int l1, int r1, int angle1, - int type2, int x2, int y2, int w2, int l2, int r2, int angle2 ); -int GetClearanceBetweenSegmentAndPad( int x1, int y1, int x2, int y2, int w, - int type, int x, int y, int wid, int len, - int radius, int angle ); int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, int w1, int x2i, int y2i, int x2f, int y2f, int style2, int w2, int max_cl, int * x, int * y ); @@ -104,5 +51,4 @@ double Distance( int x1, int y1, int x2, int y2 ); int GetArcIntersections( EllipseKH * el1, EllipseKH * el2, double * x1=NULL, double * y1=NULL, double * x2=NULL, double * y2=NULL ); -CPoint GetInflectionPoint( CPoint pi, CPoint pf, int mode ); diff --git a/polygon/polygon_test_point_inside.cpp b/polygon/polygon_test_point_inside.cpp index 167d4a0c26..74e18eac1e 100644 --- a/polygon/polygon_test_point_inside.cpp +++ b/polygon/polygon_test_point_inside.cpp @@ -15,6 +15,10 @@ using namespace std; * At each crossing, the ray switches between inside and outside. * If odd count, the test point is inside the polygon * This is called the Jordan curve theorem, or sometimes referred to as the "even-odd" test. + * Take care to starting and ending points of segments outlines: + * Only one must be used because the startingpoint of a segemnt is also the ending point of the previous. + * And we do no use twice the same segment, so we do NOT use both starting and ending points of segments. + * So we must use starting point but not ending point of each segment when calculating intersections */ /* 2 versions are given. @@ -22,7 +26,7 @@ using namespace std; * the first version is for explanations and tests (used to test the second version) * both use the same algorithm. */ -#if 1 +#if 0 /* This text and the algorithm come from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html * @@ -291,7 +295,6 @@ bool TestPointInsidePolygon( std::vector aPolysList, /** Function TestPointInsidePolygon * test if a point is inside or outside a polygon. - * if a point is on a outline segment, it is considered outside the polygon * the polygon must have only lines (not arcs) for outlines. * Use TestPointInside or TestPointInsideContour for more complex polygons * @param aPolysList: the list of polygons @@ -301,55 +304,54 @@ bool TestPointInsidePolygon( std::vector aPolysList, * @return true if the point is inside, false for outside */ { - #define OUTSIDE_IF_ON_SIDE 0 // = 1 if we consider point on a side outside the polygon - // define line passing through (x,y), with slope = 0 (horizontal line) - // get intersection points - // count intersection points to right of (x,y), if odd (x,y) is inside polyline - int xx, yy; - double slope = 0; // Using an horizontal line. - double a = refy - slope * refx; + // count intersection points to right of (refx,refy), if odd (refx,refy) is inside polyline int ics, ice; bool inside = false; // find all intersection points of line with polyline sides for( ics = istart, ice = iend; ics <= iend; ice = ics++ ) { - double intersectx1, intersecty1, intersectx2, intersecty2; - int ok; - ok = FindLineSegmentIntersection( a, slope, - aPolysList[ics].x, aPolysList[ics].y, - aPolysList[ice].x, aPolysList[ice].y, - CPolyLine::STRAIGHT, - &intersectx1, &intersecty1, - &intersectx2, &intersecty2 ); + int seg_startX = aPolysList[ics].x; + int seg_startY = aPolysList[ics].y; + int seg_endX = aPolysList[ice].x; + int seg_endY = aPolysList[ice].y; - /* FindLineSegmentIntersection() returns 0, 1 or 2 coordinates (ok = 0, 1, 2) - * for straight line segments, only 0 or 1 are possible - * (2 intersections points are possible only with arcs - */ - if( ok ) // Intersection found - { - xx = (int) intersectx1; - yy = (int) intersecty1; + /* Trivial cases: skip if ref above or below the segment to test + * Note: end point segment is skipped, because we do not test twice the same point: + * If the start point of segments is tested, the end point must be skipped, because + * this is also the starting point of the next segment + */ + // segment above ref point: skip + if( ( seg_startY > refy ) && (seg_endY > refy ) ) + continue; - /* if the intersection point is on the start point of the current segment, - * do not count it, - * because it was already counted, as ending point of the previous segment - */ - if( xx == aPolysList[ics].x && yy == aPolysList[ics].y ) - continue; -#if OUTSIDE_IF_ON_SIDE - if( xx == refx && yy == refy ) - return false; // (x,y) is on a side, call it outside - else -#endif - if( xx > refx ) - inside = not inside; - } + // segment below ref point, or its end on ref point: skip + // Note: also we skip vertical segments + // So points on vertical segments outlines are seen as outside the polygon + if( ( seg_startY <= refy ) && (seg_endY <= refy ) ) + continue; + + /* refy is between seg_startY and seg_endY. + * see if an horizontal line from refx is intersecting the segment + */ + + // calculate the x position of the intersection of this segment and the semi infinite line + // this is more easier if we move the X,Y axis origin to the segment start point: + seg_endX -= seg_startX; + seg_endY -= seg_startY; + double newrefx = (double)(refx - seg_startX); + double newrefy = (double) (refy - seg_startY); + // Now calculate the x intersection coordinate of the line from (0,0) to (seg_endX,seg_endY) + // with the horizontal line at the new refy position + // the line slope is slope = seg_endY/seg_endX; + // and the x pos relative to the new origin is intersec_x = refy/slope + // Note: because vertical segments are skipped, slope exists (seg_end_y not O) + double intersec_x = newrefy * seg_endX / seg_endY; + if( newrefx < intersec_x ) // Intersection found with the semi-infinite line from -infinite to refx + inside = not inside; } return inside; } - #endif