- 积分
- 30685
- 明经币
- 个
- 注册时间
- 2007-4-24
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 gzxl 于 2025-9-5 21:12 编辑
个人体会:
getSplitCurves 方法对自相交总之...,虽然折衷处理,但在某些特殊的情况下难以言表!
下面不以 getSplitCurves 分割的思路代码
 - Acad::ErrorStatus es;
- // 分割点点集(自相交+两个曲线相交)
- AcGePoint3dArray pointsBreak;
- // 新建一个过滤掉孤立的曲线对象集合
- std::vector<AcDbCurve*> curvesCopy;
- // 曲线对象集合大小
- size_t nSize = curves.size();
- // 曲线自相交检测,将交点加入 pointsBreak 点集
- for (size_t i = 0; i < nSize; i++)
- {
- AcDbCurve* pCurve = curves.at(i);
- // 自相交
- AcGePoint3dArray pointsOneselfInter;
- if (GetCurveOneselfInter(pCurve, pointsOneselfInter))
- {
- int n = pointsOneselfInter.length();
- for (int j = 0; j < n; j++)
- {
- AcGePoint3d pt = pointsOneselfInter.at(j);
- pointsBreak.append(pt);
- }
- pointsOneselfInter.removeAll();
- }
- pCurve->close();
- }
- // 两条曲线相交
- for (size_t i = 0; i < nSize; i++)
- {
- AcDbCurve* pCurve1 = curves.at(i);
- // 起点和终点
- AcGePoint3d ptStart1, ptEnd1;
- pCurve1->getStartPoint(ptStart1);
- pCurve1->getEndPoint(ptEnd1);
- // 是否与其他曲线相交
- bool bInters = false;
- for (size_t j = 0; j < nSize; j++)
- {
- AcDbCurve* pCurve2 = curves.at(j);
- if (pCurve2 == pCurve1)
- {
- pCurve2->close();
- continue;
- }
- // 起点和终点
- AcGePoint3d ptStart2, ptEnd2;
- pCurve2->getStartPoint(ptStart2);
- pCurve2->getEndPoint(ptEnd2);
- // 两条曲线求交点
- AcGePoint3dArray pointsInters;
- if (GetCurvesInterPoints(pCurve2, pCurve1, pointsInters))
- {
- int n = pointsInters.length();
- for (int k = 0; k < n; k++)
- {
- // 交点不为曲线的起点或终点
- AcGePoint3d pt = pointsInters.at(k);
- if (!IsEqual(pt, ptStart1) || !IsEqual(pt, ptEnd1) ||
- !IsEqual(pt, ptStart2) || !IsEqual(pt, ptEnd2))
- {
- pointsBreak.append(pt);
- }
- }
- bInters = true;
- }
- pCurve2->close();
- }
- if (bInters)
- {
- curvesCopy.push_back(pCurve1);
- }
- pCurve1->close();
- }
- // 分割点点集过滤掉重复点
- if (pointsBreak.length() >= 2)
- {
- CSplitCurves::FilterEqualPoints(pointsBreak);
- }
- // 曲线对象集合大小
- size_t nSizeCopy = curvesCopy.size();
- // 曲线前后顶点组成的线段插入交点处理
- for (size_t i = 0; i < nSizeCopy; i++)
- {
- AcDbCurve* pCurveCopy = curvesCopy.at(i);
- // 曲线的顶点点集
- AcGePoint3dArray pointsVertex;
- // 直线
- if (pCurveCopy->isKindOf(AcDbLine::desc()))
- {
- AcDbLine *pLine = AcDbLine::cast(pCurveCopy);
- // 起点和终点
- AcGePoint3d ptStart, ptEnd;
- pLine->getStartPoint(ptStart);
- pLine->getEndPoint(ptEnd);
- // 加入 pointsVertex 顶点点集
- pointsVertex.append(ptStart);
- pointsVertex.append(ptEnd);
- pLine->close();
- }
- // 经量多段线
- else if (pCurveCopy->isKindOf(AcDbPolyline::desc()))
- {
- AcDbPolyline *pPoly = AcDbPolyline::cast(pCurveCopy);
- // 循环获取顶点加入 pointsVertex 顶点点集(将凸度值代入 Z 坐标)
- int n = pPoly->numVerts();
- for (int j = 0; j < n; j++)
- {
- AcGePoint3d pt;
- pPoly->getPointAt(j, pt);
- double dBulge = 0.0;
- pPoly->getBulgeAt(j, dBulge);
- pointsVertex.append(AcGePoint3d(pt.x, pt.y, dBulge));
- }
- // 如果是闭合的,则再将起点加入 pointVerts 顶点点集
- if (pPoly->isClosed())
- {
- AcGePoint3d ptStart;
- pPoly->getStartPoint(ptStart);
- pointsVertex.append(AcGePoint3d(ptStart.x, ptStart.y, 0.0));
- }
- pPoly->close();
- }
- // 二维多段线
- else if (pCurveCopy->isKindOf(AcDb2dPolyline::desc()))
- {
- AcDb2dPolyline *pPoly = AcDb2dPolyline::cast(pCurveCopy);
- // 迭代器对象的指针
- AcDbObjectIterator *pVertIter = pPoly->vertexIterator();
- for (pVertIter->start(); !pVertIter->done(); pVertIter->step())
- {
- AcDbObjectId objId = pVertIter->objectId();
- AcDb2dVertex *p2dVertex = NULL;
- es = acdbOpenObject(p2dVertex, objId, AcDb::kForRead);
- if (es != Acad::eOk)
- continue;
- AcGePoint3d pt = p2dVertex->position();
- pointsVertex.append(pt);
- p2dVertex->close();
- }
- // 删除迭代器对象的指针
- delete pVertIter;
- // 如果是闭合的,则再将起点加入 pointVerts 顶点点集
- if (pPoly->isClosed())
- {
- AcGePoint3d ptStart;
- pPoly->getStartPoint(ptStart);
- pointsVertex.append(AcGePoint3d(ptStart.x, ptStart.y, 0.0));
- }
- pPoly->close();
- }
- // 三维多段线
- else if (pCurveCopy->isKindOf(AcDb3dPolyline::desc()))
- {
- AcDb3dPolyline *pPoly = AcDb3dPolyline::cast(pCurveCopy);
- AcDbObjectIterator *pVertIter = pPoly->vertexIterator();
- for (pVertIter->start(); !pVertIter->done(); pVertIter->step())
- {
- AcDbObjectId objId = pVertIter->objectId();
- AcDb3dPolylineVertex *p3dVertex = NULL;
- es = acdbOpenObject(p3dVertex, objId, AcDb::kForRead);
- if (es != Acad::eOk)
- continue;
- AcGePoint3d pt = p3dVertex->position();
- pointsVertex.append(pt);
- p3dVertex->close();
- }
- delete pVertIter;
- pPoly->close();
- }
- // 圆弧
- else if (pCurveCopy->isKindOf(AcDbArc::desc()))
- {
- AcDbArc *pArc = AcDbArc::cast(pCurveCopy);
- // 起点和终点
- AcGePoint3d ptStart, ptEnd;
- pArc->getStartPoint(ptStart);
- pArc->getEndPoint(ptEnd);
- // 起始角度和结束角度
- double dStartAngle = pArc->startAngle();
- double dEndAngle = pArc->endAngle();
- // 获取圆弧凸度
- double dAlfa = dEndAngle - dStartAngle;
- if (dAlfa < 0.0) // 如果终点角度小于起点角度
- {
- dAlfa = 2 * PI + dAlfa;
- }
- double dBulge = tan((dAlfa) / 4.0);
- pointsVertex.append(AcGePoint3d(ptStart.x, ptStart.y, dBulge));
- pointsVertex.append(ptEnd);
- pArc->close();
- }
- // 圆
- else if (pCurveCopy->isKindOf(AcDbCircle::desc()))
- {
- AcDbCircle *pCircle = AcDbCircle::cast(pCurveCopy);
- // 圆的中心点
- AcGePoint3d ptCenter;
- ptCenter = pCircle->center();
- // 圆的半径
- double radius = 0.0;
- radius = pCircle->radius();
- // 获取圆上的四点
- AcGePoint3dArray pointsTemp;
- for (int j = 0; j <= 4; j++)
- {
- double x = ptCenter.x + radius * cos(j * 0.5 * PI);
- double y = ptCenter.y + radius * sin(j * 0.5 * PI);
- AcGePoint3d pt(x, y, 0.0);
- pointsTemp.append(pt);
- }
- // 获取凸度
- int nTemp = pointsTemp.length();
- for (int j = 0; j < nTemp - 1; j++)
- {
- AcGePoint3d pt1 = pointsTemp.at(j);
- AcGePoint3d pt2 = pointsTemp.at(j + 1);
- // 重新计算设置 pt1 点的凸度
- double dBulge1 = GetBulge(pt1, pt2, ptCenter);
- pointsVertex.append(AcGePoint3d(pt1.x, pt1.y, dBulge1));
- pointsVertex.append(AcGePoint3d(pt2.x, pt2.y, 0.0));
- }
- pCircle->close();
- }
- // 遍历曲线 pointVerts 顶点点集
- // 如果交点在两顶点曲线上,则在两顶点曲线之间插入交点,且需重设对应顶点的凸度值
- if (pointsBreak.length() > 0)
- {
- // 新建一个曲线顶点点集
- AcGePoint3dArray pointsVertexNew;
- // 原曲线顶点点集大小
- int nVertex = pointsVertex.length();
- // 原曲线前后顶点组成的线段是否存在交点
- for (int j = 0; j < nVertex - 1; j++)
- {
- // 曲线当前顶点
- AcGePoint3d ptCurrent = pointsVertex.at(j);
- // 曲线下一个顶点
- AcGePoint3d ptNext = pointsVertex.at(j + 1);
- // 当前顶点 ptCurrent 加入 pointsVertexNew 点集中
- pointsVertexNew.append(ptCurrent);
- // 临时交点点集
- AcGePoint3dArray pointsTemp;
- // 遍历交点,交点是否在两顶点组成的曲线上(需考虑有多个交点)
- int nBreak = pointsBreak.length();
- for (int k = 0; k < nBreak; k++)
- {
- AcGePoint3d ptBreak = pointsBreak.at(k);
- // 给定的交点 ptBreak 在由两个顶点 ptCurrent ptNext 组成的曲线上
- // 交点加入 pointsTemp 临时交点点集
- if (IsPointOnCurve(ptCurrent, ptNext, ptBreak))
- {
- pointsTemp.append(ptBreak);
- }
- }
- if (pointsTemp.length() > 0)
- {
- // 计算曲线原前后两个顶点的中心点
- AcGePoint3d ptCenter = AcGePoint3d::kOrigin;
- if (fabs(ptCurrent.z) > 1.0E-4) // Z 值代表凸度值
- {
- ptCenter = GetCenterPoint(ptCurrent, ptNext, ptCurrent.z);
- }
- // 两个前后顶点之间有多个交点
- if (pointsTemp.length() > 1)
- {
- // 创建由当前顶点和下一个顶点组成的曲线
- AcGePoint3dArray points;
- points.append(ptCurrent);
- points.append(ptNext);
- int numVertices = points.length();
- AcDbPolyline *pPoly = new AcDbPolyline(numVertices);
- for (int i = 0; i < numVertices; i++)
- {
- AcGePoint3d pt3d = points.at(i);
- AcGePoint2d pt2d(pt3d.x, pt3d.y);
- double dBugle = pt3d.z;
- pPoly->addVertexAt(i, pt2d, dBugle, 0.0, 0.0);
- }
- // 强制转换为曲线类
- AcDbCurve* pCurveNew = static_cast<AcDbCurve*>(pPoly);
- // 点沿曲线排序
- SortPointsOnCurve(pCurveNew, pointsTemp, 0, pointsTemp.length() - 1);
- // 清理由当前顶点和下一个顶点组成的曲线
- pPoly->erase();
- pPoly->close();
- pCurveNew->erase();
- pCurveNew->close();
- // 对于有弧度的重新计算和设置交点的凸度值
- int nTemp = pointsTemp.length();
- for (int k = 0; k < nTemp - 1; k++)
- {
- AcGePoint3d ptTemp1 = pointsTemp.at(k);
- AcGePoint3d ptTemp2 = pointsTemp.at(k + 1);
- // Z 值代表是有凸度
- if (fabs(ptCurrent.z) > 1.0E-4)
- {
- // 计算重设 ptCurrent 新的凸度值
- double dBulge1 = GetBulge(ptCurrent, ptTemp1, ptCenter);
- int nCount = FindPoint(pointsVertexNew, ptCurrent);
- if (nCount > -1)
- pointsVertexNew.at(nCount).z = dBulge1;
- // 计算交点的凸度值
- double dBulge2 = GetBulge(ptTemp1, ptTemp2, ptCenter);
- ptTemp1.set(ptTemp1.x, ptTemp1.y, dBulge2);
- pointsVertexNew.append(ptTemp1);
- }
- else
- {
- pointsVertexNew.append(ptTemp1);
- }
- ptCurrent = ptTemp1;
- }
- AcGePoint3d ptEnd = pointsTemp.at(pointsTemp.length() - 1);
- pointsVertexNew.append(ptEnd);
- }
- // 只有一个交点
- else
- {
- AcGePoint3d ptTemp = pointsTemp.at(0);
- if (fabs(ptCurrent.z) > 1.0E-4) // Z 值代表凸度值
- {
- // 计算重设 ptCurrent 新的凸度值
- double dBulge1 = GetBulge(ptCurrent, ptTemp, ptCenter);
- int nCount = FindPoint(pointsVertexNew, ptCurrent);
- if (nCount > -1)
- pointsVertexNew.at(nCount).z = dBulge1;
- // 计算交点的凸度值
- double dBulge2 = GetBulge(ptTemp, ptNext, ptCenter);
- ptTemp.set(ptTemp.x, ptTemp.y, dBulge2);
- pointsVertexNew.append(ptTemp);
- }
- else
- {
- pointsVertexNew.append(ptTemp);
- }
- }
- }
- pointsVertexNew.append(AcGePoint3d(ptNext.x, ptNext.y, 0.0));
- }
- // 将有与其他曲线相交的曲线点集加入新的集合
- if (pointsVertexNew.length() > 0)
- {
- vecPointsBreak.push_back(pointsVertexNew);
- }
- }
- // 清理
- pointsVertex.removeAll();
- pCurveCopy->close();
- }
- // 清理
- if (curvesCopy.size() > 0)
- {
- std::vector<AcDbCurve*>().swap(curvesCopy);
- }
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
评分
-
查看全部评分
|