天气与日历 切换到窄版

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

[ObjectARX]-几何类的使用

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
[code]1)计算直线几何类和 圆弧几何类的交点。

注册命令InsertsetWith,实现代码:

static void AAAMyGroupIntersectWith() {
                // 计算所要计算交点的几何类对象
                AcGeCircArc2d geArc(AcGePoint2d::kOrigin, 50, 0, 6);
                        //AcGePoint2d::kOrigin返回一个坐标为(0,0)的点
                        //圆弧的圆心为(0,0),半径为50,起始角0;终止角6

                AcGeLine2d geLine(AcGePoint2d::kOrigin, AcGePoint2d(10, 10));
                        //构造一条穿过(0,0)和(10, 10)的无界线
               
                //计算并输出交点
                AcGePoint2d point1, point2;
                int num;
                if (geArc.intersectWith(geLine, num, point1, point2))//如果存在交点,intersectWith返回Adesk::kTrue
                {
                        acutPrintf(TEXT("\n直线和圆弧有%d个交点."), num);
                        if (num > 0)
                        {
                                acutPrintf(TEXT("\n交点1坐标:(%.4f,%.4f)."), point1.x, point1.y);
                        }
                        if (num > 1)
                        {
                                acutPrintf(TEXT("\n交点2坐标:(%.4f,%.4f)."), point2.x, point2.y);
                        }
                }

        }
效果:

  加载AutoCAD2018,执行命令IntersectWith:



快捷键Ctrl+F2 打开文本窗口:

直线和圆弧有2个交点.
交点1坐标:(35.3553,35.3553).
交点2坐标:(-35.3553,-35.3553).
(2)注册一个新命令LineDistance

  用于提示用户在图形窗口中选择两条直线,计算两条直线之间的最短距离,并在命令窗口中选择两条直线,计算两条直线之阿的最短距离并在命令窗口中输出:

static void AAAMyGroupLineDistance() {
                // 提示用户选择所要计算距离的两条直线
                AcDbObjectIdArray lineIds;
                if (CSelectUtil::PromptSelectEnts(TEXT("\n选择两条直线:"), AcDbLine::desc(), lineIds))
                {

                        if (lineIds.length() != 2)
                        {
                                acutPrintf(TEXT("\n必须选择两条直线."));
                                return;
                        }

                        //将直线转换成对应的几何类对象
                        AcGeLineSeg2d geLine1 = GetGeLineObj(lineIds[0]);
                        AcGeLineSeg2d geLine2 = GetGeLineObj(lineIds[1]);

                        //计算并输出两者之间的最短距离
                        double distance = geLine1.distanceTo(geLine2);
                        acutPrintf(TEXT("\n两条直线之间的最短距离为:%.4f."), distance);
                }
        }
其中,

GetGeLineObj函数的实现:

        //根据输入的实体ID获得相同参数的AcGeLineSeg2d对象
        static AcGeLineSeg2d GetGeLineObj(AcDbObjectId lineId)
        {
                AcGeLineSeg2d geLine; //AcGeLineSeg2d:在二维空间中表示一个有界的线段。
                AcDbLine *pLine = NULL;
                if (acdbOpenObject(pLine, lineId, AcDb::kForRead) == Acad::eOk)
                                                 //指针pLine指向打开的对象lineId
                {
                        geLine.set(ToPoint2d(pLine->startPoint()),
                                ToPoint2d(pLine->endPoint()));
                        pLine->close();
                }
                return geLine;
        }
ToPoint2d函数的实现:

        // 二维点和三维点之间的转换
        static AcGePoint2d ToPoint2d(const AcGePoint3d &point3d)
        {
                return AcGePoint2d(point3d.x, point3d.y);
        }
PromptSelectEnts函数的实现:

bool CSelectUtil::PromptSelectEnts(const TCHAR* prompt, AcRxClass* classDesc, AcDbObjectIdArray &entIds)
{
        std::vector<AcRxClass*> vecClassDesc;
        vecClassDesc.push_back(classDesc);

        return PromptSelectEnts(prompt, vecClassDesc, entIds);
}

bool CSelectUtil::PromptSelectEnts(const TCHAR* prompt, const std::vector<AcRxClass*> &classDescs, AcDbObjectIdArray &entIds)
{
        // 初始化
        entIds.setLogicalLength(0);

        // 提示用户选择实体
        ads_name sset;
        int result = 0;
        acutPrintf(prompt);
        result = acedSSGet(NULL, NULL, NULL, NULL, sset);

        if (result != RTNORM)
        {
                return false;
        }

        // 取得选择集的长度
        long length = 0;
        acedSSLength(sset, (Adesk::Int32 *)&length);

        // 遍历选择集
        Acad::ErrorStatus es;
        AcDbEntity* pEnt = NULL;
        for (long i = 0; i < length; i++)
        {
                ads_name ename;
                acedSSName(sset, i, ename);

                AcDbObjectId curEntId;
                es = acdbGetObjectId(curEntId, ename);
                if (es != Acad::eOk)
                {
                        continue;
                }

                // 打开实体
                es = acdbOpenObject(pEnt, curEntId, AcDb::kForRead);
                if (es != Acad::eOk)
                {
                        continue;
                }

                // 判断当前实体是否是指定的实体类型
                for (int j = 0; j < (int)classDescs.size(); j++)
                {
                        if (pEnt->isKindOf(classDescs[j]))
                        {
                                entIds.append(pEnt->objectId());
                                break;
                        }
                }

                pEnt->close();        // 关闭实体
        }
        acedSSFree(sset);        // 释放选择集

        return (entIds.length() > 0);
}
效果:

