- 积分
- 29208
- 明经币
- 个
- 注册时间
- 2007-4-24
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 gzxl 于 2025-8-11 10:42 编辑
保持起点不变及面积不变的情况下
继上一个贴: getSplitCurves 应用之:经量多段线添加顶点(支持弧段)
http://bbs.mjtd.com/thread-193321-1-1.html
此处采用两点和圆心点计算凸度方式
 - // 多段线添加顶点(支持弧段)
- Acad::ErrorStatus es = Acad::eOk;
- ads_name ename;
- AcGePoint3d ptPick;
- if (RTNORM != acedEntSel(_T("\n请单选需要添加顶点的经量多段线:\n"), ename, asDblArray(ptPick)))
- {
- acutPrintf(_T("\n您退出了选择!"));
- return;
- }
- AcDbObjectId entId = AcDbObjectId::kNull;
- es = acdbGetObjectId(entId, ename);
- if (es != Acad::eOk)
- {
- acutPrintf(_T("\n获取对象ID失败,错误码: es=%s\n"), acadErrorStatusText(es));
- return;
- }
- AcDbEntity* pEnt = NULL;
- es = acdbOpenAcDbEntity(pEnt, entId, AcDb::kForRead);
- if (es != Acad::eOk)
- {
- acutPrintf(_T("\n打开对象失败,错误码: es=%s\n"), acadErrorStatusText(es));
- return;
- }
- // 检查选择对象是否是一条轻量多段线
- AcDbPolyline* pPolyline = AcDbPolyline::cast(pEnt);
- if (!pPolyline)
- {
- acutPrintf(_T("\n您选择的对象不是经量多段线\n"));
- pEnt->close();
- return;
- }
- // 多段线是否闭合
- bool bClosed = pPolyline->isClosed();
- // 多段线颜色
- int nColorIndex = pPolyline->colorIndex();
- // 多段线全局宽度
- double dWidth = 0.0;
- pPolyline->getConstantWidth(dWidth);
- // 强制转换为曲线类
- AcDbCurve* pCurve = static_cast<AcDbCurve*>(pPolyline);
- // 用户输入
- TCHAR szKword1[10];
- acedInitGet(0, _T("A B"));
- int nRe1 = acedGetKword(_T("输入添加顶点方式选项[拾取点(A)/两节点间按指定距离(B)]:"), szKword1);
- if (nRe1 != RTNORM)
- {
- pCurve->close();
- pEnt->close();
- }
- int nCmdecho = 0, nOsmode = 0;
- // 回显系统变量, 0-关闭回显 1-打开回显
- GetVar(_T("cmdecho"), nCmdecho);
- // 关闭回显
- SetVar(_T("cmdecho"), 0);
- // 添加顶点点集
- AcGePoint3dArray addPoints;
- if (_tcscmp(szKword1, _T("A")) == 0)
- {
- // 命令标志 ACRX_CMD_USEPICKSET | ACRX_CMD_REDRAW
- // 对象捕捉系统变量
- GetVar(_T("osmode"), nOsmode);
- // 设置对象捕捉系统变量(最近点和中点)
- SetVar(_T("osmode"), 514);
- ads_name ss, aname;
- // 创建一个选择集
- acedSSAdd(NULL, NULL, ss);
- // 从 objectID 获取 ads name
- acdbGetAdsName(aname, entId);
- // 将选定的实体 adsname 添加到选择集
- acedSSAdd(aname, ss, ss);
- // 选择集夹点
- acedSSSetFirst(ss, NULL);
- AcGePoint3d ptClick;
- while (acedGetPoint(0, _T("\n指定添加顶点的位置:\n"), asDblArray(ptClick)) == RTNORM)
- {
- // 转换为WCS坐标
- AcGePoint3d ptWcs;
- acdbUcs2Wcs(asDblArray(ptClick), asDblArray(ptWcs), Adesk::kFalse);
- // 获取曲线上离指定点最近的点(在 WCS 上)
- AcGePoint3d ptNearest;
- pCurve->getClosestPointTo(ptWcs, ptNearest);
- double dParam = 0.0;
- pCurve->getParamAtPoint(ptNearest, dParam);
- int n = (int)dParam;
- AcGePoint3d startVertPt, endVertPt;
- pCurve->getPointAtParam((double)n, startVertPt);
- pCurve->getPointAtParam((double)n + 1, endVertPt);
- double dStartBugle = 0.0, dEndBugle = 0.0;
- pPolyline->getBulgeAt(n, dStartBugle);
- pPolyline->getBulgeAt(n + 1, dEndBugle);
- double dInsertBugle = 0.0;
- if (fabs(dStartBugle) > 1e-6)
- {
- // 通过两点和凸度,求圆心点
- AcGePoint3d ptCenter = GetCenterPoint(startVertPt, endVertPt, dStartBugle);
- // 两点和圆心点,求凸度
- dInsertBugle = GetBulge(ptWcs, endVertPt, ptCenter);
- dStartBugle = GetBulge(startVertPt, ptWcs, ptCenter);
- }
- pPolyline->upgradeOpen();
- pPolyline->setBulgeAt(n, dStartBugle);
- pPolyline->addVertexAt(n + 1, AcGePoint2d(ptWcs.x, ptWcs.y), dInsertBugle, dWidth, dWidth);
- pPolyline->downgradeOpen();
- //acutPrintf(_T("\n起始端点:%.3f,%.3f,%.6f\n"), startvertPt.x, startvertPt.y, dStartBugle);
- //acutPrintf(_T("\n结束端点:%.3f,%.3f,%.6f\n"), endvertPt.x, endvertPt.y, dEndBugle);
- }
- acedSSFree(ss);
- acedSSSetFirst(NULL, NULL);
- pCurve->close();
- pEnt->close();
- // 还原对象捕捉系统变量
- SetVar(_T("osmode"), nOsmode);
- }
- else if (_tcscmp(szKword1, _T("B")) == 0)
- {
- TCHAR szKword2[10];
- acedInitGet(0, _T("C D E"));
- int nRe2 = acedGetKword(_T("输入添加顶点的多段线子段类型[直线段(C)/弧段(D)/全部(E)]:"), szKword2);
- if (nRe2 != RTNORM)
- {
- pCurve->close();
- pEnt->close();
- return;
- }
- double dDist = 0.0;
- if (!GetReal(_T("\n请输入指定间距"), 1.0, 1, dDist))
- {
- pCurve->close();
- pEnt->close();
- return;
- }
- // 曲线的起始参数和终点参数
- double startParam, endParam;
- es = pCurve->getStartParam(startParam);
- es = pCurve->getEndParam(endParam);
- for (double i = startParam; i <= endParam; ++i)
- {
- // 由参数获取对应的当前点
- AcGePoint3d ptCurrent;
- es = pCurve->getPointAtParam(i, ptCurrent);
- // 获取当前点的凸度值
- double dBugle = 0.0;
- pPolyline->getBulgeAt((int)i, dBugle);
- // 由参数获取的下一个顶点
- AcGePoint3d ptNext;
- es = pCurve->getPointAtParam(i + 1, ptNext);
- // 获取当前点至起点的距离
- double dLenCurrent = 0.0;
- pCurve->getDistAtPoint(ptCurrent, dLenCurrent);
- // 获取下一个顶点至起点的距离,曲线终点距离需要单独用 getDistAtParam 获取
- double dLenNext = 0.0;
- if (i == (endParam - 1))
- {
- pCurve->getDistAtParam(endParam, dLenNext);
- }
- else
- {
- pCurve->getDistAtPoint(ptNext, dLenNext);
- }
- // 弧段的圆心点
- AcGePoint3d ptCenter;
- // 直线段添加顶点选项
- if (_tcscmp(szKword2, _T("C")) == 0)
- {
- // 当前点的凸度值为零,说明当前线段是直线段
- if (dBugle < 1e-6)
- {
- addPoints.append(ptCurrent);
- GetLineSegmentsPoints(dLenCurrent, dLenNext, dDist, pCurve, addPoints);
- }
- if (fabs(dBugle) > 1e-6)
- {
- addPoints.append(AcGePoint3d(ptCurrent.x, ptCurrent.y, dBugle));
- }
- }
- // 弧段添加顶点选项
- else if (_tcscmp(szKword2, _T("D")) == 0)
- {
- if (dBugle < 1e-6)
- {
- addPoints.append(ptCurrent);
- }
- if (fabs(dBugle) > 1e-6)
- {
- GetArcSegmentsPoints(ptCurrent, ptNext, dBugle, dLenCurrent, dLenNext, dDist, pCurve, addPoints);
- }
- }
- // 直线段和弧段都添加顶点
- else if (_tcscmp(szKword2, _T("E")) == 0)
- {
- // 当前点的凸度值为零,说明当前线段是直线段
- if (dBugle < 1e-6)
- {
- addPoints.append(ptCurrent);
- GetLineSegmentsPoints(dLenCurrent, dLenNext, dDist, pCurve, addPoints);
- }
- else if (fabs(dBugle) > 1e-6)
- {
- GetArcSegmentsPoints(ptCurrent, ptNext, dBugle, dLenCurrent, dLenNext, dDist, pCurve, addPoints);
- }
- }
- }
- if (addPoints.length() > 2)
- {
- AcGePoint3d firstPoint = addPoints.at(0);
- AcGePoint3d lastPoint = addPoints.at(addPoints.length() - 1);
- if (IsEqual(firstPoint, lastPoint))
- {
- addPoints.removeAt(addPoints.length() - 1);
- }
- // 创建新的经量多段线
- int numVertices = addPoints.length();
- AcDbPolyline *pNewPoly = new AcDbPolyline(numVertices);
- for (int i = 0; i < numVertices; i++)
- {
- AcGePoint3d pt = addPoints.at(i);
- pNewPoly->addVertexAt(i, AcGePoint2d(pt.x, pt.y), pt.z, dWidth, dWidth);
- }
- // 如果原多段线是闭合的,则设置新创建的多段线闭合
- if (bClosed)
- {
- pNewPoly->setClosed(Adesk::kTrue);
- }
- pNewPoly->setColorIndex(nColorIndex);
- AcDbObjectId polyId = PostToModelSpace(pNewPoly);
- // 删除原曲线
- pCurve->close();
- if (acdbOpenObject(pEnt, entId, AcDb::kForWrite) == Acad::eOk)
- {
- pEnt->erase();
- pEnt->close();
- }
- acutPrintf(_T("\n添加多段线顶点已完成!\n"));
- }
- }
- // 还原回显系统变量
- SetVar(_T("cmdecho"), nCmdecho);
 - // 两点和圆心点计算凸度方式:多段线删除顶点(支持弧段)
