From 72d4b2353b3939b97da7296ff46c2b5f5589a94c Mon Sep 17 00:00:00 2001 From: Dick Hollenbeck Date: Tue, 17 Apr 2012 09:18:14 -0500 Subject: [PATCH] uncrustify math_for_graphics, add copyright legacy_plugin.h --- common/base_screen.cpp | 6 +- pcbnew/legacy_plugin.h | 7 +- polygon/math_for_graphics.cpp | 900 +++++++++++++++++++++------------- 3 files changed, 561 insertions(+), 352 deletions(-) diff --git a/common/base_screen.cpp b/common/base_screen.cpp index cd0439c9ff..4a6e13cd7c 100644 --- a/common/base_screen.cpp +++ b/common/base_screen.cpp @@ -94,7 +94,7 @@ double BASE_SCREEN::GetScalingFactor() const } -void BASE_SCREEN::SetScalingFactor(double aScale ) +void BASE_SCREEN::SetScalingFactor( double aScale ) { double zoom = aScale; @@ -150,12 +150,10 @@ bool BASE_SCREEN::SetZoom( double coeff ) bool BASE_SCREEN::SetNextZoom() { - size_t i; - if( m_ZoomList.IsEmpty() || m_Zoom >= m_ZoomList.Last() ) 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] ) { diff --git a/pcbnew/legacy_plugin.h b/pcbnew/legacy_plugin.h index c62201c120..046395671b 100644 --- a/pcbnew/legacy_plugin.h +++ b/pcbnew/legacy_plugin.h @@ -4,7 +4,8 @@ /* * 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 + * Copyright (C) 2012 KiCad Developers, see change_log.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -59,8 +60,6 @@ struct FPL_CACHE; */ class LEGACY_PLUGIN : public PLUGIN { - friend struct FPL_CACHE; - public: //--------------------------------------------------- @@ -272,6 +271,8 @@ protected: /// we only cache one footprint library for now, this determines which one. void cacheLib( const wxString& aLibraryPath ); + + friend struct FPL_CACHE; }; #endif // LEGACY_PLUGIN_H_ diff --git a/polygon/math_for_graphics.cpp b/polygon/math_for_graphics.cpp index 94f612a15f..10498b2fbc 100644 --- a/polygon/math_for_graphics.cpp +++ b/polygon/math_for_graphics.cpp @@ -29,14 +29,16 @@ bool TestLineHit( int xi, int yi, int xf, int yf, int x, int y, double dist ) if( xf==xi ) { // vertical segment - dd = fabs( (double)(x-xi) ); + dd = fabs( (double) (x - xi) ); + if( ddyi && yyi) || (yfyf && yxi && xxi) || (xfxf && x0.7 ) + dd = sqrt( (x - xp) * (x - xp) + (y - yp) * (y - yp) ); + + if( fabs( b )>0.7 ) { // line segment more vertical than horizontal if( ddyi && ypyi) || (yfyf && yp xxi && yyf > yyi ) { - xo = xxf; - yo = yyi; - el->theta1 = M_PI; - el->theta2 = M_PI/2.0; + xo = xxf; + yo = yyi; + el->theta1 = M_PI; + el->theta2 = M_PI / 2.0; } else if( xxf < xxi && yyf > yyi ) { - xo = xxi; - yo = yyf; - el->theta1 = -M_PI/2.0; - el->theta2 = -M_PI; + xo = xxi; + yo = yyf; + el->theta1 = -M_PI / 2.0; + el->theta2 = -M_PI; } else if( xxf < xxi && yyf < yyi ) { - xo = xxf; - yo = yyi; - el->theta1 = 0.0; - el->theta2 = -M_PI/2.0; + xo = xxf; + yo = yyi; + el->theta1 = 0.0; + el->theta2 = -M_PI / 2.0; } else if( xxf > xxi && yyf < yyi ) { - xo = xxi; - yo = yyf; - el->theta1 = M_PI/2.0; - el->theta2 = 0.0; + xo = xxi; + yo = yyf; + el->theta1 = M_PI / 2.0; + el->theta2 = 0.0; } - el->Center.X = xo; - el->Center.Y = yo; - el->xrad = abs(xf-xi); - el->yrad = abs(yf-yi); + + el->Center.X = xo; + el->Center.Y = yo; + el->xrad = abs( xf - xi ); + el->yrad = abs( yf - yi ); #if 0 - el->Phi = 0.0; - el->MaxRad = el->xrad; - el->MinRad = el->yrad; + el->Phi = 0.0; + el->MaxRad = el->xrad; + el->MinRad = el->yrad; + if( el->MaxRad < el->MinRad ) { - el->MaxRad = el->yrad; - el->MinRad = el->xrad; - el->Phi = M_PI/2.0; + el->MaxRad = el->yrad; + el->MinRad = el->xrad; + el->Phi = M_PI / 2.0; } + #endif return 0; } + // find intersections between line segment (xi,yi) to (xf,yf) // and line segment (xi2,yi2) to (xf2,yf2) // 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 // returns coords of intersections in arrays x[2], y[2] // int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, - int xi2, int yi2, int xf2, int yf2, int style2, - double x[], double y[] ) + int xi2, int yi2, int xf2, int yf2, int style2, + double x[], double y[] ) { - double xr[12], yr[12]; - int iret = 0; + double xr[12], yr[12]; + int iret = 0; - if( max(xi,xf) < min(xi2,xf2) - || min(xi,xf) > max(xi2,xf2) - || max(yi,yf) < min(yi2,yf2) - || min(yi,yf) > max(yi2,yf2) ) + if( max( xi, xf ) < min( xi2, xf2 ) + || min( xi, xf ) > max( xi2, xf2 ) + || max( yi, yf ) < min( yi2, yf2 ) + || min( yi, yf ) > max( yi2, yf2 ) ) return 0; if( style != CPolyLine::STRAIGHT && style2 != CPolyLine::STRAIGHT ) @@ -166,18 +177,20 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, { if( x && y ) { - x[0] = xi; - y[0] = yi; + x[0] = xi; + y[0] = yi; } + return 1; } else if( style != style2 && xi == xf2 && yi == yf2 && xf == xi2 && yf == yi2 ) { if( x && y ) { - x[0] = xi; - y[0] = yi; + x[0] = xi; + y[0] = yi; } + return 1; } } @@ -185,48 +198,63 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, if( style == CPolyLine::STRAIGHT && style2 == CPolyLine::STRAIGHT ) { // both straight-line segments - int x, y; - bool bYes = TestForIntersectionOfStraightLineSegments( xi, yi, xf, yf, xi2, yi2, xf2, yf2, &x, &y ); + int x, y; + bool bYes = TestForIntersectionOfStraightLineSegments( xi, + yi, + xf, + yf, + xi2, + yi2, + xf2, + yf2, + &x, + &y ); + if( !bYes ) return 0; - xr[0] = x; - yr[0] = y; - iret = 1; + + xr[0] = x; + yr[0] = y; + iret = 1; } else if( style == CPolyLine::STRAIGHT ) { // first segment is straight, second segment is an arc - int ret; - double x1r, y1r, x2r, y2r; + int ret; + double x1r, y1r, x2r, y2r; + if( xf == xi ) { // vertical first segment - double a = xi; - double b = DBL_MAX/2.0; + double a = xi; + double b = DBL_MAX / 2.0; ret = FindLineSegmentIntersection( a, b, xi2, yi2, xf2, yf2, style2, - &x1r, &y1r, &x2r, &y2r ); + &x1r, &y1r, &x2r, &y2r ); } else { - double b = (double)(yf-yi)/(double)(xf-xi); - double a = yf - b*xf; + double b = (double) (yf - yi) / (double) (xf - xi); + double a = yf - b * xf; ret = FindLineSegmentIntersection( a, b, xi2, yi2, xf2, yf2, style2, - &x1r, &y1r, &x2r, &y2r ); + &x1r, &y1r, &x2r, &y2r ); } + if( ret == 0 ) return 0; + if( InRange( x1r, xi, xf ) && InRange( y1r, yi, yf ) ) { - xr[iret] = x1r; - yr[iret] = y1r; + xr[iret] = x1r; + yr[iret] = y1r; iret++; } + if( ret == 2 ) { if( InRange( x2r, xi, xf ) && InRange( y2r, yi, yf ) ) { - xr[iret] = x2r; - yr[iret] = y2r; + xr[iret] = x2r; + yr[iret] = y2r; iret++; } } @@ -234,37 +262,41 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, else if( style2 == CPolyLine::STRAIGHT ) { // first segment is an arc, second segment is straight - int ret; - double x1r, y1r, x2r, y2r; + int ret; + double x1r, y1r, x2r, y2r; + if( xf2 == xi2 ) { // vertical second segment - double a = xi2; - double b = DBL_MAX/2.0; + double a = xi2; + double b = DBL_MAX / 2.0; ret = FindLineSegmentIntersection( a, b, xi, yi, xf, yf, style, - &x1r, &y1r, &x2r, &y2r ); + &x1r, &y1r, &x2r, &y2r ); } else { - double b = (double)(yf2-yi2)/(double)(xf2-xi2); - double a = yf2 - b*xf2; + double b = (double) (yf2 - yi2) / (double) (xf2 - xi2); + double a = yf2 - b * xf2; ret = FindLineSegmentIntersection( a, b, xi, yi, xf, yf, style, - &x1r, &y1r, &x2r, &y2r ); + &x1r, &y1r, &x2r, &y2r ); } + if( ret == 0 ) return 0; + if( InRange( x1r, xi2, xf2 ) && InRange( y1r, yi2, yf2 ) ) { - xr[iret] = x1r; - yr[iret] = y1r; + xr[iret] = x1r; + yr[iret] = y1r; iret++; } + if( ret == 2 ) { if( InRange( x2r, xi2, xf2 ) && InRange( y2r, yi2, yf2 ) ) { - xr[iret] = x2r; - yr[iret] = y2r; + xr[iret] = x2r; + yr[iret] = y2r; iret++; } } @@ -272,28 +304,33 @@ int FindSegmentIntersections( int xi, int yi, int xf, int yf, int style, else { // both segments are arcs - EllipseKH el1; - EllipseKH el2; + EllipseKH el1; + EllipseKH el2; MakeEllipseFromArc( xi, yi, xf, yf, style, &el1 ); MakeEllipseFromArc( xi2, yi2, xf2, yf2, style2, &el2 ); - int n; - if( el1.xrad+el1.yrad > el2.xrad+el2.yrad ) + int n; + + if( el1.xrad + el1.yrad > el2.xrad + el2.yrad ) n = GetArcIntersections( &el1, &el2 ); else n = GetArcIntersections( &el2, &el1 ); + iret = n; } + if( x && y ) { - for( int i=0; i DBL_MAX/10, assume vertical line at x = a // 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, // if no intersection, returns min distance in dist // 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 ) + double* x1, double* y1, double* x2, double* y2, + double* dist ) { - double xx = 0, yy = 0; //Init made to avoid C compil "uninitialized" warning - bool bVert = false; - if( b > DBL_MAX/10.0 ) + double xx = 0, yy = 0; // Init made to avoid C compil "uninitialized" warning + bool bVert = false; + + if( b > DBL_MAX / 10.0 ) bVert = true; if( xf != xi ) @@ -318,36 +356,42 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int { // horizontal or oblique straight segment // put into form y = c + dx; - double d = (double)(yf-yi)/(double)(xf-xi); - double c = yf - d*xf; + double d = (double) (yf - yi) / (double) (xf - xi); + double c = yf - d * xf; + if( bVert ) { // if vertical line, easy if( InRange( a, xi, xf ) ) { *x1 = a; - *y1 = c + d*a; + *y1 = c + d * a; return 1; } else { if( dist ) - *dist = min( abs(a-xi), abs(a-xf) ); + *dist = min( abs( a - xi ), abs( a - xf ) ); + return 0; } } - if( fabs(b-d) < 1E-12 ) + + if( fabs( b - d ) < 1E-12 ) { // parallel lines if( dist ) { *dist = GetPointToLineDistance( a, b, xi, xf ); } - return 0; // lines parallel + + return 0; // lines parallel } + // calculate intersection - xx = (c-a)/(b-d); - yy = a + b*(xx); + xx = (c - a) / (b - d); + yy = a + b * (xx); + // see if intersection is within the line segment if( yf == yi ) { @@ -368,6 +412,7 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int // arc (quadrant of ellipse) // convert to clockwise arc int xxi, xxf, yyi, yyf; + if( style == CPolyLine::ARC_CCW ) { xxi = xf; @@ -382,39 +427,45 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int yyi = yi; yyf = yf; } + // 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 ) { - xo = xxf; - yo = yyi; + xo = xxf; + yo = yyi; } else if( xxf < xxi && yyf > yyi ) { - xo = xxi; - yo = yyf; + xo = xxi; + yo = yyf; } else if( xxf < xxi && yyf < yyi ) { - xo = xxf; - yo = yyi; + xo = xxf; + yo = yyi; } else if( xxf > xxi && yyf < yyi ) { - xo = xxi; - yo = yyf; + xo = xxi; + yo = yyf; } - rx = fabs( (double)(xxi-xxf) ); - ry = fabs( (double)(yyi-yyf) ); - bool test; - double xx1, xx2, yy1, yy2, aa; + + rx = fabs( (double) (xxi - xxf) ); + ry = fabs( (double) (yyi - yyf) ); + bool test; + double xx1, xx2, yy1, yy2, aa; + if( bVert ) { // shift vertical line to coordinate system of ellipse aa = a - xo; test = FindVerticalLineEllipseIntersections( rx, ry, aa, &yy1, &yy2 ); + if( !test ) return 0; + // shift back to PCB coordinates yy1 += yo; yy2 += yo; @@ -424,66 +475,76 @@ int FindLineSegmentIntersection( double a, double b, int xi, int yi, int xf, int else { // 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 ); + if( !test ) return 0; + // shift back to PCB coordinates - yy1 = aa + b*xx1; + yy1 = aa + b * xx1; xx1 += xo; yy1 += yo; - yy2 = aa + b*xx2; + yy2 = aa + b * xx2; xx2 += xo; yy2 += yo; } + int npts = 0; + if( (xxf>xxi && xx1xxi) || (xxfxxf) ) { if( (yyf>yyi && yy1yyi) || (yyfyyf) ) { - *x1 = xx1; - *y1 = yy1; - npts = 1; + *x1 = xx1; + *y1 = yy1; + npts = 1; } } + if( (xxf>xxi && xx2xxi) || (xxfxxf) ) { if( (yyf>yyi && yy2yyi) || (yyfyyf) ) { if( npts == 0 ) { - *x1 = xx2; - *y1 = yy2; - npts = 1; + *x1 = xx2; + *y1 = yy2; + npts = 1; } else { - *x2 = xx2; - *y2 = yy2; - npts = 2; + *x2 = xx2; + *y2 = yy2; + npts = 2; } } } + return npts; } else - wxASSERT(0); + wxASSERT( 0 ); } else { // vertical line segment if( bVert ) return 0; - xx = xi; - yy = a + b*xx; + + xx = xi; + yy = a + b * xx; + if( (yy>=yi && yy>yf) || (yy<=yi && yy 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 x2i, int y2i, int x2f, int y2f, int style2, int w2, - int max_cl, int * x, int * y ) + int x2i, int y2i, int x2f, int y2f, int style2, int w2, + int max_cl, int* x, int* y ) { // check clearance between bounding rectangles - int test = max_cl + w1/2 + w2/2; - if( min(x1i,x1f)-max(x2i,x2f) > test ) + int test = max_cl + w1 / 2 + w2 / 2; + + if( min( x1i, x1f ) - max( x2i, x2f ) > test ) return max_cl; - if( min(x2i,x2f)-max(x1i,x1f) > test ) + + if( min( x2i, x2f ) - max( x1i, x1f ) > test ) return max_cl; - if( min(y1i,y1f)-max(y2i,y2f) > test ) + + if( min( y1i, y1f ) - max( y2i, y2f ) > test ) return max_cl; - if( min(y2i,y2f)-max(y1i,y1f) > test ) + + if( min( y2i, y2f ) - max( y1i, y1f ) > test ) return max_cl; if( style1 == CPolyLine::STRAIGHT && style1 == CPolyLine::STRAIGHT ) { // both segments are straight lines - int xx, yy; - double dd; + int xx, yy; + double dd; TestForIntersectionOfStraightLineSegments( x1i, y1i, x1f, y1f, - x2i, y2i, x2f, y2f, &xx, &yy, &dd ); - int d = max( 0, (int)dd - w1/2 - w2/2 ); + x2i, y2i, x2f, y2f, &xx, &yy, &dd ); + int d = max( 0, (int) dd - w1 / 2 - w2 / 2 ); + if( x ) *x = xx; + if( y ) *y = yy; + return d; } // not both straight-line segments // see if segments intersect - double xr[2]; - double yr[2]; - test = FindSegmentIntersections( x1i, y1i, x1f, y1f, style1, x2i, y2i, x2f, y2f, style2, xr, yr ); + double xr[2]; + double yr[2]; + test = + FindSegmentIntersections( x1i, y1i, x1f, y1f, style1, x2i, y2i, x2f, y2f, style2, xr, yr ); + if( test ) { if( x ) *x = (int) xr[0]; + if( y ) *y = (int) yr[0]; + return 0; } // at least one segment is an arc - EllipseKH el1; - EllipseKH el2; - bool bArcs; - int xi=0, yi=0, xf=0, yf=0; + EllipseKH el1; + EllipseKH el2; + bool bArcs; + int xi = 0, yi = 0, xf = 0, yf = 0; + if( style2 == CPolyLine::STRAIGHT ) { // style1 = arc, style2 = straight @@ -798,10 +930,10 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, else if( style1 == CPolyLine::STRAIGHT ) { // style2 = arc, style1 = straight - xi = x1i; - yi = y1i; - xf = x1f; - yf = y1f; + xi = x1i; + yi = y1i; + xf = x1f; + yf = y1f; MakeEllipseFromArc( x2i, y2i, x2f, y2f, style2, &el1 ); bArcs = false; } @@ -812,106 +944,127 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, MakeEllipseFromArc( x2i, y2i, x2f, y2f, style2, &el2 ); bArcs = true; } + const int NSTEPS = 32; if( el1.theta2 > el1.theta1 ) { - wxASSERT(0); + wxASSERT( 0 ); } + if( bArcs && el2.theta2 > el2.theta1 ) { - wxASSERT(0); + wxASSERT( 0 ); } // test multiple points in both segments - double th1; - double th2; - double len2; + double th1; + double th2; + double len2; + if( bArcs ) { - th1 = el2.theta1; - th2 = el2.theta2; - len2 = max(el2.xrad, el2.yrad); + th1 = el2.theta1; + th2 = el2.theta2; + len2 = max( el2.xrad, el2.yrad ); } else { - th1 = 1.0; - th2 = 0.0; - len2 = abs(xf-xi)+abs(yf-yi); + th1 = 1.0; + th2 = 0.0; + len2 = abs( xf - xi ) + abs( yf - yi ); } - double s_start = el1.theta1; - double s_end = el1.theta2; - double s_start2 = th1; - double s_end2 = th2; - 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; - double step = (s_start-s_end)/(nsteps-1); - double step2 = (s_start2-s_end2)/(nsteps2-1); - while( (step * max(el1.xrad, el1.yrad)) > 0.1*NM_PER_MIL - && (step2 * len2) > 0.1*NM_PER_MIL ) + double s_start = el1.theta1; + double s_end = el1.theta2; + double s_start2 = th1; + double s_end2 = th2; + 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; + double step = (s_start - s_end) / (nsteps - 1); + double step2 = (s_start2 - s_end2) / (nsteps2 - 1); + + 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); - for( int i=0; i step2 ) { - s_start = min(el1.theta1, smin + step); - s_end = max(el1.theta2, smin - step); - step = (s_start - s_end)/nsteps; + s_start = min( el1.theta1, smin + step ); + s_end = max( el1.theta2, smin - step ); + step = (s_start - s_end) / nsteps; } else { - s_start2 = min(th1, smin2 + step2); - s_end2 = max(th2, smin2 - step2); - step2 = (s_start2 - s_end2)/nsteps2; + s_start2 = min( th1, smin2 + step2 ); + s_end2 = max( th2, smin2 - step2 ); + step2 = (s_start2 - s_end2) / nsteps2; } } + if( x ) *x = (int) xmin; + if( y ) *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, // if b > DBL_MAX/10, assume vertical line at x = a // 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 if( xpp && ypp ) { - *xpp = a; - *ypp = y; + *xpp = a; + *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) - double d = -1.0/b; - double c = (double)y-d*x; + double d = -1.0 / b; + double c = (double) y - d * x; + // find nearest point to (x,y) on line through (xi,yi) to (xf,yf) - double xp = (a-c)/(d-b); - double yp = a + b*xp; + double xp = (a - c) / (d - b); + double yp = a + b * xp; + if( xpp && ypp ) { - *xpp = xp; - *ypp = yp; + *xpp = xp; + *ypp = yp; } + // find distance return Distance( x, y, (int) xp, (int) yp ); } + /***********************************************************************************/ 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 { // oblique segment // find a,b such that (xi,yi) and (xf,yf) lie on y = a + bx - double b = (double)(yf-yi)/(xf-xi); - double a = (double)yi-b*xi; + double b = (double) (yf - yi) / (xf - xi); + double a = (double) yi - b * xi; + // find c,d such that (x,y) lies on y = c + dx where d=(-1/b) - double d = -1.0/b; - double c = (double)y-d*x; + double d = -1.0 / b; + double c = (double) y - d * x; + // find nearest point to (x,y) on line through (xi,yi) to (xf,yf) - double xp = (a-c)/(d-b); - double yp = a + b*xp; + double xp = (a - c) / (d - b); + double yp = a + b * xp; + // find distance if( InRange( xp, xi, xf ) && InRange( yp, yi, yf ) ) 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 } } + // test for value within range // bool InRange( double x, double xi, double xf ) { - if( xf>xi ) + if( xf > xi ) { if( x >= xi && x <= xf ) return true; @@ -1009,187 +1172,234 @@ bool InRange( double x, double xi, double xf ) if( x >= xf && x <= xi ) return true; } + return false; } + // Get distance between 2 points // double Distance( int x1, int y1, int x2, int y2 ) { - double d; - d = sqrt( (double)(x1-x2)*(x1-x2) + (double)(y1-y2)*(y1-y2) ); + double dx = x1 - x2; + double dy = y1 - y2; + + double d = sqrt( dx * dx + dy * dy ); + 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 // note: this works best if el2 is smaller than el1 // -int GetArcIntersections( EllipseKH * el1, EllipseKH * el2, - double * x1, double * y1, double * x2, double * y2 ) +int GetArcIntersections( EllipseKH* el1, EllipseKH* el2, + double* x1, double* y1, double* x2, double* y2 ) { if( el1->theta2 > el1->theta1 ) { - wxASSERT(0); + wxASSERT( 0 ); } + if( el2->theta2 > el2->theta1 ) { - wxASSERT(0); + wxASSERT( 0 ); } - const int NSTEPS = 32; - double xret[2], yret[2]; + const int NSTEPS = 32; + 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 // with origin at center if first ellipse, // scaled so the first ellipse is a circle of radius = 1.0 - double xo = (el2->Center.X - el1->Center.X)*xscale; - double yo = (el2->Center.Y - el1->Center.Y)*yscale; - double xr = el2->xrad*xscale; - double yr = el2->yrad*yscale; + double xo = (el2->Center.X - el1->Center.X) * xscale; + double yo = (el2->Center.Y - el1->Center.Y) * yscale; + double xr = el2->xrad * xscale; + double yr = el2->yrad * yscale; + // now test NSTEPS positions in arc, moving clockwise (ie. decreasing theta) - double step = M_PI/((NSTEPS-1)*2.0); - double d_prev=0; - double th_interp; - double th1; - int n = 0; - for( int i=0; itheta1 - i*step; + + if( i < NSTEPS - 1 ) + theta = el2->theta1 - i * step; else theta = el2->theta2; - double x = xo + xr*cos(theta); - double y = yo + yr*sin(theta); - double d = 1.0 - sqrt(x*x + y*y); + + double x = xo + xr * cos( theta ); + + double y = yo + yr * sin( theta ); + + double d = 1.0 - sqrt( x * x + y * y ); + if( i>0 ) { bool bInt = false; + 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; } 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; } + if( bInt ) { - x = xo + xr*cos(th_interp); - y = yo + yr*sin(th_interp); + x = xo + xr * cos( th_interp ); + + y = yo + yr * sin( th_interp ); + th1 = atan2( y, x ); + if( th1 <= el1->theta1 && th1 >= el1->theta2 ) { - xret[n] = x*el1->xrad + el1->Center.X; - yret[n] = y*el1->yrad + el1->Center.Y; + xret[n] = x * el1->xrad + el1->Center.X; + yret[n] = y * el1->yrad + el1->Center.Y; n++; + if( n > 2 ) { - wxASSERT(0); + wxASSERT( 0 ); } } } } + d_prev = d; } + if( x1 ) *x1 = xret[0]; + if( y1 ) *y1 = yret[0]; + if( x2 ) *x2 = xret[1]; + if( y2 ) *y2 = yret[1]; + return n; } + // this finds approximate solution // -//double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2, -double GetArcClearance( EllipseKH * el1, EllipseKH * el2, - double * x1, double * y1 ) +// double GetSegmentClearance( EllipseKH * el1, EllipseKH * el2, +double GetArcClearance( EllipseKH* el1, EllipseKH* el2, + double* x1, double* y1 ) { const int NSTEPS = 32; if( el1->theta2 > el1->theta1 ) { - wxASSERT(0); + wxASSERT( 0 ); } + if( el2->theta2 > el2->theta1 ) { - wxASSERT(0); + wxASSERT( 0 ); } // test multiple positions in both arcs, moving clockwise (ie. decreasing theta) - double th_start = el1->theta1; - double th_end = el1->theta2; - double th_start2 = el2->theta1; - double th_end2 = el2->theta2; - double dmin = DBL_MAX; - double xmin=0, ymin=0, thmin=0, thmin2=0; + double th_start = el1->theta1; + double th_end = el1->theta2; + double th_start2 = el2->theta1; + double th_end2 = el2->theta2; + double dmin = DBL_MAX; + double xmin = 0, ymin = 0, thmin = 0, thmin2 = 0; - int nsteps = NSTEPS; - int nsteps2 = NSTEPS; - double step = (th_start-th_end)/(nsteps-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 ) + int nsteps = NSTEPS; + int nsteps2 = NSTEPS; + double step = (th_start - th_end) / (nsteps - 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 ) { - step = (th_start-th_end)/(nsteps-1); - for( int i=0; iCenter.X + el1->xrad*cos(theta); - double y = el1->Center.Y + el1->yrad*sin(theta); - step2 = (th_start2-th_end2)/(nsteps2-1); - for( int i2=0; i2Center.X + el1->xrad * cos( theta ); + + double y = el1->Center.Y + el1->yrad * sin( theta ); + + step2 = (th_start2 - th_end2) / (nsteps2 - 1); + + for( int i2 = 0; i2Center.X + el2->xrad*cos(theta2); - double y2 = el2->Center.Y + el2->yrad*sin(theta2); - double d = Distance( (int) x, (int) y, (int) x2, (int) y2 ); + + double x2 = el2->Center.X + el2->xrad * cos( theta2 ); + double y2 = el2->Center.Y + el2->yrad * sin( theta2 ); + double d = Distance( (int) x, (int) y, (int) x2, (int) y2 ); + if( d < dmin ) { - dmin = d; - xmin = x; - ymin = y; - thmin = theta; - thmin2 = theta2; + dmin = d; + xmin = x; + ymin = y; + thmin = theta; + thmin2 = theta2; } } } + if( step > step2 ) { - th_start = min(el1->theta1, thmin + step); - th_end = max(el1->theta2, thmin - step); - step = (th_start - th_end)/nsteps; + th_start = min( el1->theta1, thmin + step ); + th_end = max( el1->theta2, thmin - step ); + step = (th_start - th_end) / nsteps; } else { - th_start2 = min(el2->theta1, thmin2 + step2); - th_end2 = max(el2->theta2, thmin2 - step2); - step2 = (th_start2 - th_end2)/nsteps2; + th_start2 = min( el2->theta1, thmin2 + step2 ); + th_end2 = max( el2->theta2, thmin2 - step2 ); + step2 = (th_start2 - th_end2) / nsteps2; } } + if( x1 ) *x1 = xmin; + if( y1 ) *y1 = ymin; + return dmin; }