在AutoCAD2018中创建两条直线,执行命令LineDistance,得到两直线的最短距离。



(3)注册新命令CurveBoolean

  用于获得两条曲线相交之后形成的边界线:

命令CurveBoolean 函数的实现:

//获得两条曲线相交之后形成的边界线
        static void AAAMyGroupCurveBoolean() {
                //选择所要操作的两条多段线
                AcDbObjectIdArray polyIds;
                if (CSelectUtil::PromptSelectEnts(TEXT("\n选择两条多段线:"),
                        AcDbPolyline::desc(), polyIds))//获得polyIds,返回bool
                {
                        if (polyIds.length() != 2)
                        {
                                acutPrintf(TEXT("\n必须选择两条多段线."));
                                return;
                        }

                        //获得两条多段线的交点
                        bool bOk = false;
                        AcDbPolyline *pPoly1 = NULL, *pPoly2 = NULL;
                        if (acdbOpenObject(pPoly1, polyIds[0], AcDb::kForWrite) == Acad::eOk)
                        {             //pPoly1指向打开的对象polyIds[0]

                                if (acdbOpenObject(pPoly2, polyIds[1], AcDb::kForWrite) ==
                                        Acad::eOk)
                                {
                                        AcGePoint3dArray intPoints;
                                        pPoly1->intersectWith(pPoly2, AcDb::kOnBothOperands,
                                                intPoints);//pPoly2:pPoly1实体将与之相交的实体
                                        //kOnBothOperands:不要扩展任何一个实体。这只会计算出两个实体
                                        //的几何相交的交点
                                        //intPoints:表示输出的交点

                                        if (intPoints.length() >= 2)
                                        {
                                                bOk = true;
                                        }
                                        else
                                        {
                                                acutPrintf(TEXT("\n多段线之间交点少于2个,无法进行计算."));
                                        }

                                        //根据交点和参数值获得交点之间的曲线
                                        if (bOk)
                                        {
                                                GetCurveBetweenIntPoints(pPoly1, intPoints);
                                                GetCurveBetweenIntPoints(pPoly2, intPoints);

                                                pPoly2->erase(); //擦除对象
                                        }
                                        pPoly2->close(); //关闭对象,自从它被打开以来,对对象所做的所有更改
                                                         //都被提交到数据库中

                                }

                                if (bOk)
                                {
                                        pPoly1->erase();
                                }

                                pPoly1->close();
                        }
                }

        }
其中:

GetCurveBetweenIntPoints函数的实现:

static void GetCurveBetweenIntPoints(AcDbPolyline *pPoly,
                const AcGePoint3dArray &intPoints)
        {
                AcDbVoidPtrArray curves;
                pPoly->getSplitCurves(intPoints, curves);
                    //在曲线上输入参数的数组intPoints
                    //返回到新创建的实体的指针curves,这些实体是原始的子曲线

                for (int i = 0; i < curves.length(); i++)
                {
                        AcDbCurve *pCurve = static_cast<AcDbCurve*>(curves[i]);

                        //删除首尾两条曲线,其他段的曲线添加到模型空间
                        if (i == 0 || i == curves.length() - 1)
                        {
                                delete pCurve;
                        }
                        else
                        {
                                AcDbObjectId curveId = CDwgDatabaseUtil::PostToModelSpace(pCurve);
                        }
                }
        }
其中:

PostToModelSpace函数的声明:

        static AcDbObjectId PostToModelSpace(AcDbEntity *pEnt,
               AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase());
PostToModelSpace函数的实现:

AcDbObjectId CDwgDatabaseUtil::PostToModelSpace(AcDbEntity *pEnt, AcDbDatabase *pDb)
{
        // 检查输入参数的有效性
        assert(pEnt);                // 等效于assert (pEnt != NULL);

                                                // 获得当前图形数据库的块表
        AcDbBlockTable *pBlkTbl = NULL;
        pDb->getBlockTable(pBlkTbl, AcDb::kForRead);

        // 获得模型空间对应的块表记录
        AcDbBlockTableRecord *pBlkTblRcd = NULL;
        pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd, AcDb::kForWrite);
        pBlkTbl->close();

        // 将实体添加到模型空间的块表记录
        AcDbObjectId entId;
        Acad::ErrorStatus es = pBlkTblRcd->appendAcDbEntity(entId, pEnt);
        if (es != Acad::eOk)
        {
                pBlkTblRcd->close();
                delete pEnt;        // 添加失败时,要delete
                pEnt = NULL;

                return AcDbObjectId::kNull;
        }

        // 关闭模型空间块表记录和实体
        pBlkTblRcd->close();
        pEnt->close();

        return entId;
}
效果:

绘制两条多段线,执行命令CurveBoolean:[/code]

[code]原文链接:https://blog.csdn.net/qq_40416052/article/details/82961341[/code]

 

 

 

 

[ObjectARX]-几何类的使用
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-1 11:48 , Processed in 0.158776 second(s), 28 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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