admin 发表于 2024-7-24 22:43:53

IsPointInBoundary在边界内

                                    //-------------------------------------//
                                    //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 += 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 + dTol < pPt && pOutline + dTol < pPt ) {
            continue;
      }
      if ( pOutline - dTol > pPt && pOutline - dTol > pPt ) {
            continue;
      }

            // Check for Horizontal Segment
      if ( fabs( pOutline - pPt ) < 0.1 && fabs( pOutline - pPt ) < 0.1 ) {
                // If the Point is On this Segment, then use the fAllowOnPerimeter Variable
            if ( IsPointOnLine( pPt, pOutline, pOutline, 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, pOutline )) {
                  nPrev = nNum - 2;
                } else {
                  nPrev = nNum - 1;
                }
            } else {
                nPrev = nKnt - 2;
            }
            if ( nKnt < nNum-1 ) {
                nNext = nKnt + 1;
            } else {
                nNext = 1;
            }
            if ( pOutline + dTol < pPt && pOutline + dTol < pPt ) {
                continue;
            } else if ( pOutline + dTol > pPt && pOutline + dTol > pPt ) {
                continue;
            }
      }

            // Check for Segment totally to the Left
      if ( pOutline + dTol < pPt && pOutline + dTol < pPt ) {
            if ( fabs( pOutline - pPt ) < 0.1 ) {
                if ( fabs( pOutline - pPt ) > 0.1 ) {
                        // Skip this if it's a Horizontal Segment
                  Cpoint( pInt, pOutline );
                  goto ProcessEndPoint;
                }
            }
            nNumLft++;
            continue;
      }

            // Check for Segment totally to the right
      if ( pOutline - dTol > pPt && pOutline - dTol > pPt ) {
            if ( fabs( pOutline - pPt ) < 0.1 ) {
                if ( fabs( pOutline - pPt ) > 0.1 ) {
                        // Skip this if it's a Horizontal Segment
                  Cpoint( pInt, pOutline );
                  goto ProcessEndPoint;
                }
            }
            nNumRgt++;
            continue;
      }

            // If the Point is On this Segment, then use the fAllowOnPerimeter Variable
      if ( IsPointOnLine( pPt, pOutline, pOutline, 0.05 )) {
            if ( fAllowOnPerimeter ) {
                return( TRUE );
            } else {
                return( FALSE );
            }
      }

            // Intersect with the Segment
      if ( acdbInters( pPt, pPt1, pOutline, pOutline, FALSE, pInt ) != RTNORM ) {
            continue;
      }
            // If it's one of the Vertex Points, process it Differently
      if ( AboutEqualPts( pInt, pOutline )) {
ProcessEndPoint:
            if ( pOutline + dTol < pPt ) {
                if ( nKnt < nNum-1 ) {
                  if ( pOutline + dTol < pPt || fabs( pOutline - pPt ) < 0.1 ) {
                        goto ProcessInt;
                  }
                } else {
                  if ( pOutline + dTol < pPt || fabs( pOutline - pPt ) < 0.1 ) {
                        goto ProcessInt;
                  }
                }
            } else {
                if ( nKnt < nNum-1 ) {
                  if ( pOutline - dTol > pPt || fabs( pOutline - pPt ) < 0.1 ) {
                        goto ProcessInt;
                  }
                } else {
                  if ( pOutline - dTol > pPt || fabs( pOutline - pPt ) < 0.1 ) {
                        goto ProcessInt;
                  }
                }
            }
      } else {
ProcessInt:
                // See if it's to the Left or Right
            if ( pInt < pPt ) {
                nNumLft++;
            } else {
                nNumRgt++;
            }
      }
    }

//acutPrintf( _T("pPt=(%f,%f), nNumLft=%d, nNumRgt=%d\n"), pPt, pPt, 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 );
}

页: [1]
查看完整版本: IsPointInBoundary在边界内