两条曲线间getClosestPointTo的精确性。
我创建了AcDb到AcGe和AcGe到AcDb的转换。我使用此转换来获得两条曲线之间的最近点,
大多数曲线的结果是准确的,但对于样条曲线,有时会与真实点略有不同。
所以问题是:我如何才能得到确切的答案?
另一个问题是:如何准确地将AcDb2dPolyline2d(或AcDb3dPolyline)转换为AcGePolyline2d?AcDb3dPolyline->getSpline?主代码:
// LINE
AcGeLineSeg3d * AcDbCurveToAcGeCurve(const AcDbLine * pLine)
{
return new AcGeLineSeg3d(pLine->startPoint(), pLine->endPoint());
}
AcDbLine * AcGeCurveToAcDbCurve(const AcGeLineSeg3d * pGe)
{
return new AcDbLine(pGe->startPoint(),pGe->endPoint());
}
// ARC
AcGeCircArc3d * AcDbCurveToAcGeCurve(const AcDbArc * pDbArc)
{
returnnew AcGeCircArc3d(
pDbArc->center(),
pDbArc->normal(),
pDbArc->normal().perpVector(),
pDbArc->radius(),
pDbArc->startAngle(),
pDbArc->endAngle());
}
AcDbCurve * AcGeCurveToAcDbCurve(const AcGeCircArc3d * pGe)
{
if (pGe->isClosed() == Adesk::kTrue)
{
returnnew AcDbCircle(
pGe->center(),
pGe->normal(),
pGe->radius());
}
else
{
returnnew AcDbArc(
pGe->center(),
pGe->normal(),
pGe->radius(),
pGe->startAng(),
pGe->endAng());
}
}
// CIRCLE
AcGeCircArc3d * AcDbCurveToAcGeCurve(const AcDbCircle * pDbCircle)
{
return new AcGeCircArc3d(pDbCircle->center(),pDbCircle->normal(),pDbCircle->radius());
}
// ELLIPSE
AcGeEllipArc3d * AcDbCurveToAcGeCurve(const AcDbEllipse * pDbEllise)
{
return new AcGeEllipArc3d(
pDbEllise->center(),
pDbEllise->majorAxis(),
pDbEllise->minorAxis(),
pDbEllise->majorAxis().length(),
pDbEllise->minorAxis().length(),
pDbEllise->startAngle(),
pDbEllise->endAngle());
}
AcDbEllipse * AcGeCurveToAcDbCurve(const AcGeEllipArc3d * pGe)
{
return new AcDbEllipse(
pGe->center(),
pGe->normal(),
pGe->majorAxis()*pGe->majorRadius(),
pGe->minorRadius()/pGe->majorRadius(),
pGe->startAng(),
pGe->endAng());
}
// SPLINE
AcGeNurbCurve3d * AcDbCurveToAcGeCurve(const AcDbSpline * pSpline)
{
Acad::ErrorStatus es = Acad::eOk;
AcGePoint3dArray fitPoints;
int degree;
double fitTolerance;
Adesk::Boolean tangentsExist;
Adesk::Boolean tangentStartDef;
Adesk::Boolean tangentEndDef;
AcGeVector3d startTangent;
AcGeVector3d endTangent;
Adesk::Boolean rational;
Adesk::Boolean closed;
Adesk::Boolean periodic;
AcGePoint3dArray controlPoints;
AcGeDoubleArray knots;
AcGeDoubleArray weights;
double controlPtTol;
double knotTol;
closed = pSpline->isClosed();
AcGeNurbCurve3d *curv = NULL;
if (0)//(pSpline->hasFitData())
{
AcGeTol tol;
if ((es = pSpline->getFitData(fitPoints,degree,fitTolerance,tangentsExist,startTangent,endTangent)) == Acad::eOk)
{
tangentStartDef = tangentsExist; //&& (startTangent != AcGeVector3d::kIdentity);
tangentEndDef = tangentsExist; //&& (endTangent != AcGeVector3d::kIdentity);
AcGeTol fitTol;
pSpline->fitTolerance();
fitTol.setEqualPoint(fitTolerance);
curv = new AcGeNurbCurve3d(fitPoints,startTangent,endTangent,tangentStartDef,tangentEndDef,fitTol);
if (closed == Adesk::kTrue)
{
curv->makeClosed();
}
}
}
else
{
if ((es = pSpline->getNurbsData(degree,rational,closed,periodic,controlPoints,knots,weights,controlPtTol,knotTol)) == Acad::eOk)
{
if (rational==Adesk::kTrue)
{
curv = new AcGeNurbCurve3d(degree,knots,controlPoints,weights,periodic);
}
else
{
curv = new AcGeNurbCurve3d(degree,knots,controlPoints,periodic);
}
if (closed == Adesk::kTrue)
{
curv->makeClosed();
}
}
}
return curv;
}
AcDbSpline * AcGeCurveToAcDbCurve(const AcGeNurbCurve3d * pGe)
{
AcDbSpline *pSpline = NULL;
if (pGe->hasFitData())
{
AcGePoint3dArray fitPoints;
AcGeTol fitTolerance;
Adesk::Boolean tangentsExist;
AcGeVector3d startTangent;
AcGeVector3d endTangent;
double tol;
pGe->getFitData(fitPoints,fitTolerance,tangentsExist,startTangent,endTangent);
pSpline = new AcDbSpline(fitPoints,startTangent,endTangent,pGe->order(),fitTolerance.equalPoint());
}
else
{
int degree;
Adesk::Boolean rational;
Adesk::Boolean periodic;
AcGePoint3dArray controlPoints;
AcGeKnotVector knots1;
AcGeDoubleArray weights;
pGe->getDefinitionData(degree,rational,periodic,knots1,controlPoints,weights);
AcGeDoubleArray knots;
for (int i = 0;inumKnots();i++)
{
knots.append(knots1);
}
pSpline = new AcDbSpline(degree,rational,pGe->isClosed(),periodic,controlPoints,knots,weights,0.0,pGe->knots().tolerance());
}
return pSpline;
}
// POLYLINE
AcGeCompositeCurve3d * AcDbCurveToAcGeCurve(const AcDbPolyline * pPoly)
{
AcGeLineSeg3d *pLine = NULL;
AcGeCircArc3d *pArc = NULL;
AcGeVoidPointerArray GeCurves;
for( int i = 0; i numVerts(); i++ )
{
if( pPoly->segType(i) == AcDbPolyline::kLine )
{
pLine = new AcGeLineSeg3d;
pPoly->getLineSegAt(i, *pLine);
GeCurves.append(pLine);
}
else if( pPoly->segType(i) == AcDbPolyline::kArc )
{
pArc = new AcGeCircArc3d;
pPoly->getArcSegAt(i, *pArc);
GeCurves.append(pArc);
}
}
returnnew AcGeCompositeCurve3d(GeCurves);
}
AcDbPolyline * AcGeCurveToAcDbCurve(const AcGeCompositeCurve3d * pGe)
{
AcGePoint3d startPnt,endPnt;
if( pGe->hasEndPoint(endPnt) == Adesk ::kFalse ||
pGe->hasStartPoint(startPnt) == Adesk::kFalse)
{
return NULL;
}
//get the plane of Curve3d
AcGePlane plane;
AcGeLine3d line;
AcGePoint3d p1,p2,p3;
if(pGe->isPlanar(plane))
{
if(pGe->isLinear(line)) //Oh,it's a little tricky!
{
line.getPerpPlane(startPnt,plane);
plane.get(p1,p2,p3);
plane.set(p2,p3-p2);
}
plane.get(p1,p2,p3);
}
else
{
return NULL;
}
//Creat a polyline
AcDbPolyline *pPoly = new AcDbPolyline();
AcGeVoidPointerArray curveList;
pGe->getCurveList(curveList);//get all the segments
AcGeCurve3d *pCurve = NULL;
AcGeCircArc3d *pArc = NULL;
int i;
double b;
AcGePoint2d pt;
for(i = 0;i hasStartPoint(startPnt);
pt = startPnt.convert2d(plane);
if (pCurve->isKindOf(AcGe::kCircArc3d))
{
pArc = (AcGeCircArc3d *)(pCurve);
b = tan(0.25*(pArc->endAng() - pArc->startAng()));
if (pArc->normal().z addVertexAt(i,pt,-b);
}
else
{
pPoly->addVertexAt(i,pt,b);
}
}
else
{
pPoly->addVertexAt(i,pt);
}
}
if(!pGe->isClosed())
{
pt = endPnt.convert2d(plane);
pPoly->addVertexAt(i,pt);
}
else
{
pPoly->setClosed(Adesk::kTrue);
}
//the most important step;
AcGeMatrix3d xform;
AcGeVector3d XAxis = p1-p2;
AcGeVector3d YAxis = p3-p2;
AcGeVector3d ZAxis = XAxis.crossProduct(YAxis);
xform.setCoordSystem(p2,XAxis,YAxis,ZAxis);
pPoly->transformBy(xform);
return pPoly;
}
// POLYLINE3D
AcGeCompositeCurve3d * AcDbCurveToAcGeCurve(const AcDb3dPolyline * pPoly3d)
{
AcGeVoidPointerArray GeCurves;
AcGePoint3d pt1;
AcGePoint3d pt2;
double Param;
pPoly3d->getEndParam(Param);
AcGeLineSeg3d *pLine = NULL;
for (int i= 0; i getPointAtParam(i,pt1);
pPoly3d->getPointAtParam(i+1,pt2);
pLine = new AcGeLineSeg3d(pt1,pt2);
GeCurves.append(pLine);
}
//AcDbSpline *pSpline= NULL;
//pPoly3d->getSpline(pSpline);
//CreateEntity(pSpline,1);
AcGeCompositeCurve3d * pGePoly3d = new AcGeCompositeCurve3d(GeCurves);
return pGePoly3d;
}
// POLYLINE2D
AcGeCompositeCurve3d * AcDbCurveToAcGeCurve(const AcDb2dPolyline *pPoly2d)
{
AcDb::Poly2dType type;
type=pPoly2d->polyType();
AcDbPolyline * pLwpoly = NULL;
Acad::ErrorStatus es;
AcGeCompositeCurve3d * pGeCurve = NULL;
if ((type==AcDb::k2dSimplePoly)||(type==AcDb::k2dFitCurvePoly))
{
pLwpoly=new AcDbPolyline;
es = pLwpoly->convertFrom((AcDbEntity *&)pPoly2d,Adesk::kFalse);
if (es!=Acad::eOk)
{
delete pLwpoly;
pLwpoly=NULL;
return NULL;
}
pGeCurve = AcDbCurveToAcGeCurve(pLwpoly);
pLwpoly->close();
}
else
{
AcGeVoidPointerArray GeCurves;
AcGePoint3d pt1;
AcGePoint3d pt2;
double Param;
pPoly2d->getEndParam(Param);
AcGeLineSeg3d *pLine = NULL;
for (int i= 0; i getPointAtParam(i,pt1);
pPoly2d->getPointAtParam(i+1,pt2);
pLine = new AcGeLineSeg3d(pt1,pt2);
GeCurves.append(pLine);
}
pGeCurve = new AcGeCompositeCurve3d(GeCurves);
}
return pGeCurve;
}
// catch all for all other entity types.
AcGeEntity3d * AcDbCurveToAcGeCurve(const AcDbEntity *pDbCurve)
{
if (pDbCurve == NULL)
{
return NULL;
}
if (pDbCurve->isKindOf(AcDbLine::desc()))
{
return AcDbCurveToAcGeCurve((AcDbLine *)pDbCurve);
}
if (pDbCurve->isKindOf(AcDbArc::desc()))
{
return AcDbCurveToAcGeCurve((AcDbArc *)pDbCurve);
}
if (pDbCurve->isKindOf(AcDbCircle::desc()))
{
return AcDbCurveToAcGeCurve((AcDbCircle *)pDbCurve);
}
if (pDbCurve->isKindOf(AcDbEllipse::desc()))
{
return AcDbCurveToAcGeCurve((AcDbEllipse *)pDbCurve);
}
if (pDbCurve->isKindOf(AcDbSpline::desc()))
{
return AcDbCurveToAcGeCurve((AcDbSpline *)pDbCurve);
}
if (pDbCurve->isKindOf(AcDbPolyline::desc()))
{
return AcDbCurveToAcGeCurve((AcDbPolyline *)pDbCurve);
}
if (pDbCurve->isKindOf(AcDb3dPolyline::desc()))
{
return AcDbCurveToAcGeCurve((AcDb3dPolyline *)pDbCurve);
}
if (pDbCurve->isKindOf(AcDb2dPolyline::desc()))
{
return AcDbCurveToAcGeCurve((AcDb2dPolyline *)pDbCurve);
}
return NULL;
}
AcDbEntity * AcGeCurveToAcDbCurve(const AcGeCurve3d * pGe)
{
if (pGe->isKindOf(AcGe::kCircArc3d))
{
return AcGeCurveToAcDbCurve((AcGeCircArc3d *) pGe);
}
if (pGe->isKindOf(AcGe::kEllipArc3d))
{
return AcGeCurveToAcDbCurve((AcGeEllipArc3d *) pGe);
}
if (pGe->isKindOf(AcGe::kLineSeg3d))
{
return AcGeCurveToAcDbCurve((AcGeLineSeg3d *) pGe);
}
if (pGe->isKindOf(AcGe::kNurbCurve3d))
{
return AcGeCurveToAcDbCurve((AcGeNurbCurve3d *) pGe);
}
if (pGe->isKindOf(AcGe::kCompositeCrv3d))
{
return AcGeCurveToAcDbCurve((AcGeCompositeCurve3d*) pGe);
}
return NULL;
}
**** Hidden Message ***** Alexander Rivilis,Gile,感谢您的代码和想法。
任何建议或错误发现欢迎和感谢。 从视觉上看,您的动画看起来是正确的。实际点和计算点之间有多大差异? 你是怎么走到这一步的? 有时这是错误的 有时它是错误的
好吧,所以有时它是错误的。查看代码,有很多,2个实体选择,其中一个可以是样条的组合。哪个实体组合不起作用?样条-样条,样条-弧等?此外,对于样条,有曲线拟合或苗圃。哪一个搞砸了,或者两者兼而有之?制作一个图表,显示成功和失败的实体组合,发布它,这将有助于任何测试人员。在图表中也包括两种不同类型的样条的通过/失败测试。问题与2d和3d实体类型相关,还是仅与一种特定类型相关。提供测试人员可以使用的绘图文件。告诉我们您怀疑哪个代码区域有问题。
我们这里只有少数人知道ARX,而那些可能在头脑中就知道样条特定答案的人,都在Autolisp论坛中。要获得尽可能多的帮助,请从上面的列表开始提供尽可能多的详细信息。 在玩了大约一个小时后,终于找到了答案
AcGeNurbCurve3d * AcDbCurveToAcGeCurve(const AcDbSpline * pSpline)
{
AcGeNurbCurve3d *curv = NULL;
if (pSpline->hasFitData())
{
BOOL bIsRational, bIsPeriodic, bIsClosed;
AcGeDoubleArray knots;
AcGePoint3dArray controlPoints;
AcGeDoubleArray weights;
double controlPtTol, knotTol;
int nDegree;
pSpline->getNurbsData(nDegree, bIsRational, bIsClosed, bIsPeriodic, controlPoints, knots, weights, controlPtTol, knotTol);
if(weights.length())
curv = new AcGeNurbCurve3d(nDegree, knots, controlPoints, weights, bIsPeriodic);
else
curv = new AcGeNurbCurve3d(nDegree, knots, controlPoints, bIsPeriodic);
bIsClosed ? curv->makeClosed() : curv->makeOpen();
}
return curv;
}
基本上,您没有从原始样条曲线检索所有nurb数据,并且使用了错误的AcGeNurbCurve3d构造函数
因此,新样条曲线与旧样条曲线的几何图形不同
以下是ARX文档对您使用的构造函数的描述。
非常感谢,pkohut。
注意:
虽然用“getNurbsData”是对的,但是看数据:
阶数:4
特性:平面,非有理,非周期
参数范围:起点0.0000端点1203.6780控制点数目:7
控制点:X = 1747.8226,Y = 840.1270,Z = 0.0000 X = 1883.3499,Y = 833.2746,Z = 0.0000 X = 2159.7191,Y = 819.3010,Z = 0.0000 X = 2054.1012,Y = 1336.1513
另一个
在折线的构造中有一个错误
抱歉,我对婴儿床一无所知,它们是如何制作的,一无所知。
得走了,孩子们周末在这里。 看看这是否有帮助:
int degree;
Adesk::Boolean rational;
Adesk::Boolean closed;
Adesk::Boolean periodic;
AcGePoint3dArray controlPoints;
AcGeDoubleArray knots;
AcGeDoubleArray weights;
double controlPtTol;
double knotTol;
AcGeTol tol;
es=pSpline->getNurbsData(degree,rational,closed,periodic,controlPoints,knots,weights,controlPtTol,knotTol);
if (es!=Acad::eOk)
return Acad::eNotImplemented;
if (rational==Adesk::kTrue)
{
acutPrintf(_T("\n*** Spline is Rational. "));
AcGeNurbCurve3d *pNurb=new AcGeNurbCurve3d(degree,knots,controlPoints,weights,periodic);
if (closed==Adesk::kTrue)
pNurb->makeClosed();
if (pSpline->hasFitData()==Adesk::kTrue)
{
AcGePoint3dArray fitPoints;
double fitTolerance;
Adesk::Boolean tangentsExist;
AcGeVector3d startTangent;
AcGeVector3d endTangent;
pSpline->getFitData(fitPoints,degree,fitTolerance,tangentsExist,startTangent,endTangent);
tol.setEqualPoint(fitTolerance);
if (tangentsExist==Adesk::kTrue)
pNurb->setFitData(fitPoints,startTangent,endTangent,tol);
else
pNurb->setFitData(degree,fitPoints,tol);
}
pGeCurve = (AcGeCurve3d *)pNurb;
}
else
{
acutPrintf(_T("\n*** Spline is Periodic. "));
AcGeNurbCurve3d *pNurb=new AcGeNurbCurve3d(degree,knots,controlPoints,periodic);
if (closed==Adesk::kTrue)
pNurb->makeClosed();
if (pSpline->hasFitData()==Adesk::kTrue)
{
AcGePoint3dArray fitPoints;
double fitTolerance;
Adesk::Boolean tangentsExist;
AcGeVector3d startTangent;
AcGeVector3d endTangent;
pSpline->getFitData(fitPoints,degree,fitTolerance,tangentsExist,startTangent,endTangent);
tol.setEqualPoint(fitTolerance);
if (tangentsExist==Adesk::kTrue)
pNurb->setFitData(fitPoints,startTangent,endTangent,tol);
else
pNurb->setFitData(degree,fitPoints,tol);
}
pGeCurve = (AcGeCurve3d *)pNurb;
}
这可能会起作用Luis。乍一看,
if(pSpline->hasFitData()==Adesk::kTrue){...}
是重复代码并不明显,这使得函数看起来比实际更复杂。收紧要好得多。
页:
[1]
2