|
- //-------------------------------------//
- // IsPointInBoundary //
- //-------------------------------------//
- int IsPointInBoundary( ads_point pPt, ads_point *pOutline, int nNum, int fAllowOnPerimeter )
- {
- int nNumLft; // Number of Boundary Intersections to the Left of this Point
- int nNumRgt; // Number of Boundary Intersections to the Right of this Point
- int nKnt;
- int nPrev;
- int nNext;
- ads_point pPt1; // Used with acdbInters()
- ads_point pInt; // Intersection Point returned by acdbInters()
- double dTol = 0.1 * pSettings.dMetricScl;
- // Create pPt1 to Be Horzontal from pPt
- Cpoint( pPt1, pPt );
- pPt1[X] += 120.0;
- // For Each Line of the Outline, Intersect a Horizontal line through pPt
- nNumLft = 0;
- nNumRgt = 0;
- for( nKnt=1; nKnt<nNum; nKnt++ ) {
- // Make sure there's potential for a horizontal intersection
- if ( pOutline[nKnt-1][Y] + dTol < pPt[Y] && pOutline[nKnt][Y] + dTol < pPt[Y] ) {
- continue;
- }
- if ( pOutline[nKnt-1][Y] - dTol > pPt[Y] && pOutline[nKnt][Y] - dTol > pPt[Y] ) {
- continue;
- }
- // Check for Horizontal Segment
- if ( fabs( pOutline[nKnt][Y] - pPt[Y] ) < 0.1 && fabs( pOutline[nKnt-1][Y] - pPt[Y] ) < 0.1 ) {
- // If the Point is On this Segment, then use the fAllowOnPerimeter Variable
- if ( IsPointOnLine( pPt, pOutline[nKnt-1], pOutline[nKnt], 0.05 )) {
- if ( fAllowOnPerimeter ) {
- return( TRUE );
- } else {
- return( FALSE );
- }
- }
- // Horizontal, if the Points Before and After this Segment are both Below or both Above,
- // Skip this segment
- if ( nKnt-2 < 0 ) {
- if ( AboutEqualPts( pOutline[nNum-1], pOutline[0] )) {
- nPrev = nNum - 2;
- } else {
- nPrev = nNum - 1;
- }
- } else {
- nPrev = nKnt - 2;
- }
- if ( nKnt < nNum-1 ) {
- nNext = nKnt + 1;
- } else {
- nNext = 1;
- }
- if ( pOutline[nPrev][Y] + dTol < pPt[Y] && pOutline[nNext][Y] + dTol < pPt[Y] ) {
- continue;
- } else if ( pOutline[nPrev][Y] + dTol > pPt[Y] && pOutline[nNext][Y] + dTol > pPt[Y] ) {
- continue;
- }
- }
- // Check for Segment totally to the Left
- if ( pOutline[nKnt-1][X] + dTol < pPt[X] && pOutline[nKnt][X] + dTol < pPt[X] ) {
- if ( fabs( pOutline[nKnt][Y] - pPt[Y] ) < 0.1 ) {
- if ( fabs( pOutline[nKnt-1][Y] - pPt[Y] ) > 0.1 ) {
- // Skip this if it's a Horizontal Segment
- Cpoint( pInt, pOutline[nKnt] );
- goto ProcessEndPoint;
- }
- }
- nNumLft++;
- continue;
- }
- // Check for Segment totally to the right
- if ( pOutline[nKnt-1][X] - dTol > pPt[X] && pOutline[nKnt][X] - dTol > pPt[X] ) {
- if ( fabs( pOutline[nKnt][Y] - pPt[Y] ) < 0.1 ) {
- if ( fabs( pOutline[nKnt-1][Y] - pPt[Y] ) > 0.1 ) {
- // Skip this if it's a Horizontal Segment
- Cpoint( pInt, pOutline[nKnt] );
- goto ProcessEndPoint;
- }
- }
- nNumRgt++;
- continue;
- }
- // If the Point is On this Segment, then use the fAllowOnPerimeter Variable
- if ( IsPointOnLine( pPt, pOutline[nKnt-1], pOutline[nKnt], 0.05 )) {
- if ( fAllowOnPerimeter ) {
- return( TRUE );
- } else {
- return( FALSE );
- }
- }
- // Intersect with the Segment
- if ( acdbInters( pPt, pPt1, pOutline[nKnt-1], pOutline[nKnt], FALSE, pInt ) != RTNORM ) {
- continue;
- }
- // If it's one of the Vertex Points, process it Differently
- if ( AboutEqualPts( pInt, pOutline[nKnt] )) {
- ProcessEndPoint:
- if ( pOutline[nKnt-1][Y] + dTol < pPt[Y] ) {
- if ( nKnt < nNum-1 ) {
- if ( pOutline[nKnt+1][Y] + dTol < pPt[Y] || fabs( pOutline[nKnt+1][Y] - pPt[Y] ) < 0.1 ) {
- goto ProcessInt;
- }
- } else {
- if ( pOutline[1][Y] + dTol < pPt[Y] || fabs( pOutline[1][Y] - pPt[Y] ) < 0.1 ) {
- goto ProcessInt;
- }
- }
- } else {
- if ( nKnt < nNum-1 ) {
- if ( pOutline[nKnt+1][Y] - dTol > pPt[Y] || fabs( pOutline[nKnt+1][Y] - pPt[Y] ) < 0.1 ) {
- goto ProcessInt;
- }
- } else {
- if ( pOutline[1][Y] - dTol > pPt[Y] || fabs( pOutline[1][Y] - pPt[Y] ) < 0.1 ) {
- goto ProcessInt;
- }
- }
- }
- } else {
- ProcessInt:
- // See if it's to the Left or Right
- if ( pInt[X] < pPt[X] ) {
- nNumLft++;
- } else {
- nNumRgt++;
- }
- }
- }
- //acutPrintf( _T("pPt=(%f,%f), nNumLft=%d, nNumRgt=%d\n"), pPt[X], pPt[Y], nNumLft, nNumRgt );
- // To be Inside the Boundary, both nNumLft and nNumRgt MUST be ODD
- if (( nNumLft % 2 ) == 0 ) {
- return( FALSE );
- }
- if (( nNumRgt % 2 ) == 0 ) {
- return( FALSE );
- }
- return( TRUE );
- }
复制代码 |
|