按里程截取CurvePrimitive


ICurvePrimitive类下有一个CloneBetweenFractions函数,这个函数的原型如下所示:

ICurvePrimitivePtr CloneBetweenFractions (double fractionA, double fractionB, bool allowExtrapolation) const;

此函数可以获取ICurvePrimitive上的一小段曲线,这一小段曲线的起点和终点是由CloneBetweenFractions函数的前两个参数fractionA和fractionB决定的,通过名字我们会认为这两个参数的值就是指定点到曲线起点这一段曲线的长度跟曲线总长度的比值,如果使用一条直线(Line)去测试的话,测试结果也确实如此。但是如果换成线串(Line String)或者样条曲线去测试的话,又会发现结果不对。实际上fraction并不是我们前面说的这个比值,想要理解其真正含义需要深入研究一下样条曲线公式,我们这里给大家介绍一种方法如何按照我们前面说的比值去获取ICurvePrimitive指定部分的曲线。ICurvePrimitive还有一个成员函数可以获取指定fraction处往后指定距离处曲线详细信息CurveLocationDetail的对象实例,函数原型如下所示:

bool PointAtSignedDistanceFromFraction (double startFraction, double signedDistance, bool allowExtension, CurveLocationDetailR location) const;

startFraction 参数为0时就是曲线的起点,signedDistance 指定了startFraction点往后多少距离。startFraction 与signedDistance 共同指定了曲线上的一点,此点的详细信息通过location参数返回。再将CurveLocationDetail的成员变量fraction传递给CloneBetweenFractions函数,就实现了通过距曲线起点距离来获取曲线指定点之间的一小段曲线。如下代码演示了获取曲线1/5处到1/3处部分段,此代码运行前要选通过选择集工具选中一条基本曲线(例如:Line、Line String、Bspline Curve,对于复杂链的话获取的是复杂链中第一段的一小段)。

ElementAgenda selectset;
	SelectionSetManager::GetManager().BuildAgenda(selectset);
	if (selectset.GetCount() < 1)
	{
		return;
	}
	EditElementHandle& eeh = selectset[0];
	CurveVectorPtr cveVec = ICurvePathQuery::ElementToCurveVector(eeh);
	ICurvePrimitivePtr cvePri = cveVec->at(0);
	double length = 0;
	cvePri->Length(length);
	CurveLocationDetail cveLocaS, cveLocaE;
	cvePri->PointAtSignedDistanceFromFraction(0, length / 5, false, cveLocaS);
	cvePri->PointAtSignedDistanceFromFraction(0, length / 3, false, cveLocaE);
	cvePri = cvePri->CloneBetweenFractions(cveLocaS.fraction, cveLocaE.fraction, false);
	EditElementHandle eehResult;
	DraftingElementSchema::ToElement(eehResult, *cvePri, NULL, ACTIVEMODEL->Is3d(), *ACTIVEMODEL);
	eehResult.AddToModel();