CAD开发者社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

ObjectARX 开发指南

特殊评估类

2022-12-31 13:45| 发布者: admin| 查看: 1809| 评论: 0|来自: AutoCAD

以下部分介绍 AcGe 库中的类,您可以使用这些类计算曲线和曲面上的点。这些类是、和。AcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurface

参数曲线由连续函数定义,该函数将实线(可能是整条实线)的某个间隔映射到 2D 或 3D 空间,具体取决于曲线是 2D 还是 3D。参数化曲面由连续函数定义,该函数将平面的某些连接子集(可能是整个平面)映射到 3D 空间。参数曲线或曲面上对应于特定参数值的点可以通过计算该参数值处的函数来获得。对于曲线,参数值是标量,对于曲面,参数值是 2D 点。uvuv

许多支持参数化曲线和曲面的几何建模系统都包含赋值器函数,用于计算参数化曲线和曲面上的点。这些赋值器通常具有要评估曲线或曲面的参数值以及要返回的导数数的输入参数。它们还具有计算点的输出参数和导数的向量数组。有时,赋值器包含用于请求和返回特定参数值的法线向量的附加参数。

除了针对每个曲线和曲面类的此类赋值器函数(调用的方法)之外,AcGe 库还包含赋值器类,并且可以通过这些类访问曲线和曲面赋值器。这些类有两个主要用途:evalPoint()AcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurface

  • 它们封装了有关曲线或曲面上特定点的所有几何信息,例如参数值、模型空间坐标、导数和曲率。
  • 它们为曲线和曲面赋值器提供了一个接口,比大多数 CAD 系统的传统赋值器界面更简单、更高效。

与 ,, 和类的公共接口是相同的,除了成员函数名称中的细微差异。例如,类包含返回导数向量的函数,而类包含两个函数,并且返回和偏导数。本节的其余部分介绍如何使用theclass,但此描述也适用于theandclasses,因为它们的接口与theclass的接口非常相似。AcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurfaceAcGePointOnCurve3dderiv(),AcGePointOnSurfaceuDeriv()vDeriv()uvAcGePointOnSurfaceAcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurface

要使用类来计算点和导数,必须指定要评估的表面以及要执行评估的参数值。以下两个成员函数设置对象的表面和参数值:AcGePointOnSurfaceAcGePointOnSurface

AcGePointOnSurface&  setSurface (const AcGeSurface&);
 
AcGePointOnSurface&  setParameter (const AcGePoint2d&); 

调用后,将在该图面上执行所有后续评估,直到再次调用其他图面。同样,在调用后,所有后续查询函数都会返回与该参数值有关的信息,直到再次为不同的参数值调用。例如,考虑 ifis anobject,is anobject,andis anobject,然后以下代码计算参数值的点和一阶导数: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);

第一个签名不带任何参数,并假定图面和参数值已由先前的调用 to and 设置。第二个签名假定曲面已由上一个调用设置,但它调用以在评估之前设置参数值。第三个签名调用在评估之前设置表面和参数值。只有第一个成员函数被声明为;另外两个通过设置表面和/或参数值来修改对象。现在,可以直接从前面的代码中删除 toand,如下所示: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);

第一个语句导致在执行评估之前调用 sand。随后的评估在同一表面上以相同的参数值进行,直到再次直接或间接调用。因此,第二个语句不需要重新指定任何一个理论参数。该类的所有求值函数都遵循具有三个不同签名的相同模式: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);

Similarly, there are three constructors for the class:AcGePointOnSurface

AcGePointOnSurface ();
 
AcGePointOnSurface (const AcGeSurface& srf);
 
AcGePointOnSurface (
    const AcGeSurface& srf, 
    const AcGePoint2d& param);

When using the first constructor, you do not specify a surface or parameter value. Presumably, you set the surface and parameter value before the first evaluation. To prevent the construction of an uninitialized object, the first constructor sets the surface to which is just the XY plane, and sets the parameter value to the default value . The second constructor calls and sets the parameter value to the default value of . The third constructor calls and . The second constructor is especially useful in functions in which a surface is passed in as an argument:AcGePlane::kXYPlane,(0,0)setSurface(srf)(0,0)setSurface(srf)setParameter(param)

void func (const AcGeSurface& srf)
{
    AcGePointOnSurface  	pntOnSrf (srf);
    .
    .
    .
}

The constructor calls so that all subsequent evaluations in this function are performed on . setSurface(srf)srf

Because the class encapsulates both the parametric and model space information about a particular point on a surface, it is useful for functions that need to return information about one or more distinct points on a surface. For instance, the class contains the member function:AcGePointOnSurfaceAcGeSurface

void 
getClosestPointTo (
    const AcGePoint3d& pnt3d, 
    AcGePointOnSurface& closestPoint, 
    const AcGeTol& tol = AcGeContext::gTol) const;

