code cleaning

This commit is contained in:
charras 2008-11-23 16:31:35 +00:00
parent 237a8539fc
commit b3b9c12173
4 changed files with 42 additions and 547 deletions

View File

@ -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 <BOARD_CONNECTED_ITEM*> Candidates; // list of pads and tracks candidates to test.
// Build a list of candidates connected to the net:

View File

@ -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<nr; ir++ )
{
if( x1 >= 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<nc; ic++ )
{
int d = (int)GetPointToLineSegmentDistance( c[ic].x, c[ic].y, x1, y1, x2, y2 ) - c[ic].r - w/2;
dist = min(dist,d);
}
for( int is=0; is<ns; is++ )
{
double d;
TestForIntersectionOfStraightLineSegments( s[is].xi, s[is].yi, s[is].xf, s[is].yf,
x1, y1, x2, y2, NULL, NULL, &d );
dist = min(dist, (int)d - w/2);
}
return max(0,dist);
}
}
// Get clearance between 2 segments
// Returns point in segment closest to other segment in x, y
@ -1300,67 +910,6 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
// Find clearance between pads
// For each pad:
// type = PAD_ROUND, PAD_SQUARE, etc.
// x, y = center position
// w, l = width and length
// r = corner radius
// angle = 0 or 90 (if 0, pad length is along x-axis)
//
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 )
{
if( type1 == PAD_NONE )
return INT_MAX;
if( type2 == PAD_NONE )
return INT_MAX;
int dist = INT_MAX;
int nr, nc, ns, nrr, ncc, nss;
my_rect r[2], rr[2];
my_circle c[4], cc[4];
my_seg s[8], ss[8];
GetPadElements( type1, x1, y1, w1, l1, r1, angle1,
&nr, r, &nc, c, &ns, s );
GetPadElements( type2, x2, y2, w2, l2, r2, angle2,
&nrr, rr, &ncc, cc, &nss, ss );
// now find distance from every element of pad1 to every element of pad2
for( int ic=0; ic<nc; ic++ )
{
for( int icc=0; icc<ncc; icc++ )
{
int d = (int) Distance( c[ic].x, c[ic].y, cc[icc].x, cc[icc].y )
- c[ic].r - cc[icc].r;
dist = min(dist,d);
}
for( int iss=0; iss<nss; iss++ )
{
int d = (int) GetPointToLineSegmentDistance( c[ic].x, c[ic].y,
ss[iss].xi, ss[iss].yi, ss[iss].xf, ss[iss].yf ) - c[ic].r;
dist = min(dist,d);
}
}
for( int is=0; is<ns; is++ )
{
for( int icc=0; icc<ncc; icc++ )
{
int d = (int) GetPointToLineSegmentDistance( cc[icc].x, cc[icc].y,
s[is].xi, s[is].yi, s[is].xf, s[is].yf ) - cc[icc].r;
dist = min(dist,d);
}
for( int iss=0; iss<nss; iss++ )
{
double d;
TestForIntersectionOfStraightLineSegments( s[is].xi, s[is].yi, s[is].xf, s[is].yf,
ss[iss].xi, ss[iss].yi, ss[iss].xf, ss[iss].yf, NULL, NULL, &d );
dist = min(dist, (int)d);
}
}
return max(dist,0);
}
// Get min. distance from (x,y) to line y = a + bx
// if b > DBL_MAX/10, assume vertical line at x = a
// returns closest point on line in xp, yp

View File

@ -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 );

View File

@ -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 <CPolyPt> 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 <CPolyPt> 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