特殊评估类
以下部分介绍 AcGe 库中的类,您可以使用这些类来评估曲线和曲面上的点。这些类是 、 和 。AcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurface 参数曲线由一个连续函数定义,该函数将实线(可能是整个实线)的某个间隔映射到 2D 或 3D 空间,具体取决于曲线是 2D 还是 3D。参数化曲面由一个连续函数定义,该函数将平面的某些连接子集(可能是整个平面)映射到 3D 空间。参数化曲线或曲面上对应于特定参数值的点可以通过计算该参数值的函数来获得。对于曲线,参数值是标量,对于曲面,参数值是二维点。uvuv 许多支持参数化曲线和曲面的几何建模系统都包含用于计算参数化曲线和曲面上的点的赋值器函数。这些赋值器通常具有用于计算曲线或曲面的参数值以及要返回的导数的输入参数。它们还具有计算点的输出参数和导数的向量数组。有时,赋值器包含其他参数,用于请求和返回特定参数值的法向量。 除了每个曲线和曲面类的此类赋值器函数(称为 )之外,AcGe 库还包含赋值器类 、 和 ,通过这些类可以访问曲线和曲面赋值器。这些类有两个主要用途:evalPoint()AcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurface
与类、 和类的公共接口是相同的,除了成员函数名称的细微差异。例如,该类包含返回导数向量的函数,而该类包含两个函数,以及 ,以返回 和偏导数。本节的其余部分将介绍如何使用该类,但此说明也适用于 and 类,因为它们的接口与该类的接口非常相似。AcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurfaceAcGePointOnCurve3dderiv(),AcGePointOnSurfaceuDeriv()vDeriv()uvAcGePointOnSurfaceAcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurface 要使用该类来评估点和导数,必须指定要评估的曲面以及要进行评估的参数值。以下两个成员函数设置对象的图面和参数值:AcGePointOnSurfaceAcGePointOnSurface AcGePointOnSurface& setSurface (const AcGeSurface&); AcGePointOnSurface& setParameter (const AcGePoint2d&); 调用后,所有后续评估都将在该图面上执行,直到您再次调用其他图面。同样,在调用 之后,所有后续查询函数都会返回与该参数值有关的信息,直到再次调用其他参数值。例如,考虑 if is an object、is an object 和 is a object,则以下代码计算参数值处的点和一阶导数:setSurface()setSurface()setParameter()setParameter()srfAcGeSurfaceparamAcGePoint2dpntOnSrfAcGePointOnSurfacesrfparam pntOnSrf.setSurface (srf); pntOnSrf.setParameter (param); AcGePoint3d pnt3d = pntOnSrf.point(); AcGeVector3d uFirstPartial = pntOnSrf.uDeriv(1), vFirstPartial = pntOnSrf.vDeriv(1); 在实践中,您很少(如果有的话)打电话或直接打电话。相反,您可以通过类的成员函数间接调用这些函数。例如,返回特定参数值的模型空间点的函数具有三个不同的签名:setSurface()setParameter()AcGePointOnSurfacepoint() AcGePoint3d point () const; AcGePoint3d point (const AcGePoint2d& param); AcGePoint3d point ( const AcGeSurface& srf, const AcGePoint2d& param); 第一个特征不接受任何参数,并假定曲面和参数值已通过先前对 和 的调用设置。第二个特征假定曲面已由先前的 调用 设置,但它调用以在求值之前设置参数值。第三个签名调用 和 在评估之前设置曲面和参数值。只有第一个成员函数声明为 ;另外两个通过设置曲面和/或参数值来修改对象。现在可以从前面的代码中删除对 和 的直接调用,如下所示:setSurface()setParameter()setSurface()setParameter(param)setSurface(srf)setParameter(param)constsetSurface()setParameter() AcGePoint3d pnt3d = pntOnSrf.point ( srf, param ); AcGeVector3d uFirstPartial = pntOnSrf.uDeriv(1), vFirstPartial = pntOnSrf.vDeriv(1); 第一个语句在执行评估之前导致和被调用。后续评估在同一曲面和相同的参数值下执行,直到直接或间接再次调用 OR。因此,第二个语句不需要重新指定 or 参数。该类的所有计算函数都遵循具有三个不同签名的相同模式:setSurface(srf)setParameter(param)setSurface()setParameter()srfparamAcGePointOnSurface AcGeVector3d uDeriv (int order) const; AcGeVector3d uDeriv (int order, const AcGePoint2d& param); AcGeVector3d uDeriv ( int order, const AcGeSurface& srf, const AcGePoint2d& param); AcGeVector3d vDeriv (int order) const; AcGeVector3d vDeriv (int order, const AcGePoint2d& param); AcGeVector3d vDeriv ( int order, const AcGeSurface& srf, const AcGePoint2d& param); AcGeVector3d mixedPartial () const; AcGeVector3d mixedPartial (const AcGePoint2d& param); AcGeVector3d mixedPartial ( const AcGeSurface& srf, const AcGePoint2d& param); AcGeVector3d normal () const; AcGeVector3d normal (const AcGePoint2d& param); AcGeVector3d normal ( const AcGeSurface& srf, const AcGePoint2d& param); 同样,该类有三个构造函数:AcGePointOnSurface AcGePointOnSurface (); AcGePointOnSurface (const AcGeSurface& srf); AcGePointOnSurface ( const AcGeSurface& srf, const AcGePoint2d& param); 使用第一个构造函数时,不指定曲面或参数值。据推测,您在第一次评估之前设置了曲面和参数值。为了防止构造未初始化的对象,第一个构造函数将曲面设置为 XY 平面,并将参数值设置为默认值。第二个构造函数调用参数值并将其设置为默认值 。第三个构造函数调用 和 。第二个构造函数在将曲面作为参数传入的函数中特别有用:AcGePlane::kXYPlane,(0,0)setSurface(srf)(0,0)setSurface(srf)setParameter(param) void func (const AcGeSurface& srf) { AcGePointOnSurface pntOnSrf (srf); . . . } 构造函数调用,以便此函数中的所有后续求值都对 执行。setSurface(srf)srf 由于该类封装了有关曲面上特定点的参数化空间信息和模型空间信息,因此对于需要返回有关曲面上一个或多个不同点的信息的函数非常有用。例如,该类包含成员函数:AcGePointOnSurfaceAcGeSurface void getClosestPointTo ( const AcGePoint3d& pnt3d, AcGePointOnSurface& closestPoint, const AcGeTol& tol = AcGeContext::gTol) const; 此函数返回曲面上最接近输入点的点。最接近的点以对象形式返回,其中包含参数值、模型空间点以及有关曲面上该特定点的其他信息。AcGe 库中返回对象作为输出参数(non)的所有函数都已调用该参数。因此,调用此类函数后,无需重置曲面或参数值。例如,以下代码获取曲面上最接近该点的参数值、模型空间点和一阶导数:pnt3dAcGePointOnSurfaceAcGePointOnSurfaceconstsetSurface()setParameter()srfpnt3d // Compute the closest point on the surface to pnt3d. AcGePointOnSurface closestPoint; srf.getClosestPointTo (pnt3d, closestPoint); // Get parameter value, model space point, and first derivative // vectors of closest point. AcGePoint2d param = closestPoint.parameter(); AcGePoint3d pnt3d = closestPoint.point(); AcGeVector3d uFirstPartial = closestPoint.uDeriv(1), vFirstPartial = closestPoint.vDeriv(1); 对 、 或 的调用都不需要指定图面或参数值,因为它们已由 设置。通常,除非您明确打算更改对象的图面或参数值,否则不应调用 。例如,以下代码中的第一个语句间接调用 和 。第二个和第三个语句效率低下,因为它们对第一个语句进行了不必要的调用,并使用与第一个语句完全相同的参数。point()uDeriv()vDeriv()getClosestPointTo()setSurface()setParameter()AcGePointOnSurfacesetSurface()setParameter()setSurface()setParameter(), AcGePoint3d pnt3d = pntOnSrf.point (srf, param); AcGeVector3d uFirstPartial = pntOnSrf.uDeriv (1, srf, param); AcGeVector3d vFirstPartial = pntOnSrf.uDeriv (1, param); 此代码正确执行;但是,按如下方式编写它更有效: AcGePoint3d pnt3d = pntOnSrf.point (srf, param); AcGeVector3d uFirstPartial = pntOnSrf.uDeriv (); AcGeVector3d vFirstPartial = pntOnSrf.uDeriv (); 、 和 类不仅提供了一种封装曲线或曲面上点的参数空间和模型空间信息的方法,而且还为曲线和曲面赋值器提供了比传统赋值器更简单、更自然的接口。典型的 C 型曲面评估器如下所示:AcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurface void evaluate ( int numDeriv, double u, double v, Point& pnt, Vector[] derivArray); 在这里,您可以指定参数值(曲面的参数值是坐标为 的 的 2D 点),并请求要返回的导数数。然后,赋值器在指定的参数值处计算点和请求的导数。如果请求衍生品,您必须知道它们的返回顺序。例如,混合部分是否存储在数组的第四个或第五个元素中?您还必须确保不要传入太小的数组,否则将发生内存覆盖。当赋值器最初被调用为零导数或一个导数(数组大小为 2 for )时,这可能是一个问题,后来又更改为返回两个导数。如果忘记增加 的大小,则会发生内存覆盖,因为赋值器将五个导数向量(两个一阶导数和三个二阶导数)返回到只能容纳两个向量的数组中。uvderivArrayderivArray 在类中,您可以使用 、 、 、 和 函数以简单的方式请求点、导数和正态信息。这些函数的名称清楚地表明它们返回的值,并且不存在内存覆盖的危险。您不必索引到数组中来获取导数向量,也不必冒着犯错误的风险,也不必为一个或多个向量使用错误的索引。该类提供了图面赋值器的接口,从而生成了更简单的代码,对其他程序员来说也更易读和理解。AcGePointOnSurfacepoint()uDeriv()vDeriv()mixedPartial()normal()AcGePointOnSurface 除了为曲线和曲面赋值器提供更简单、更自然的接口外,类 、 和 类还提供了比传统赋值器更有效的接口。这是因为这些类中的每一个都包含指向数据区域的指针,赋值器可以使用该指针在评估之间存储信息。例如,NURBS 赋值器使用此区域来存储幂基矩阵,这些矩阵不作为曲面定义的一部分存储。通过使用此数据区域,评估人员可以避免重新计算在先前评估中计算的相同数据,从而更有效地运行。此数据不是曲线类或曲面类的一部分,因为评估可能以交替方式在多个区域进行,这将导致在切换上下文中局部评估数据的低效丢失。AcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurface 当对对象应用转换时,此数据区域还允许赋值器更加高效。如果在对象上调用该函数,则会导致后续计算由指定的转换进行转换,而不会实际转换底层图面。这意味着赋值人员必须将变换应用于他们计算的每个点、导数和法向量。通过使用对象的数据区,赋值人员可以避免在每次赋值时实际应用此变换。例如,该类包含数据成员 、 和 ,它们定义平面的原点和轴。赋值器使用以下语句评估点:AcGePointOnSurfacetransformBy()AcGePointOnSurfaceAcGePointOnSurfaceAcGePlanemPointmUAxismVAxisAcGePlane AcGePoint3d pnt3d = mPoint + param.x * mUAxis + param.y * mVAxis; 如果已为对象调用,则必须先应用此转换,然后才能将其返回给调用方。赋值器可以通过将变换后的 、 和 存储在数据域中来避免矩阵乘法的支出。然后,上面的语句将计算变换位置中的点,而无需矩阵乘法的额外费用。这在装配建模等应用中特别有用,在这些应用中,曲线和曲面已通过定位变换转换为装配空间。transformBy()AcGePointOnSurfacepnt3dmPointmUAxismVAxisAcGePointOnSurface 父主题: |
|Archiver|CAD开发者社区
( 苏ICP备2022047690号-1 苏公网安备32011402011833)
GMT+8, 2025-3-14 07:02
Powered by Discuz! X3.4
Copyright © 2001-2021, Tencent Cloud.