- UID
- 5043
- 积分
- 1347
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-5-13
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
打开VS2015,使用ObjectARX向导创建新工程,名为BaseGeometryClass。
(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);
- //删除首尾两条曲线,其他段的曲线添加到模型空间
- 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:
项目完整代码:
https://pan.baidu.com/s/1M5MsYoQFIvF04oCSOv68yA
参考资料:
《AutoCAD ObjectARX(VC)开发基础与实例教程》
---------------------
作者:李燕良
来源:CSDN
原文:https://blog.csdn.net/qq_40416052/article/details/82961341
版权声明:本文为博主原创文章,转载请附上博文链接!
|
|