|
//-------------------------------------//
// 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 );
}
|
|