|
如何使用 ObjectARX 获取曲线和平面的交点
问:有一条曲线(由 AcDbCurve 继承),并且平面设置为 AcGePlane。如何获得曲线和平面的所有交点?
答:为此,我们将使用几何库。首先,我们使用 acdbConvertAcDbCurveToGelibCurve 函数将 AcDbCurve(及其任何后续版本)转换为 AcGeCurve3d。其次,让我们使用 AcGeCurveSurfInt 类来获取曲线和平面的交点。
下面你可以看到一个函数的源代码,它要求用户提供曲线、水平面的起始和结束水平以及水平面之间的间距。她的作品成果是标记平面和曲线交点的黄点。static void RivilisCheckInt () {
Acad::ErrorStatus es;
ads_name en; ads_point p;
double level1 = -10.0;
double level2 = +10.0;
double step = 1.0;
if (acedEntSel(_T("\nВыберите произвольную кривую: "), en, p) == RTNORM) {
TCHAR buf1[32]; acdbRToS(level1,-1,-1, buf1, sizeof(buf1)-1);
TCHAR buf2[32]; acdbRToS(level2,-1,-1, buf2, sizeof(buf2)-1);
TCHAR buf3[32]; acdbRToS(step,-1,-1, buf3, sizeof(buf3)-1);
AcString s1;
s1.format(_T("\nУкажите начальную отметку уровня для проверки пересечения с плоскостью <%s>: "), buf1);
AcString s2;
s2.format(_T("\nУкажите конечную отметку уровня для проверки пересечения с плоскостью <%s>: "), buf2);
if (acedGetReal(s1,&level1) != RTCAN && acedGetReal(s2,&level2) != RTCAN) {
AcString s3; s3.format(_T("\nУкажите шаг уровней <%s>: "), buf3);
acedInitGet(RSG_NOZERO | RSG_NONEG, NULL);
if (acedGetReal(s3,&step) == RTCAN) return;
AcDbObjectId eId; acdbGetObjectId(eId, en);
AcDbObjectPointer<AcDbCurve> pCurve(eId, AcDb::kForRead);
if (pCurve.openStatus() == Acad::eWrongObjectType) {
acutPrintf(_T("\nВыбрана не кривая. Допустимы линии, полилинии, дуги, окружности, сплайны, и т.д."));
return;
}
if (pCurve.openStatus() != Acad::eOk) {
acutPrintf(_T("\nОшибка открытия: %s"), acadErrorStatusText(pCurve.openStatus()));
return;
}
// GE-кривая, полученная из AcDb-кривой
AcGeCurve3d *pGeCurve = NULL;
if ((es = acdbConvertAcDbCurveToGelibCurve(pCurve, pGeCurve)) != Acad::eOk) {
acutPrintf(_T("\nacdbConvertAcDbCurveToGelibCurve: %s"), acadErrorStatusText(es));
return;
}
for (double z = min(level1, level2); z <= max(level1,level2); z += step)
{
// Плоскость сечения
AcGePlane plan(AcGePoint3d(0,0,z), AcGeVector3d::kZAxis);
AcGeIntersectError err;
AcGeCurveSurfInt csint(*pGeCurve, plan);
int n = csint.numIntPoints(err);
if ((n = csint.numIntPoints(err)) != 0)
{
// Задаём форму точки
acdbCurDwg()->setPdmode(34);
acutPrintf(_T("\nВсего %d пересечений на уровне %g"), n, z);
AcDbBlockTableRecordPointer pBTR(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite);
if (pBTR.openStatus() == Acad::eOk) {
for (int i = 0; i < n; i++) {
AcDbPoint *pPoint = new AcDbPoint(csint.intPoint(i,err));
pPoint->setDatabaseDefaults();
pPoint->setColorIndex(2);
pBTR->appendAcDbEntity(pPoint);
pPoint->close();
}
}
}
}
delete pGeCurve;
}
}
} |
|