This function returns the closest point on the surface to the input point . The closest point is returned as an object, which contains the parameter value, model space point, and other information about that particular point on the surface. All functions in the AcGe library that return an object as an output argument (non) have already called and for that argument. Therefore, after calling such a function, you do not need to reset the surface or parameter value. For example, the following code obtains the parameter value, model space point, and first derivatives of the closest point on the surface to the point : 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);

None of the calls to , , or needs to specify the surface or parameter value, because they were already set by . In general, and should not be called unless you explicitly intend to change the surface or parameter value of the object. For example, the first statement in the following code indirectly calls and . The second and third statements are inefficient because they make unnecessary calls to and using the exact same arguments as the first statement.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);

This code executes correctly; however, it is more efficient to write it as follows:

AcGePoint3d	   pnt3d = pntOnSrf.point (srf, param);
AcGeVector3d	  uFirstPartial = pntOnSrf.uDeriv ();
AcGeVector3d	  vFirstPartial = pntOnSrf.uDeriv ();

The , , and classes not only provide a way to encapsulate the parameter space and model space information of a point on a curve or surface, they also provide a simpler and more natural interface to the curve and surface evaluators than the traditional evaluators. A typical C-style surface evaluator looks something like the following: AcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurface

void evaluate (
    int numDeriv, 
    double u, 
    double v, 
    Point& pnt,
    Vector[] derivArray);

在这里,您可以指定参数值(曲面的参数值是坐标为 的 2D 点),并请求要返回多少导数。然后,赋值器在指定的参数值下计算点和请求的导数。如果请求衍生品,您必须知道它们的返回顺序。例如,混合部分是否存储在数组的第四个或第五个元素中?您还必须确保不要传入太小的数组,否则会发生内存覆盖。当赋值器最初被调用为零导数或一个导数(数组大小为 2)时,这可能是一个问题,后来更改为返回两个导数。如果忘记增加 的大小,则会发生内存覆盖,因为计算器将五个导数向量(两个一阶导数和三个二阶导数)返回到一个只能容纳两个向量的数组中。uvderivArrayderivArray

使用类,您可以使用 ,,,, 和函数以简单的方式请求点、导数和正常信息。这些函数的名称清楚地指示它们返回的值,并且没有内存覆盖的危险。您不必索引到数组中来获取导数向量,并且冒着出错和对一个或多个向量使用错误索引的风险。Theclass 提供了一个与表面评估器的接口,从而产生了更简单的代码,其他程序员也更容易阅读和理解。AcGePointOnSurfacepoint()uDeriv()vDeriv()mixedPartial()normal()AcGePointOnSurface

除了为曲线和曲面赋值器提供更简单、更自然的接口外,,,和类还提供了比传统赋值器更高效的接口。这是因为这些类中的每一个都包含一个指向数据区域的指针,赋值程序可以使用该指针在评估之间存储信息。例如,NURBS 赋值器使用此区域来存储幂基矩阵,这些矩阵不作为表面定义的一部分存储。通过使用此数据区域,赋值人员可以避免重新计算在先前评估中计算的相同数据,从而提高操作效率。此数据不是曲线或表面类的一部分,因为评估可能以交替方式在多个区域中进行,这将导致在切换上下文中本地评估数据的效率低下丢失。AcGePointOnCurve2dAcGePointOnCurve3dAcGePointOnSurface

此数据区域还允许赋值器在将转换应用于对象时更加高效。如果在对象上调用该函数,则会导致后续计算由指定的转换进行转换,而不会实际转换底层表面。这意味着赋值器必须将变换应用于他们计算的每个点、导数和法线向量。通过使用对象的数据区域,评估者可以避免实际对每个评估应用此转换。例如,该类包含定义平面原点和轴的数据成员 and赋值器使用以下语句评估点:AcGePointOnSurfacetransformBy()AcGePointOnSurfaceAcGePointOnSurfaceAcGePlanemPointmUAxismVAxisAcGePlane

AcGePoint3d pnt3d = mPoint + param.x * mUAxis + 
                    param.y * mVAxis;

如果为对象调用了 If,则在将其返回给调用方之前,必须应用此转换。评估器可以通过将转换的、和存储在数据区域中来避免矩阵乘法的费用。然后,上述语句将评估转换位置中的点,而无需额外的矩阵乘法费用。在装配体建模等应用中,这是一项特别有用的功能,在这些应用中,曲线和曲面已通过定位变换转换为装配体空间。transformBy()AcGePointOnSurfacepnt3dmPointmUAxismVAxisAcGePointOnSurface


路过

雷人

握手

鲜花

鸡蛋

最新评论

QQ|Archiver|CAD开发者社区 ( 苏ICP备2022047690号-1 )

GMT+8, 2024-5-19 13:52

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部