code cleaning
This commit is contained in:
parent
237a8539fc
commit
b3b9c12173
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue