Commit 72d4b235 authored by Dick Hollenbeck's avatar Dick Hollenbeck

uncrustify math_for_graphics, add copyright legacy_plugin.h

parent 597833b5
...@@ -94,7 +94,7 @@ double BASE_SCREEN::GetScalingFactor() const ...@@ -94,7 +94,7 @@ double BASE_SCREEN::GetScalingFactor() const
} }
void BASE_SCREEN::SetScalingFactor(double aScale ) void BASE_SCREEN::SetScalingFactor( double aScale )
{ {
double zoom = aScale; double zoom = aScale;
...@@ -150,12 +150,10 @@ bool BASE_SCREEN::SetZoom( double coeff ) ...@@ -150,12 +150,10 @@ bool BASE_SCREEN::SetZoom( double coeff )
bool BASE_SCREEN::SetNextZoom() bool BASE_SCREEN::SetNextZoom()
{ {
size_t i;
if( m_ZoomList.IsEmpty() || m_Zoom >= m_ZoomList.Last() ) if( m_ZoomList.IsEmpty() || m_Zoom >= m_ZoomList.Last() )
return false; return false;
for( i = 0; i < m_ZoomList.GetCount(); i++ ) for( unsigned i = 0; i < m_ZoomList.GetCount(); i++ )
{ {
if( m_Zoom < m_ZoomList[i] ) if( m_Zoom < m_ZoomList[i] )
{ {
......
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
/* /*
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 1992-2011 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -59,8 +60,6 @@ struct FPL_CACHE; ...@@ -59,8 +60,6 @@ struct FPL_CACHE;
*/ */
class LEGACY_PLUGIN : public PLUGIN class LEGACY_PLUGIN : public PLUGIN
{ {
friend struct FPL_CACHE;
public: public:
//-----<PLUGIN IMPLEMENTATION>---------------------------------------------- //-----<PLUGIN IMPLEMENTATION>----------------------------------------------
...@@ -272,6 +271,8 @@ protected: ...@@ -272,6 +271,8 @@ protected:
/// we only cache one footprint library for now, this determines which one. /// we only cache one footprint library for now, this determines which one.
void cacheLib( const wxString& aLibraryPath ); void cacheLib( const wxString& aLibraryPath );
friend struct FPL_CACHE;
}; };
#endif // LEGACY_PLUGIN_H_ #endif // LEGACY_PLUGIN_H_
...@@ -29,14 +29,16 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist ) ...@@ -29,14 +29,16 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
if( xf==xi ) if( xf==xi )
{ {
// vertical segment // vertical segment
dd = fabs( (double)(x-xi) ); dd = fabs( (double) (x - xi) );
if( dd<dist && ( (yf>yi && y<yf && y>yi) || (yf<yi && y>yf && y<yi) ) ) if( dd<dist && ( (yf>yi && y<yf && y>yi) || (yf<yi && y>yf && y<yi) ) )
return true; return true;
} }
else if( yf==yi ) else if( yf==yi )
{ {
// horizontal segment // horizontal segment
dd = fabs( (double)(y-yi) ); dd = fabs( (double) (y - yi) );
if( dd<dist && ( (xf>xi && x<xf && x>xi) || (xf<xi && x>xf && x<xi) ) ) if( dd<dist && ( (xf>xi && x<xf && x>xi) || (xf<xi && x>xf && x<xi) ) )
return true; return true;
} }
...@@ -44,17 +46,18 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist ) ...@@ -44,17 +46,18 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
{ {
// oblique segment // oblique segment
// find a,b such that (xi,yi) and (xf,yf) lie on y = a + bx // find a,b such that (xi,yi) and (xf,yf) lie on y = a + bx
double b = (double)(yf-yi)/(xf-xi); double b = (double) (yf - yi) / (xf - xi);
double a = (double)yi-b*xi; double a = (double) yi - b * xi;
// find c,d such that (x,y) lies on y = c + dx where d=(-1/b) // find c,d such that (x,y) lies on y = c + dx where d=(-1/b)
double d = -1.0/b; double d = -1.0 / b;
double c = (double)y-d*x; double c = (double) y - d * x;
// find nearest point to (x,y) on line segment (xi,yi) to (xf,yf) // find nearest point to (x,y) on line segment (xi,yi) to (xf,yf)
double xp = (a-c)/(d-b); double xp = (a - c) / (d - b);
double yp = a + b*xp; double yp = a + b * xp;
// find distance // find distance
dd = sqrt((x-xp)*(x-xp)+(y-yp)*(y-yp)); dd = sqrt( (x - xp) * (x - xp) + (y - yp) * (y - yp) );
if( fabs(b)>0.7 )
if( fabs( b )>0.7 )
{ {
// line segment more vertical than horizontal // line segment more vertical than horizontal
if( dd<dist && ( (yf>yi && yp<yf && yp>yi) || (yf<yi && yp>yf && yp<yi) ) ) if( dd<dist && ( (yf>yi && yp<yf && yp>yi) || (yf<yi && yp>yf && yp<yi) ) )
...@@ -67,17 +70,19 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist ) ...@@ -67,17 +70,19 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist )
return true; return true;
} }
} }
return false; // no hit
return false; // no hit
} }
// set EllipseKH struct to describe the ellipse for an arc // set EllipseKH struct to describe the ellipse for an arc
// //
int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * el ) int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH* el )
{ {
// arc (quadrant of ellipse) // arc (quadrant of ellipse)
// convert to clockwise arc // convert to clockwise arc
int xxi, xxf, yyi, yyf; int xxi, xxf, yyi, yyf;
if( style == CPolyLine::ARC_CCW ) if( style == CPolyLine::ARC_CCW )
{ {
xxi = xf; xxi = xf;
...@@ -92,54 +97,60 @@ int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * e ...@@ -92,54 +97,60 @@ int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * e
yyi = yi; yyi = yi;
yyf = yf; yyf = yf;
} }
// find center and radii of ellipse // find center and radii of ellipse
double xo=0, yo=0; double xo = 0, yo = 0;
if( xxf > xxi && yyf > yyi ) if( xxf > xxi && yyf > yyi )
{ {
xo = xxf; xo = xxf;
yo = yyi; yo = yyi;
el->theta1 = M_PI; el->theta1 = M_PI;
el->theta2 = M_PI/2.0; el->theta2 = M_PI / 2.0;
} }
else if( xxf < xxi && yyf > yyi ) else if( xxf < xxi && yyf > yyi )
{ {
xo = xxi; xo = xxi;
yo = yyf; yo = yyf;
el->theta1 = -M_PI/2.0; el->theta1 = -M_PI / 2.0;
el->theta2 = -M_PI; el->theta2 = -M_PI;
} }
else if( xxf < xxi && yyf < yyi ) else if( xxf < xxi && yyf < yyi )
{ {
xo = xxf; xo = xxf;
yo = yyi; yo = yyi;
el->theta1 = 0.0; el->theta1 = 0.0;
el->theta2 = -M_PI/2.0; el->theta2 = -M_PI / 2.0;
} }
else if( xxf > xxi && yyf < yyi ) else if( xxf > xxi && yyf < yyi )
{ {
xo = xxi; xo = xxi;
yo = yyf; yo = yyf;
el->theta1 = M_PI/2.0; el->theta1 = M_PI / 2.0;
el->theta2 = 0.0; el->theta2 = 0.0;
} }
el->Center.X = xo;
el->Center.Y = yo; el->Center.X = xo;
el->xrad = abs(xf-xi); el->Center.Y = yo;
el->yrad = abs(yf-yi); el->xrad = abs( xf - xi );
el->yrad = abs( yf - yi );
#if 0 #if 0
el->Phi = 0.0; el->Phi = 0.0;
el->MaxRad = el->xrad; el->MaxRad = el->xrad;
el->MinRad = el->yrad; el->MinRad = el->yrad;
if( el->MaxRad < el->MinRad ) if( el->MaxRad < el->MinRad )
{ {
el->MaxRad = el->yrad; el->MaxRad = el->yrad;
el->MinRad = el->xrad; el->MinRad = el->xrad;
el->Phi = M_PI/2.0; el->Phi = M_PI / 2.0;
} }
#endif #endif
return 0; return 0;
} }
// find intersections between line segment (xi,yi) to (xf,yf) // find intersections between line segment (xi,yi) to (xf,yf)
// and line segment (xi2,yi2) to (xf2,yf2) // and line segment (xi2,yi2) to (xf2,yf2)
// the line segments may be arcs (i.e. quadrant of an ellipse) or straight // the line segments may be arcs (i.e. quadrant of an ellipse) or straight
...@@ -147,16 +158,16 @@ int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * e ...@@ -147,16 +158,16 @@ int MakeEllipseFromArc( int xi, int yi, int xf, int yf, int style, EllipseKH * e
// returns coords of intersections in arrays x[2], y[2] // returns coords of intersections in arrays x[2], y[2]
// //
int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
int xi2, int yi2, int xf2, int yf2, int style2, int xi2, int yi2, int xf2, int yf2, int style2,
double x[], double y[] ) double x[], double y[] )
{ {
double xr[12], yr[12]; double xr[12], yr[12];
int iret = 0; int iret = 0;
if( max(xi,xf) < min(xi2,xf2) if( max( xi, xf ) < min( xi2, xf2 )
|| min(xi,xf) > max(xi2,xf2) || min( xi, xf ) > max( xi2, xf2 )
|| max(yi,yf) < min(yi2,yf2) || max( yi, yf ) < min( yi2, yf2 )
|| min(yi,yf) > max(yi2,yf2) ) || min( yi, yf ) > max( yi2, yf2 ) )
return 0; return 0;
if( style != CPolyLine::STRAIGHT && style2 != CPolyLine::STRAIGHT ) if( style != CPolyLine::STRAIGHT && style2 != CPolyLine::STRAIGHT )
...@@ -166,18 +177,20 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, ...@@ -166,18 +177,20 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
{ {
if( x && y ) if( x && y )
{ {
x[0] = xi; x[0] = xi;
y[0] = yi; y[0] = yi;
} }
return 1; return 1;
} }
else if( style != style2 && xi == xf2 && yi == yf2 && xf == xi2 && yf == yi2 ) else if( style != style2 && xi == xf2 && yi == yf2 && xf == xi2 && yf == yi2 )
{ {
if( x && y ) if( x && y )
{ {
x[0] = xi; x[0] = xi;
y[0] = yi; y[0] = yi;
} }
return 1; return 1;
} }
} }
...@@ -185,48 +198,63 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, ...@@ -185,48 +198,63 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
if( style == CPolyLine::STRAIGHT && style2 == CPolyLine::STRAIGHT ) if( style == CPolyLine::STRAIGHT && style2 == CPolyLine::STRAIGHT )
{ {
// both straight-line segments // both straight-line segments
int x, y; int x, y;
bool bYes = TestForIntersectionOfStraightLineSegments( xi, yi, xf, yf, xi2, yi2, xf2, yf2, &x, &y ); bool bYes = TestForIntersectionOfStraightLineSegments( xi,
yi,
xf,
yf,
xi2,
yi2,
xf2,
yf2,
&x,
&y );
if( !bYes ) if( !bYes )
return 0; return 0;
xr[0] = x;
yr[0] = y; xr[0] = x;
iret = 1; yr[0] = y;
iret = 1;
} }
else if( style == CPolyLine::STRAIGHT ) else if( style == CPolyLine::STRAIGHT )
{ {
// first segment is straight, second segment is an arc // first segment is straight, second segment is an arc
int ret; int ret;
double x1r, y1r, x2r, y2r; double x1r, y1r, x2r, y2r;
if( xf == xi ) if( xf == xi )
{ {
// vertical first segment // vertical first segment
double a = xi; double a = xi;
double b = DBL_MAX/2.0; double b = DBL_MAX / 2.0;
ret = FindLineSegmentIntersection( a, b, xi2, yi2, xf2, yf2, style2, ret = FindLineSegmentIntersection( a, b, xi2, yi2, xf2, yf2, style2,
&x1r, &y1r, &x2r, &y2r ); &x1r, &y1r, &x2r, &y2r );
} }
else else
{ {
double b = (double)(yf-yi)/(double)(xf-xi); double b = (double) (yf - yi) / (double) (xf - xi);
double a = yf - b*xf; double a = yf - b * xf;
ret = FindLineSegmentIntersection( a, b, xi2, yi2, xf2, yf2, style2, ret = FindLineSegmentIntersection( a, b, xi2, yi2, xf2, yf2, style2,
&x1r, &y1r, &x2r, &y2r ); &x1r, &y1r, &x2r, &y2r );
} }
if( ret == 0 ) if( ret == 0 )
return 0; return 0;
if( InRange( x1r, xi, xf ) && InRange( y1r, yi, yf ) ) if( InRange( x1r, xi, xf ) && InRange( y1r, yi, yf ) )
{ {
xr[iret] = x1r; xr[iret] = x1r;
yr[iret] = y1r; yr[iret] = y1r;
iret++; iret++;
} }
if( ret == 2 ) if( ret == 2 )
{ {
if( InRange( x2r, xi, xf ) && InRange( y2r, yi, yf ) ) if( InRange( x2r, xi, xf ) && InRange( y2r, yi, yf ) )
{ {
xr[iret] = x2r; xr[iret] = x2r;
yr[iret] = y2r; yr[iret] = y2r;
iret++; iret++;
} }
} }
...@@ -234,37 +262,41 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, ...@@ -234,37 +262,41 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
else if( style2 == CPolyLine::STRAIGHT ) else if( style2 == CPolyLine::STRAIGHT )
{ {
// first segment is an arc, second segment is straight // first segment is an arc, second segment is straight
int ret; int ret;
double x1r, y1r, x2r, y2r; double x1r, y1r, x2r, y2r;
if( xf2 == xi2 ) if( xf2 == xi2 )
{ {
// vertical second segment // vertical second segment
double a = xi2; double a = xi2;
double b = DBL_MAX/2.0; double b = DBL_MAX / 2.0;
ret = FindLineSegmentIntersection( a, b, xi, yi, xf, yf, style, ret = FindLineSegmentIntersection( a, b, xi, yi, xf, yf, style,
&x1r, &y1r, &x2r, &y2r ); &x1r, &y1r, &x2r, &y2r );
} }
else else
{ {
double b = (double)(yf2-yi2)/(double)(xf2-xi2); double b = (double) (yf2 - yi2) / (double) (xf2 - xi2);
double a = yf2 - b*xf2; double a = yf2 - b * xf2;
ret = FindLineSegmentIntersection( a, b, xi, yi, xf, yf, style, ret = FindLineSegmentIntersection( a, b, xi, yi, xf, yf, style,
&x1r, &y1r, &x2r, &y2r ); &x1r, &y1r, &x2r, &y2r );
} }
if( ret == 0 ) if( ret == 0 )
return 0; return 0;
if( InRange( x1r, xi2, xf2 ) && InRange( y1r, yi2, yf2 ) ) if( InRange( x1r, xi2, xf2 ) && InRange( y1r, yi2, yf2 ) )
{ {
xr[iret] = x1r; xr[iret] = x1r;
yr[iret] = y1r; yr[iret] = y1r;
iret++; iret++;
} }
if( ret == 2 ) if( ret == 2 )
{ {
if( InRange( x2r, xi2, xf2 ) && InRange( y2r, yi2, yf2 ) ) if( InRange( x2r, xi2, xf2 ) && InRange( y2r, yi2, yf2 ) )
{ {
xr[iret] = x2r; xr[iret] = x2r;
yr[iret] = y2r; yr[iret] = y2r;
iret++; iret++;
} }
} }
...@@ -272,28 +304,33 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, ...@@ -272,28 +304,33 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
else else
{ {
// both segments are arcs // both segments are arcs
EllipseKH el1; EllipseKH el1;
EllipseKH el2; EllipseKH el2;
MakeEllipseFromArc( xi, yi, xf, yf, style, &el1 ); MakeEllipseFromArc( xi, yi, xf, yf, style, &el1 );
MakeEllipseFromArc( xi2, yi2, xf2, yf2, style2, &el2 ); MakeEllipseFromArc( xi2, yi2, xf2, yf2, style2, &el2 );
int n; int n;
if( el1.xrad+el1.yrad > el2.xrad+el2.yrad )
if( el1.xrad + el1.yrad > el2.xrad + el2.yrad )
n = GetArcIntersections( &el1, &el2 ); n = GetArcIntersections( &el1, &el2 );
else else
n = GetArcIntersections( &el2, &el1 ); n = GetArcIntersections( &el2, &el1 );
iret = n; iret = n;
} }
if( x && y ) if( x && y )
{ {
for( int i=0; i<iret; i++ ) for( int i = 0; i<iret; i++ )
{ {
x[i] = xr[i]; x[i] = xr[i];
y[i] = yr[i]; y[i] = yr[i];
} }
} }
return iret; return iret;
} }
// find intersection between line y = a + bx and line segment (xi,yi) to (xf,yf) // find intersection between line y = a + bx and line segment (xi,yi) to (xf,yf)
// if b > DBL_MAX/10, assume vertical line at x = a // if b > DBL_MAX/10, assume vertical line at x = a
// the line segment may be an arc (i.e. quadrant of an ellipse) // the line segment may be an arc (i.e. quadrant of an ellipse)
...@@ -303,12 +340,13 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, ...@@ -303,12 +340,13 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style,
// if no intersection, returns min distance in dist // if no intersection, returns min distance in dist
// //
int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int yf, int style, 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* x1, double* y1, double* x2, double* y2,
double * dist ) double* dist )
{ {
double xx = 0, yy = 0; //Init made to avoid C compil "uninitialized" warning double xx = 0, yy = 0; // Init made to avoid C compil "uninitialized" warning
bool bVert = false; bool bVert = false;
if( b > DBL_MAX/10.0 )
if( b > DBL_MAX / 10.0 )
bVert = true; bVert = true;
if( xf != xi ) if( xf != xi )
...@@ -318,36 +356,42 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int ...@@ -318,36 +356,42 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
{ {
// horizontal or oblique straight segment // horizontal or oblique straight segment
// put into form y = c + dx; // put into form y = c + dx;
double d = (double)(yf-yi)/(double)(xf-xi); double d = (double) (yf - yi) / (double) (xf - xi);
double c = yf - d*xf; double c = yf - d * xf;
if( bVert ) if( bVert )
{ {
// if vertical line, easy // if vertical line, easy
if( InRange( a, xi, xf ) ) if( InRange( a, xi, xf ) )
{ {
*x1 = a; *x1 = a;
*y1 = c + d*a; *y1 = c + d * a;
return 1; return 1;
} }
else else
{ {
if( dist ) if( dist )
*dist = min( abs(a-xi), abs(a-xf) ); *dist = min( abs( a - xi ), abs( a - xf ) );
return 0; return 0;
} }
} }
if( fabs(b-d) < 1E-12 )
if( fabs( b - d ) < 1E-12 )
{ {
// parallel lines // parallel lines
if( dist ) if( dist )
{ {
*dist = GetPointToLineDistance( a, b, xi, xf ); *dist = GetPointToLineDistance( a, b, xi, xf );
} }
return 0; // lines parallel
return 0; // lines parallel
} }
// calculate intersection // calculate intersection
xx = (c-a)/(b-d); xx = (c - a) / (b - d);
yy = a + b*(xx); yy = a + b * (xx);
// see if intersection is within the line segment // see if intersection is within the line segment
if( yf == yi ) if( yf == yi )
{ {
...@@ -368,6 +412,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int ...@@ -368,6 +412,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
// arc (quadrant of ellipse) // arc (quadrant of ellipse)
// convert to clockwise arc // convert to clockwise arc
int xxi, xxf, yyi, yyf; int xxi, xxf, yyi, yyf;
if( style == CPolyLine::ARC_CCW ) if( style == CPolyLine::ARC_CCW )
{ {
xxi = xf; xxi = xf;
...@@ -382,39 +427,45 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int ...@@ -382,39 +427,45 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
yyi = yi; yyi = yi;
yyf = yf; yyf = yf;
} }
// find center and radii of ellipse // find center and radii of ellipse
double xo = xxf, yo = yyi, rx, ry; // Init made to avoid C compil warnings double xo = xxf, yo = yyi, rx, ry; // Init made to avoid C compil warnings
if( xxf > xxi && yyf > yyi ) if( xxf > xxi && yyf > yyi )
{ {
xo = xxf; xo = xxf;
yo = yyi; yo = yyi;
} }
else if( xxf < xxi && yyf > yyi ) else if( xxf < xxi && yyf > yyi )
{ {
xo = xxi; xo = xxi;
yo = yyf; yo = yyf;
} }
else if( xxf < xxi && yyf < yyi ) else if( xxf < xxi && yyf < yyi )
{ {
xo = xxf; xo = xxf;
yo = yyi; yo = yyi;
} }
else if( xxf > xxi && yyf < yyi ) else if( xxf > xxi && yyf < yyi )
{ {
xo = xxi; xo = xxi;
yo = yyf; yo = yyf;
} }
rx = fabs( (double)(xxi-xxf) );
ry = fabs( (double)(yyi-yyf) ); rx = fabs( (double) (xxi - xxf) );
bool test; ry = fabs( (double) (yyi - yyf) );
double xx1, xx2, yy1, yy2, aa; bool test;
double xx1, xx2, yy1, yy2, aa;
if( bVert ) if( bVert )
{ {
// shift vertical line to coordinate system of ellipse // shift vertical line to coordinate system of ellipse
aa = a - xo; aa = a - xo;
test = FindVerticalLineEllipseIntersections( rx, ry, aa, &yy1, &yy2 ); test = FindVerticalLineEllipseIntersections( rx, ry, aa, &yy1, &yy2 );
if( !test ) if( !test )
return 0; return 0;
// shift back to PCB coordinates // shift back to PCB coordinates
yy1 += yo; yy1 += yo;
yy2 += yo; yy2 += yo;
...@@ -424,66 +475,76 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int ...@@ -424,66 +475,76 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
else else
{ {
// shift line to coordinate system of ellipse // shift line to coordinate system of ellipse
aa = a + b*xo - yo; aa = a + b * xo - yo;
test = FindLineEllipseIntersections( rx, ry, aa, b, &xx1, &xx2 ); test = FindLineEllipseIntersections( rx, ry, aa, b, &xx1, &xx2 );
if( !test ) if( !test )
return 0; return 0;
// shift back to PCB coordinates // shift back to PCB coordinates
yy1 = aa + b*xx1; yy1 = aa + b * xx1;
xx1 += xo; xx1 += xo;
yy1 += yo; yy1 += yo;
yy2 = aa + b*xx2; yy2 = aa + b * xx2;
xx2 += xo; xx2 += xo;
yy2 += yo; yy2 += yo;
} }
int npts = 0; int npts = 0;
if( (xxf>xxi && xx1<xxf && xx1>xxi) || (xxf<xxi && xx1<xxi && xx1>xxf) ) if( (xxf>xxi && xx1<xxf && xx1>xxi) || (xxf<xxi && xx1<xxi && xx1>xxf) )
{ {
if( (yyf>yyi && yy1<yyf && yy1>yyi) || (yyf<yyi && yy1<yyi && yy1>yyf) ) if( (yyf>yyi && yy1<yyf && yy1>yyi) || (yyf<yyi && yy1<yyi && yy1>yyf) )
{ {
*x1 = xx1; *x1 = xx1;
*y1 = yy1; *y1 = yy1;
npts = 1; npts = 1;
} }
} }
if( (xxf>xxi && xx2<xxf && xx2>xxi) || (xxf<xxi && xx2<xxi && xx2>xxf) ) if( (xxf>xxi && xx2<xxf && xx2>xxi) || (xxf<xxi && xx2<xxi && xx2>xxf) )
{ {
if( (yyf>yyi && yy2<yyf && yy2>yyi) || (yyf<yyi && yy2<yyi && yy2>yyf) ) if( (yyf>yyi && yy2<yyf && yy2>yyi) || (yyf<yyi && yy2<yyi && yy2>yyf) )
{ {
if( npts == 0 ) if( npts == 0 )
{ {
*x1 = xx2; *x1 = xx2;
*y1 = yy2; *y1 = yy2;
npts = 1; npts = 1;
} }
else else
{ {
*x2 = xx2; *x2 = xx2;
*y2 = yy2; *y2 = yy2;
npts = 2; npts = 2;
} }
} }
} }
return npts; return npts;
} }
else else
wxASSERT(0); wxASSERT( 0 );
} }
else else
{ {
// vertical line segment // vertical line segment
if( bVert ) if( bVert )
return 0; return 0;
xx = xi;
yy = a + b*xx; xx = xi;
yy = a + b * xx;
if( (yy>=yi && yy>yf) || (yy<=yi && yy<yf) ) if( (yy>=yi && yy>yf) || (yy<=yi && yy<yf) )
return 0; return 0;
} }
*x1 = xx; *x1 = xx;
*y1 = yy; *y1 = yy;
return 1; return 1;
} }
/* /*
* Function TestForIntersectionOfStraightLineSegments * Function TestForIntersectionOfStraightLineSegments
* Test for intersection of line segments * Test for intersection of line segments
...@@ -492,10 +553,11 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int ...@@ -492,10 +553,11 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int
* if false, returns min. distance in dist (may be 0.0 if parallel) * if false, returns min. distance in dist (may be 0.0 if parallel)
*/ */
bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y1f, bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y1f,
int x2i, int y2i, int x2f, int y2f, int x2i, int y2i, int x2f, int y2f,
int * x, int * y, double * d ) int* x, int* y, double* d )
{ {
double a, b, dist; double a, b, dist;
// first, test for intersection // first, test for intersection
if( x1i == x1f && x2i == x2f ) if( x1i == x1f && x2i == x2f )
{ {
...@@ -513,10 +575,13 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y ...@@ -513,10 +575,13 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{ {
if( x ) if( x )
*x = x1i; *x = x1i;
if( y ) if( y )
*y = y2i; *y = y2i;
if( d ) if( d )
*d = 0.0; *d = 0.0;
return true; return true;
} }
} }
...@@ -528,10 +593,13 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y ...@@ -528,10 +593,13 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{ {
if( x ) if( x )
*x = x2i; *x = x2i;
if( y ) if( y )
*y = y1i; *y = y1i;
if( d ) if( d )
*d = 0.0; *d = 0.0;
return true; return true;
} }
} }
...@@ -539,21 +607,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y ...@@ -539,21 +607,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{ {
// first segment vertical, second oblique // first segment vertical, second oblique
// get a and b for second line segment, so that y = a + bx; // get a and b for second line segment, so that y = a + bx;
b = (double)(y2f-y2i)/(x2f-x2i); b = double( y2f - y2i ) / (x2f - x2i);
a = (double)y2i - b*x2i; a = (double) y2i - b * x2i;
double x1, y1, x2, y2;
int test = FindLineSegmentIntersection( a, b, x1i, y1i, x1f, y1f, CPolyLine::STRAIGHT, double x1, y1, x2, y2;
&x1, &y1, &x2, &y2 ); int test = FindLineSegmentIntersection( a, b, x1i, y1i, x1f, y1f, CPolyLine::STRAIGHT,
&x1, &y1, &x2, &y2 );
if( test ) if( test )
{ {
if( InRange( y1, y1i, y1f ) && InRange( x1, x2i, x2f ) && InRange( y1, y2i, y2f ) ) if( InRange( y1, y1i, y1f ) && InRange( x1, x2i, x2f ) && InRange( y1, y2i, y2f ) )
{ {
if( x ) if( x )
*x = (int) x1; *x = (int) x1;
if( y ) if( y )
*y = (int) y1; *y = (int) y1;
if( d ) if( d )
*d = 0.0; *d = 0.0;
return true; return true;
} }
} }
...@@ -562,21 +635,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y ...@@ -562,21 +635,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{ {
// first segment horizontal, second oblique // first segment horizontal, second oblique
// get a and b for second line segment, so that y = a + bx; // get a and b for second line segment, so that y = a + bx;
b = (double)(y2f-y2i)/(x2f-x2i); b = double( y2f - y2i ) / (x2f - x2i);
a = (double)y2i - b*x2i; a = (double) y2i - b * x2i;
double x1, y1, x2, y2;
int test = FindLineSegmentIntersection( a, b, x1i, y1i, x1f, y1f, CPolyLine::STRAIGHT, double x1, y1, x2, y2;
&x1, &y1, &x2, &y2 ); int test = FindLineSegmentIntersection( a, b, x1i, y1i, x1f, y1f, CPolyLine::STRAIGHT,
&x1, &y1, &x2, &y2 );
if( test ) if( test )
{ {
if( InRange( x1, x1i, x1f ) && InRange( x1, x2i, x2f ) && InRange( y1, y2i, y2f ) ) if( InRange( x1, x1i, x1f ) && InRange( x1, x2i, x2f ) && InRange( y1, y2i, y2f ) )
{ {
if( x ) if( x )
*x = (int) x1; *x = (int) x1;
if( y ) if( y )
*y = (int) y1; *y = (int) y1;
if( d ) if( d )
*d = 0.0; *d = 0.0;
return true; return true;
} }
} }
...@@ -585,21 +663,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y ...@@ -585,21 +663,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{ {
// second segment vertical, first oblique // second segment vertical, first oblique
// get a and b for first line segment, so that y = a + bx; // get a and b for first line segment, so that y = a + bx;
b = (double)(y1f-y1i)/(x1f-x1i); b = double( y1f - y1i ) / (x1f - x1i);
a = (double)y1i - b*x1i; a = (double) y1i - b * x1i;
double x1, y1, x2, y2;
int test = FindLineSegmentIntersection( a, b, x2i, y2i, x2f, y2f, CPolyLine::STRAIGHT, double x1, y1, x2, y2;
&x1, &y1, &x2, &y2 ); int test = FindLineSegmentIntersection( a, b, x2i, y2i, x2f, y2f, CPolyLine::STRAIGHT,
&x1, &y1, &x2, &y2 );
if( test ) if( test )
{ {
if( InRange( x1, x1i, x1f ) && InRange( y1, y1i, y1f ) && InRange( y1, y2i, y2f ) ) if( InRange( x1, x1i, x1f ) && InRange( y1, y1i, y1f ) && InRange( y1, y2i, y2f ) )
{ {
if( x ) if( x )
*x = (int) x1; *x = (int) x1;
if( y ) if( y )
*y = (int) y1; *y = (int) y1;
if( d ) if( d )
*d = 0.0; *d = 0.0;
return true; return true;
} }
} }
...@@ -608,21 +691,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y ...@@ -608,21 +691,26 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{ {
// second segment horizontal, first oblique // second segment horizontal, first oblique
// get a and b for second line segment, so that y = a + bx; // get a and b for second line segment, so that y = a + bx;
b = (double)(y1f-y1i)/(x1f-x1i); b = double( y1f - y1i ) / (x1f - x1i);
a = (double)y1i - b*x1i; a = (double) y1i - b * x1i;
double x1, y1, x2, y2;
int test = FindLineSegmentIntersection( a, b, x2i, y2i, x2f, y2f, CPolyLine::STRAIGHT, double x1, y1, x2, y2;
&x1, &y1, &x2, &y2 ); int test = FindLineSegmentIntersection( a, b, x2i, y2i, x2f, y2f, CPolyLine::STRAIGHT,
&x1, &y1, &x2, &y2 );
if( test ) if( test )
{ {
if( InRange( x1, x1i, x1f ) && InRange( y1, y1i, y1f ) ) if( InRange( x1, x1i, x1f ) && InRange( y1, y1i, y1f ) )
{ {
if( x ) if( x )
*x = (int) x1; *x = (int) x1;
if( y ) if( y )
*y = (int) y1; *y = (int) y1;
if( d ) if( d )
*d = 0.0; *d = 0.0;
return true; return true;
} }
} }
...@@ -630,14 +718,25 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y ...@@ -630,14 +718,25 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
else else
{ {
// both segments oblique // both segments oblique
if( (long)(y1f-y1i)*(x2f-x2i) != (long)(y2f-y2i)*(x1f-x1i) ) if( long( y1f - y1i ) * (x2f - x2i) != long( y2f - y2i ) * (x1f - x1i) )
{ {
// not parallel, get a and b for first line segment, so that y = a + bx; // not parallel, get a and b for first line segment, so that y = a + bx;
b = (double)(y1f-y1i)/(x1f-x1i); b = double( y1f - y1i ) / (x1f - x1i);
a = (double)y1i - b*x1i; a = (double) y1i - b * x1i;
double x1, y1, x2, y2;
int test = FindLineSegmentIntersection( a, b, x2i, y2i, x2f, y2f, CPolyLine::STRAIGHT, double x1, y1, x2, y2;
&x1, &y1, &x2, &y2 ); int test = FindLineSegmentIntersection( a,
b,
x2i,
y2i,
x2f,
y2f,
CPolyLine::STRAIGHT,
&x1,
&y1,
&x2,
&y2 );
// both segments oblique // both segments oblique
if( test ) if( test )
{ {
...@@ -645,89 +744,110 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y ...@@ -645,89 +744,110 @@ bool TestForIntersectionOfStraightLineSegments( int x1i, int y1i, int x1f, int y
{ {
if( x ) if( x )
*x = (int) x1; *x = (int) x1;
if( y ) if( y )
*y = (int) y1; *y = (int) y1;
if( d ) if( d )
*d = 0.0; *d = 0.0;
return true; return true;
} }
} }
} }
} }
// don't intersect, get shortest distance between each endpoint and the other line segment // don't intersect, get shortest distance between each endpoint and the other line segment
dist = GetPointToLineSegmentDistance( x1i, y1i, x2i, y2i, x2f, y2f ); dist = GetPointToLineSegmentDistance( x1i, y1i, x2i, y2i, x2f, y2f );
double xx = x1i;
double yy = y1i; double xx = x1i;
double dd = GetPointToLineSegmentDistance( x1f, y1f, x2i, y2i, x2f, y2f ); double yy = y1i;
double dd = GetPointToLineSegmentDistance( x1f, y1f, x2i, y2i, x2f, y2f );
if( dd < dist ) if( dd < dist )
{ {
dist = dd; dist = dd;
xx = x1f; xx = x1f;
yy = y1f; yy = y1f;
} }
dd = GetPointToLineSegmentDistance( x2i, y2i, x1i, y1i, x1f, y1f ); dd = GetPointToLineSegmentDistance( x2i, y2i, x1i, y1i, x1f, y1f );
if( dd < dist ) if( dd < dist )
{ {
dist = dd; dist = dd;
xx = x2i; xx = x2i;
yy = y2i; yy = y2i;
} }
dd = GetPointToLineSegmentDistance( x2f, y2f, x1i, y1i, x1f, y1f ); dd = GetPointToLineSegmentDistance( x2f, y2f, x1i, y1i, x1f, y1f );
if( dd < dist ) if( dd < dist )
{ {
dist = dd; dist = dd;
xx = x2f; xx = x2f;
yy = y2f; yy = y2f;
} }
if( x ) if( x )
*x = (int) xx; *x = (int) xx;
if( y ) if( y )
*y = (int) yy; *y = (int) yy;
if( d ) if( d )
*d = dist; *d = dist;
return false; return false;
} }
/*solves the Quadratic equation = a*x*x + b*x + c /*solves the Quadratic equation = a*x*x + b*x + c
*/ */
bool Quadratic( double a, double b, double c, double *x1, double *x2 ) bool Quadratic( double a, double b, double c, double* x1, double* x2 )
{ {
double root = b*b - 4.0*a*c; double root = b * b - 4.0 * a * c;
if( root < 0.0 ) if( root < 0.0 )
return false; return false;
root = sqrt( root );
*x1 = (-b+root)/(2.0*a); root = sqrt( root );
*x2 = (-b-root)/(2.0*a); *x1 = (-b + root) / (2.0 * a);
*x2 = (-b - root) / (2.0 * a);
return true; return true;
} }
// finds intersections of vertical line at x // finds intersections of vertical line at x
// with ellipse defined by (x^2)/(a^2) + (y^2)/(b^2) = 1; // with ellipse defined by (x^2)/(a^2) + (y^2)/(b^2) = 1;
// returns true if solution exist, with solutions in y1 and y2 // returns true if solution exist, with solutions in y1 and y2
// else returns false // else returns false
// //
bool FindVerticalLineEllipseIntersections( double a, double b, double x, double *y1, double *y2 ) bool FindVerticalLineEllipseIntersections( double a, double b, double x, double* y1, double* y2 )
{ {
double y_sqr = (1.0-(x*x)/(a*a))*b*b; double y_sqr = ( 1.0 - (x * x) / (a * a) ) * b * b;
if( y_sqr < 0.0 ) if( y_sqr < 0.0 )
return false; return false;
*y1 = sqrt(y_sqr);
*y1 = sqrt( y_sqr );
*y2 = -*y1; *y2 = -*y1;
return true; return true;
} }
// finds intersections of straight line y = c + dx // finds intersections of straight line y = c + dx
// with ellipse defined by (x^2)/(a^2) + (y^2)/(b^2) = 1; // with ellipse defined by (x^2)/(a^2) + (y^2)/(b^2) = 1;
// returns true if solution exist, with solutions in x1 and x2 // returns true if solution exist, with solutions in x1 and x2
// else returns false // else returns false
// //
bool FindLineEllipseIntersections( double a, double b, double c, double d, double *x1, double *x2 ) bool FindLineEllipseIntersections( double a, double b, double c, double d, double* x1, double* x2 )
{ {
// quadratic terms // quadratic terms
double A = d*d+b*b/(a*a); double A = d * d + b * b / (a * a);
double B = 2.0*c*d; double B = 2.0 * c * d;
double C = c*c-b*b; double C = c * c - b * b;
return Quadratic( A, B, C, x1, x2 ); return Quadratic( A, B, C, x1, x2 );
} }
...@@ -737,54 +857,66 @@ bool FindLineEllipseIntersections( double a, double b, double c, double d, doubl ...@@ -737,54 +857,66 @@ bool FindLineEllipseIntersections( double a, double b, double c, double d, doubl
// in clearance > max_cl, just returns max_cl and doesn't return x,y // in clearance > max_cl, just returns max_cl and doesn't return x,y
// //
int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, int w1, 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 x2i, int y2i, int x2f, int y2f, int style2, int w2,
int max_cl, int * x, int * y ) int max_cl, int* x, int* y )
{ {
// check clearance between bounding rectangles // check clearance between bounding rectangles
int test = max_cl + w1/2 + w2/2; int test = max_cl + w1 / 2 + w2 / 2;
if( min(x1i,x1f)-max(x2i,x2f) > test )
if( min( x1i, x1f ) - max( x2i, x2f ) > test )
return max_cl; return max_cl;
if( min(x2i,x2f)-max(x1i,x1f) > test )
if( min( x2i, x2f ) - max( x1i, x1f ) > test )
return max_cl; return max_cl;
if( min(y1i,y1f)-max(y2i,y2f) > test )
if( min( y1i, y1f ) - max( y2i, y2f ) > test )
return max_cl; return max_cl;
if( min(y2i,y2f)-max(y1i,y1f) > test )
if( min( y2i, y2f ) - max( y1i, y1f ) > test )
return max_cl; return max_cl;
if( style1 == CPolyLine::STRAIGHT && style1 == CPolyLine::STRAIGHT ) if( style1 == CPolyLine::STRAIGHT && style1 == CPolyLine::STRAIGHT )
{ {
// both segments are straight lines // both segments are straight lines
int xx, yy; int xx, yy;
double dd; double dd;
TestForIntersectionOfStraightLineSegments( x1i, y1i, x1f, y1f, TestForIntersectionOfStraightLineSegments( x1i, y1i, x1f, y1f,
x2i, y2i, x2f, y2f, &xx, &yy, &dd ); x2i, y2i, x2f, y2f, &xx, &yy, &dd );
int d = max( 0, (int)dd - w1/2 - w2/2 ); int d = max( 0, (int) dd - w1 / 2 - w2 / 2 );
if( x ) if( x )
*x = xx; *x = xx;
if( y ) if( y )
*y = yy; *y = yy;
return d; return d;
} }
// not both straight-line segments // not both straight-line segments
// see if segments intersect // see if segments intersect
double xr[2]; double xr[2];
double yr[2]; double yr[2];
test = FindSegmentIntersections( x1i, y1i, x1f, y1f, style1, x2i, y2i, x2f, y2f, style2, xr, yr ); test =
FindSegmentIntersections( x1i, y1i, x1f, y1f, style1, x2i, y2i, x2f, y2f, style2, xr, yr );
if( test ) if( test )
{ {
if( x ) if( x )
*x = (int) xr[0]; *x = (int) xr[0];
if( y ) if( y )
*y = (int) yr[0]; *y = (int) yr[0];
return 0; return 0;
} }
// at least one segment is an arc // at least one segment is an arc
EllipseKH el1; EllipseKH el1;
EllipseKH el2; EllipseKH el2;
bool bArcs; bool bArcs;
int xi=0, yi=0, xf=0, yf=0; int xi = 0, yi = 0, xf = 0, yf = 0;
if( style2 == CPolyLine::STRAIGHT ) if( style2 == CPolyLine::STRAIGHT )
{ {
// style1 = arc, style2 = straight // style1 = arc, style2 = straight
...@@ -798,10 +930,10 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, ...@@ -798,10 +930,10 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
else if( style1 == CPolyLine::STRAIGHT ) else if( style1 == CPolyLine::STRAIGHT )
{ {
// style2 = arc, style1 = straight // style2 = arc, style1 = straight
xi = x1i; xi = x1i;
yi = y1i; yi = y1i;
xf = x1f; xf = x1f;
yf = y1f; yf = y1f;
MakeEllipseFromArc( x2i, y2i, x2f, y2f, style2, &el1 ); MakeEllipseFromArc( x2i, y2i, x2f, y2f, style2, &el1 );
bArcs = false; bArcs = false;
} }
...@@ -812,106 +944,127 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, ...@@ -812,106 +944,127 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
MakeEllipseFromArc( x2i, y2i, x2f, y2f, style2, &el2 ); MakeEllipseFromArc( x2i, y2i, x2f, y2f, style2, &el2 );
bArcs = true; bArcs = true;
} }
const int NSTEPS = 32; const int NSTEPS = 32;
if( el1.theta2 > el1.theta1 ) if( el1.theta2 > el1.theta1 )
{ {
wxASSERT(0); wxASSERT( 0 );
} }
if( bArcs && el2.theta2 > el2.theta1 ) if( bArcs && el2.theta2 > el2.theta1 )
{ {
wxASSERT(0); wxASSERT( 0 );
} }
// test multiple points in both segments // test multiple points in both segments
double th1; double th1;
double th2; double th2;
double len2; double len2;
if( bArcs ) if( bArcs )
{ {
th1 = el2.theta1; th1 = el2.theta1;
th2 = el2.theta2; th2 = el2.theta2;
len2 = max(el2.xrad, el2.yrad); len2 = max( el2.xrad, el2.yrad );
} }
else else
{ {
th1 = 1.0; th1 = 1.0;
th2 = 0.0; th2 = 0.0;
len2 = abs(xf-xi)+abs(yf-yi); len2 = abs( xf - xi ) + abs( yf - yi );
} }
double s_start = el1.theta1;
double s_end = el1.theta2; double s_start = el1.theta1;
double s_start2 = th1; double s_end = el1.theta2;
double s_end2 = th2; double s_start2 = th1;
double dmin = DBL_MAX; double s_end2 = th2;
double xmin = 0, ymin = 0, smin = 0, smin2 = 0; // Init made to avoid C compil warnings double dmin = DBL_MAX;
double xmin = 0, ymin = 0, smin = 0, smin2 = 0; // Init made to avoid C compil warnings
int nsteps = NSTEPS;
int nsteps2 = NSTEPS; int nsteps = NSTEPS;
double step = (s_start-s_end)/(nsteps-1); int nsteps2 = NSTEPS;
double step2 = (s_start2-s_end2)/(nsteps2-1); double step = (s_start - s_end) / (nsteps - 1);
while( (step * max(el1.xrad, el1.yrad)) > 0.1*NM_PER_MIL double step2 = (s_start2 - s_end2) / (nsteps2 - 1);
&& (step2 * len2) > 0.1*NM_PER_MIL )
while( ( step * max( el1.xrad, el1.yrad ) ) > 0.1 * NM_PER_MIL
&& (step2 * len2) > 0.1 * NM_PER_MIL )
{ {
step = (s_start-s_end)/(nsteps-1); step = (s_start - s_end) / (nsteps - 1);
for( int i=0; i<nsteps; i++ )
for( int i = 0; i<nsteps; i++ )
{ {
double s; double s;
if( i < nsteps-1 )
s = s_start - i*step; if( i < nsteps - 1 )
s = s_start - i * step;
else else
s = s_end; s = s_end;
double x = el1.Center.X + el1.xrad*cos(s);
double y = el1.Center.Y + el1.yrad*sin(s); double x = el1.Center.X + el1.xrad * cos( s );
double y = el1.Center.Y + el1.yrad * sin( s );
// if not an arc, use s2 as fractional distance along line // if not an arc, use s2 as fractional distance along line
step2 = (s_start2-s_end2)/(nsteps2-1); step2 = (s_start2 - s_end2) / (nsteps2 - 1);
for( int i2=0; i2<nsteps2; i2++ )
for( int i2 = 0; i2<nsteps2; i2++ )
{ {
double s2; double s2;
if( i2 < nsteps2-1 )
s2 = s_start2 - i2*step2; if( i2 < nsteps2 - 1 )
s2 = s_start2 - i2 * step2;
else else
s2 = s_end2; s2 = s_end2;
double x2, y2; double x2, y2;
if( !bArcs ) if( !bArcs )
{ {
x2 = xi + (xf-xi)*s2; x2 = xi + (xf - xi) * s2;
y2 = yi + (yf-yi)*s2; y2 = yi + (yf - yi) * s2;
} }
else else
{ {
x2 = el2.Center.X + el2.xrad*cos(s2); x2 = el2.Center.X + el2.xrad* cos( s2 );
y2 = el2.Center.Y + el2.yrad*sin(s2);
y2 = el2.Center.Y + el2.yrad* sin( s2 );
} }
double d = Distance( (int) x, (int) y, (int) x2, (int) y2 ); double d = Distance( (int) x, (int) y, (int) x2, (int) y2 );
if( d < dmin ) if( d < dmin )
{ {
dmin = d; dmin = d;
xmin = x; xmin = x;
ymin = y; ymin = y;
smin = s; smin = s;
smin2 = s2; smin2 = s2;
} }
} }
} }
if( step > step2 ) if( step > step2 )
{ {
s_start = min(el1.theta1, smin + step); s_start = min( el1.theta1, smin + step );
s_end = max(el1.theta2, smin - step); s_end = max( el1.theta2, smin - step );
step = (s_start - s_end)/nsteps; step = (s_start - s_end) / nsteps;
} }
else else
{ {
s_start2 = min(th1, smin2 + step2); s_start2 = min( th1, smin2 + step2 );
s_end2 = max(th2, smin2 - step2); s_end2 = max( th2, smin2 - step2 );
step2 = (s_start2 - s_end2)/nsteps2; step2 = (s_start2 - s_end2) / nsteps2;
} }
} }
if( x ) if( x )
*x = (int) xmin; *x = (int) xmin;
if( y ) if( y )
*y = (int) ymin; *y = (int) ymin;
return max(0, (int)dmin-w1/2-w2/2); // allow for widths
return max( 0, (int) dmin - w1 / 2 - w2 / 2 ); // allow for widths
} }
...@@ -919,33 +1072,39 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, ...@@ -919,33 +1072,39 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1,
// if b > DBL_MAX/10, assume vertical line at x = a // if b > DBL_MAX/10, assume vertical line at x = a
// returns closest point on line in xp, yp // returns closest point on line in xp, yp
// //
double GetPointToLineDistance( double a, double b, int x, int y, double * xpp, double * ypp ) double GetPointToLineDistance( double a, double b, int x, int y, double* xpp, double* ypp )
{ {
if( b > DBL_MAX/10 ) if( b > DBL_MAX / 10 )
{ {
// vertical line // vertical line
if( xpp && ypp ) if( xpp && ypp )
{ {
*xpp = a; *xpp = a;
*ypp = y; *ypp = y;
} }
return abs(a-x);
return abs( a - x );
} }
// find c,d such that (x,y) lies on y = c + dx where d=(-1/b) // find c,d such that (x,y) lies on y = c + dx where d=(-1/b)
double d = -1.0/b; double d = -1.0 / b;
double c = (double)y-d*x; double c = (double) y - d * x;
// find nearest point to (x,y) on line through (xi,yi) to (xf,yf) // find nearest point to (x,y) on line through (xi,yi) to (xf,yf)
double xp = (a-c)/(d-b); double xp = (a - c) / (d - b);
double yp = a + b*xp; double yp = a + b * xp;
if( xpp && ypp ) if( xpp && ypp )
{ {
*xpp = xp; *xpp = xp;
*ypp = yp; *ypp = yp;
} }
// find distance // find distance
return Distance( x, y, (int) xp, (int) yp ); return Distance( x, y, (int) xp, (int) yp );
} }
/***********************************************************************************/ /***********************************************************************************/
double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int yf ) double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int yf )
/***********************************************************************************/ /***********************************************************************************/
...@@ -979,14 +1138,17 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int ...@@ -979,14 +1138,17 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int
{ {
// oblique segment // oblique segment
// find a,b such that (xi,yi) and (xf,yf) lie on y = a + bx // find a,b such that (xi,yi) and (xf,yf) lie on y = a + bx
double b = (double)(yf-yi)/(xf-xi); double b = (double) (yf - yi) / (xf - xi);
double a = (double)yi-b*xi; double a = (double) yi - b * xi;
// find c,d such that (x,y) lies on y = c + dx where d=(-1/b) // find c,d such that (x,y) lies on y = c + dx where d=(-1/b)
double d = -1.0/b; double d = -1.0 / b;
double c = (double)y-d*x; double c = (double) y - d * x;
// find nearest point to (x,y) on line through (xi,yi) to (xf,yf) // find nearest point to (x,y) on line through (xi,yi) to (xf,yf)
double xp = (a-c)/(d-b); double xp = (a - c) / (d - b);
double yp = a + b*xp; double yp = a + b * xp;
// find distance // find distance
if( InRange( xp, xi, xf ) && InRange( yp, yi, yf ) ) if( InRange( xp, xi, xf ) && InRange( yp, yi, yf ) )
return Distance( x, y, (int) xp, (int) yp ); return Distance( x, y, (int) xp, (int) yp );
...@@ -995,11 +1157,12 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int ...@@ -995,11 +1157,12 @@ double GetPointToLineSegmentDistance( int x, int y, int xi, int yi, int xf, int
} }
} }
// test for value within range // test for value within range
// //
bool InRange( double x, double xi, double xf ) bool InRange( double x, double xi, double xf )
{ {
if( xf>xi ) if( xf > xi )
{ {
if( x >= xi && x <= xf ) if( x >= xi && x <= xf )
return true; return true;
...@@ -1009,187 +1172,234 @@ bool InRange( double x, double xi, double xf ) ...@@ -1009,187 +1172,234 @@ bool InRange( double x, double xi, double xf )
if( x >= xf && x <= xi ) if( x >= xf && x <= xi )
return true; return true;
} }
return false; return false;
} }
// Get distance between 2 points // Get distance between 2 points
// //
double Distance( int x1, int y1, int x2, int y2 ) double Distance( int x1, int y1, int x2, int y2 )
{ {
double d; double dx = x1 - x2;
d = sqrt( (double)(x1-x2)*(x1-x2) + (double)(y1-y2)*(y1-y2) ); double dy = y1 - y2;
double d = sqrt( dx * dx + dy * dy );
if( d > INT_MAX || d < INT_MIN ) if( d > INT_MAX || d < INT_MIN )
{ {
wxASSERT(0); wxASSERT( 0 );
} }
return (int)d;
// wxASSERT( d <= INT_MAX && d >= INT_MIN );
return int( d );
} }
// this finds approximate solutions // this finds approximate solutions
// note: this works best if el2 is smaller than el1 // note: this works best if el2 is smaller than el1
// //
int GetArcIntersections( EllipseKH * el1, EllipseKH * el2, int GetArcIntersections( EllipseKH* el1, EllipseKH* el2,
double * x1, double * y1, double * x2, double * y2 ) double* x1, double* y1, double* x2, double* y2 )
{ {
if( el1->theta2 > el1->theta1 ) if( el1->theta2 > el1->theta1 )
{ {
wxASSERT(0); wxASSERT( 0 );
} }
if( el2->theta2 > el2->theta1 ) if( el2->theta2 > el2->theta1 )
{ {
wxASSERT(0); wxASSERT( 0 );
} }
const int NSTEPS = 32; const int NSTEPS = 32;
double xret[2], yret[2]; double xret[2], yret[2];
double xscale = 1.0 / el1->xrad;
double yscale = 1.0 / el1->yrad;
double xscale = 1.0/el1->xrad;
double yscale = 1.0/el1->yrad;
// now transform params of second ellipse into reference frame // now transform params of second ellipse into reference frame
// with origin at center if first ellipse, // with origin at center if first ellipse,
// scaled so the first ellipse is a circle of radius = 1.0 // scaled so the first ellipse is a circle of radius = 1.0
double xo = (el2->Center.X - el1->Center.X)*xscale; double xo = (el2->Center.X - el1->Center.X) * xscale;
double yo = (el2->Center.Y - el1->Center.Y)*yscale; double yo = (el2->Center.Y - el1->Center.Y) * yscale;
double xr = el2->xrad*xscale; double xr = el2->xrad * xscale;
double yr = el2->yrad*yscale; double yr = el2->yrad * yscale;
// now test NSTEPS positions in arc, moving clockwise (ie. decreasing theta) // now test NSTEPS positions in arc, moving clockwise (ie. decreasing theta)
double step = M_PI/((NSTEPS-1)*2.0); double step = M_PI / ( (NSTEPS - 1) * 2.0 );
double d_prev=0; double d_prev = 0;
double th_interp; double th_interp;
double th1; double th1;
int n = 0;
for( int i=0; i<NSTEPS; i++ ) int n = 0;
for( int i = 0; i<NSTEPS; i++ )
{ {
double theta; double theta;
if( i < NSTEPS-1 )
theta = el2->theta1 - i*step; if( i < NSTEPS - 1 )
theta = el2->theta1 - i * step;
else else
theta = el2->theta2; theta = el2->theta2;
double x = xo + xr*cos(theta);
double y = yo + yr*sin(theta); double x = xo + xr * cos( theta );
double d = 1.0 - sqrt(x*x + y*y);
double y = yo + yr * sin( theta );
double d = 1.0 - sqrt( x * x + y * y );
if( i>0 ) if( i>0 )
{ {
bool bInt = false; bool bInt = false;
if( d >= 0.0 && d_prev <= 0.0 ) if( d >= 0.0 && d_prev <= 0.0 )
{ {
th_interp = theta + (step*(-d_prev))/(d-d_prev); th_interp = theta + ( step * (-d_prev) ) / (d - d_prev);
bInt = true; bInt = true;
} }
else if( d <= 0.0 && d_prev >= 0.0 ) else if( d <= 0.0 && d_prev >= 0.0 )
{ {
th_interp = theta + (step*d_prev)/(d_prev-d); th_interp = theta + (step * d_prev) / (d_prev - d);
bInt = true; bInt = true;
} }
if( bInt ) if( bInt )
{ {
x = xo + xr*cos(th_interp); x = xo + xr * cos( th_interp );
y = yo + yr*sin(th_interp);
y = yo + yr * sin( th_interp );
th1 = atan2( y, x ); th1 = atan2( y, x );
if( th1 <= el1->theta1 && th1 >= el1->theta2 ) if( th1 <= el1->theta1 && th1 >= el1->theta2 )
{ {
xret[n] = x*el1->xrad + el1->Center.X; xret[n] = x * el1->xrad + el1->Center.X;
yret[n] = y*el1->yrad + el1->Center.Y; yret[n] = y * el1->yrad + el1->Center.Y;
n++; n++;
if( n > 2 ) if( n > 2 )
{ {
wxASSERT(0); wxASSERT( 0 );
} }
} }
} }
} }
d_prev = d; d_prev = d;
} }
if( x1 ) if( x1 )
*x1 = xret[0]; *x1 = xret[0];
if( y1 ) if( y1 )
*y1 = yret[0]; *y1 = yret[0];
if( x2 ) if( x2 )
*x2 = xret[1]; *x2 = xret[1];
if( y2 ) if( y2 )
*y2 = yret[1]; *y2 = yret[1];
return n; return n;
} }
// this finds approximate solution // this finds approximate solution
// //
//double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2, // double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2,
double GetArcClearance( EllipseKH * el1, EllipseKH * el2, double GetArcClearance( EllipseKH* el1, EllipseKH* el2,
double * x1, double * y1 ) double* x1, double* y1 )
{ {
const int NSTEPS = 32; const int NSTEPS = 32;
if( el1->theta2 > el1->theta1 ) if( el1->theta2 > el1->theta1 )
{ {
wxASSERT(0); wxASSERT( 0 );
} }
if( el2->theta2 > el2->theta1 ) if( el2->theta2 > el2->theta1 )
{ {
wxASSERT(0); wxASSERT( 0 );
} }
// test multiple positions in both arcs, moving clockwise (ie. decreasing theta) // test multiple positions in both arcs, moving clockwise (ie. decreasing theta)
double th_start = el1->theta1; double th_start = el1->theta1;
double th_end = el1->theta2; double th_end = el1->theta2;
double th_start2 = el2->theta1; double th_start2 = el2->theta1;
double th_end2 = el2->theta2; double th_end2 = el2->theta2;
double dmin = DBL_MAX; double dmin = DBL_MAX;
double xmin=0, ymin=0, thmin=0, thmin2=0; double xmin = 0, ymin = 0, thmin = 0, thmin2 = 0;
int nsteps = NSTEPS; int nsteps = NSTEPS;
int nsteps2 = NSTEPS; int nsteps2 = NSTEPS;
double step = (th_start-th_end)/(nsteps-1); double step = (th_start - th_end) / (nsteps - 1);
double step2 = (th_start2-th_end2)/(nsteps2-1); double step2 = (th_start2 - th_end2) / (nsteps2 - 1);
while( (step * max(el1->xrad, el1->yrad)) > 1.0*NM_PER_MIL
&& (step2 * max(el2->xrad, el2->yrad)) > 1.0*NM_PER_MIL ) while( ( step * max( el1->xrad, el1->yrad ) ) > 1.0 * NM_PER_MIL
&& ( step2 * max( el2->xrad, el2->yrad ) ) > 1.0 * NM_PER_MIL )
{ {
step = (th_start-th_end)/(nsteps-1); step = (th_start - th_end) / (nsteps - 1);
for( int i=0; i<nsteps; i++ )
for( int i = 0; i<nsteps; i++ )
{ {
double theta; double theta;
if( i < nsteps-1 )
theta = th_start - i*step; if( i < nsteps - 1 )
theta = th_start - i * step;
else else
theta = th_end; theta = th_end;
double x = el1->Center.X + el1->xrad*cos(theta);
double y = el1->Center.Y + el1->yrad*sin(theta); double x = el1->Center.X + el1->xrad * cos( theta );
step2 = (th_start2-th_end2)/(nsteps2-1);
for( int i2=0; i2<nsteps2; i2++ ) double y = el1->Center.Y + el1->yrad * sin( theta );
step2 = (th_start2 - th_end2) / (nsteps2 - 1);
for( int i2 = 0; i2<nsteps2; i2++ )
{ {
double theta2; double theta2;
if( i2 < nsteps2-1 )
theta2 = th_start2 - i2*step2; if( i2 < nsteps2 - 1 )
theta2 = th_start2 - i2 * step2;
else else
theta2 = th_end2; theta2 = th_end2;
double x2 = el2->Center.X + el2->xrad*cos(theta2);
double y2 = el2->Center.Y + el2->yrad*sin(theta2); double x2 = el2->Center.X + el2->xrad * cos( theta2 );
double d = Distance( (int) x, (int) y, (int) x2, (int) y2 ); double y2 = el2->Center.Y + el2->yrad * sin( theta2 );
double d = Distance( (int) x, (int) y, (int) x2, (int) y2 );
if( d < dmin ) if( d < dmin )
{ {
dmin = d; dmin = d;
xmin = x; xmin = x;
ymin = y; ymin = y;
thmin = theta; thmin = theta;
thmin2 = theta2; thmin2 = theta2;
} }
} }
} }
if( step > step2 ) if( step > step2 )
{ {
th_start = min(el1->theta1, thmin + step); th_start = min( el1->theta1, thmin + step );
th_end = max(el1->theta2, thmin - step); th_end = max( el1->theta2, thmin - step );
step = (th_start - th_end)/nsteps; step = (th_start - th_end) / nsteps;
} }
else else
{ {
th_start2 = min(el2->theta1, thmin2 + step2); th_start2 = min( el2->theta1, thmin2 + step2 );
th_end2 = max(el2->theta2, thmin2 - step2); th_end2 = max( el2->theta2, thmin2 - step2 );
step2 = (th_start2 - th_end2)/nsteps2; step2 = (th_start2 - th_end2) / nsteps2;
} }
} }
if( x1 ) if( x1 )
*x1 = xmin; *x1 = xmin;
if( y1 ) if( y1 )
*y1 = ymin; *y1 = ymin;
return dmin; return dmin;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment