天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 67|回复: 0

构造射线算法,测试点是否在曲线内

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
[code]enum IncidenceType {
    kIncidenceToLeft = 0,
    kIncidenceToRight = 1,
    kIncidenceToFront =2,
    kIncidenceUnknown,
};

IncidenceType CurveIncidence(AcDbCurve* pCurve, double param, AcGeVector3d dir, AcGeVector3d normal )
{
    AcGeVector3d deriv1;
    pCurve->getFirstDeriv( param, deriv1 );

    if( deriv1.isParallelTo( dir ))
    { // need second degree analysis
        AcGeVector3d deriv2;
        pCurve->getSecondDeriv( param, deriv2 );

        if( deriv2.isZeroLength() || deriv2.isParallelTo( dir ) )
        {
            return kIncidenceToFront;
        }
        else if(deriv2.crossProduct( dir ).dotProduct( normal ) < 0 )
        {
            return kIncidenceToRight;
        }
        else
        {
            return kIncidenceToLeft;
        }
    }

    if( deriv1.crossProduct( dir ).dotProduct( normal ) < 0 )
    {
        return kIncidenceToLeft;
    }
    else
    {
        return kIncidenceToRight;
    }
}

Adesk::Boolean IsInsideCurve(AcDbCurve*pCurve, AcGePoint3d testPt )
{
    if(pCurve== NULL || !pCurve->isClosed())
    {    // cannot be inside
        return Adesk::kFalse;
    }

    AcDb2dPolyline* p2dPoly = AcDb2dPolyline::cast(pCurve);

    if( p2dPoly != NULL && p2dPoly->polyType() != AcDb::k2dSimplePoly )
    { // Not supported
        return Adesk::kFalse;
    }

    AcGePoint3d ptOnCurve;
    Acad::ErrorStatus es = pCurve->getClosestPointTo(testPt, ptOnCurve );

    if( testPt == ptOnCurve )
    {
        return Adesk::kTrue;
    }

    AcGePlane plane;
    AcDb::Planarity planarity; // check its planar
    es = pCurve->getPlane(plane, planarity );

    if( es != Acad::eOk || planarity != AcDb::kPlanar )
    { // 曲线不共面
        return Adesk::kFalse;
    }

    // make the test ray from the plane
    AcGeVector3d normal = plane.normal();
    AcGeVector3d testVector = normal.perpVector();
    AcDbRay ray;
    ray.setBasePoint(testPt);
    ray.setUnitDir(testVector);

    AcGePoint3dArray IntersectionPoints;
    // fire the ray at the curve
    es = pCurve->intersectWith(&ray, AcDb::kOnBothOperands, IntersectionPoints);

    if(es != Acad::eOk)
    {
        return Adesk::kFalse;
    }

    int numberOfInters = IntersectionPoints.length();

    if (numberOfInters == 0)
    { // must be outside
        return Adesk::kFalse;
    }

    int nGlancingHits = 0;
    double epsilon = 2e-6;

    for( int i=0;i < numberOfInters; i++ )
    { // get the first point, and get its parameter
        AcGePoint3d hitPt = IntersectionPoints;
        double hitParam;
        es = pCurve->getParamAtPoint(hitPt, hitParam );

        if(es != Acad::eOk)
        {
            return Adesk::kFalse;
        }

        double inParam = hitParam - epsilon;
        double outParam = hitParam + epsilon;
        IncidenceType inIncidence = CurveIncidence(pCurve, inParam, testVector, normal );
        IncidenceType outIncidence = CurveIncidence(pCurve, outParam, testVector, normal );

        if ((inIncidence == kIncidenceToRight && outIncidence == kIncidenceToLeft) ||
            ( inIncidence == kIncidenceToLeft && outIncidence == kIncidenceToRight ) )
        {
            nGlancingHits ++;
        }
    }

    return (( numberOfInters + nGlancingHits) % 2 == 1);
}

void utilsisinside()
{
    ads_name eName;
    ads_point pt;

    if( RTNORM != ads_entsel( "\nPlease pick a curve ", eName, pt) )
    {
        return;
    }

    AcDbObjectId curveId;
    acdbGetObjectId( curveId, eName );
    AcDbCurve* pCurve = NULL;
    acdbOpenObject(pCurve, curveId, AcDb::kForRead );

    if( pCurve == NULL )
    {
        return;
    }

    while( RTNORM == ads_getpoint( NULL, "\nPlease pick a point ", pt ) )
    {
        acdbUcs2Wcs( pt, pt, Adesk::kFalse );
        Adesk::Boolean isIn;
        isIn = IsInsideCurve( pCurve, asPnt3d( pt ) );
        ads_printf("\n%s", isIn ? "INSIDE OR ON" : "OUTSIDE" );
    }
    pCurve->close();
}[/code]

 

 

 

 

构造射线算法,测试点是否在曲线内
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 11:44 , Processed in 0.148429 second(s), 24 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表