- // 命令标志 ACRX_CMD_USEPICKSET | ACRX_CMD_REDRAW
- Acad::ErrorStatus es = Acad::eOk;
- ads_name ename;
- AcGePoint3d ptPick;
- if (RTNORM != acedEntSel(_T("\n请单选需要添加顶点的经量多段线:\n"), ename, asDblArray(ptPick)))
- {
- acutPrintf(_T("\n您退出了选择!"));
- return;
- }
- AcDbObjectId entId = AcDbObjectId::kNull;
- es = acdbGetObjectId(entId, ename);
- if (es != Acad::eOk)
- {
- acutPrintf(_T("\n获取对象ID失败,错误码: es=%s\n"), acadErrorStatusText(es));
- return;
- }
- AcDbEntity* pEnt = NULL;
- es = acdbOpenAcDbEntity(pEnt, entId, AcDb::kForRead);
- if (es != Acad::eOk)
- {
- acutPrintf(_T("\n打开对象失败,错误码: es=%s\n"), acadErrorStatusText(es));
- return;
- }
- // 检查选择对象是否是一条轻量多段线
- AcDbPolyline* pPolyline = AcDbPolyline::cast(pEnt);
- if (!pPolyline)
- {
- acutPrintf(_T("\n您选择的对象不是经量多段线\n"));
- pEnt->close();
- return;
- }
- // 强制转换为曲线类
- AcDbCurve* pCurve = static_cast<AcDbCurve*>(pPolyline);
- int nCmdecho = 0, nOsmode = 0;
- // 回显系统变量, 0-关闭回显 1-打开回显
- GetVar(_T("cmdecho"), nCmdecho);
- // 关闭回显
- SetVar(_T("cmdecho"), 0);
- // 对象捕捉系统变量
- GetVar(_T("osmode"), nOsmode);
- // 设置对象捕捉系统变量(端点)
- SetVar(_T("osmode"), 1);
- ads_name ss, aname;
- // 创建一个选择集
- acedSSAdd(NULL, NULL, ss);
- // 从 objectID 获取 ads name
- acdbGetAdsName(aname, entId);
- // 将选定的实体 adsname 添加到选择集
- acedSSAdd(aname, ss, ss);
- // 选择集夹点
- acedSSSetFirst(ss, NULL);
- AcGePoint3d ptClick;
- while (acedGetPoint(0, _T("\n指定删除顶点的位置:\n"), asDblArray(ptClick)) == RTNORM)
- {
- // 转换为WCS坐标
- AcGePoint3d ptWcs;
- acdbUcs2Wcs(asDblArray(ptClick), asDblArray(ptWcs), Adesk::kFalse);
- // 获取曲线上离指定点最近的点(在 WCS 上)
- AcGePoint3d ptNearest;
- pCurve->getClosestPointTo(ptWcs, ptNearest);
- // 由参数获取点
- double dParam = 0.0;
- pCurve->getParamAtPoint(ptNearest, dParam);
- int n = (int)dParam;
- AcGePoint3d startVertPt, endVertPt;
- pCurve->getPointAtParam((double)(n - 1), startVertPt);
- pCurve->getPointAtParam((double)(n + 1), endVertPt);
- double dStartBugle = 0.0;
- pPolyline->getBulgeAt(n - 1, dStartBugle);
- double dNewBugle = 0.0;
- if (fabs(dStartBugle) > 1e-6)
- {
- // 通过两点和凸度,求圆心点
- AcGePoint3d ptCenter = GetCenterPoint(startVertPt, ptWcs, dStartBugle);
- // 两点和圆心点,求凸度
- dNewBugle = GetBulge(startVertPt, endVertPt, ptCenter);
- }
- int num = pPolyline->numVerts();
- if (num > 2)
- {
- pPolyline->upgradeOpen();
- pPolyline->setBulgeAt(n - 1, dNewBugle);
- pPolyline->removeVertexAt(n);
- pPolyline->downgradeOpen();
- }
- else
- {
- acedAlert(_T("多段线顶点个数至少为2点!"));
- }
- }
- acedSSFree(ss);
- acedSSSetFirst(NULL, NULL);
- pCurve->close();
- pEnt->close();
- // 还原对象捕捉系统变量
- SetVar(_T("osmode"), nOsmode);
- // 还原回显系统变量
- SetVar(_T("cmdecho"), nCmdecho);
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
|