65.9K
CodeProject 正在变化。 阅读更多。
Home

公有域几何工具库中的参数曲线和曲面

starIconstarIconstarIconstarIconstarIcon

5.00/5 (3投票s)

2015年5月12日

公共领域

6分钟阅读

viewsIcon

21192

描述参数曲线和曲面以及如何使用我的公有域 HTML 3D 库生成它们

引言

本页面描述了参数曲线和曲面以及如何使用我的公有域 几何工具库 生成它们。

该库最新版本的源代码可在 几何工具库项目页面 获取。

目录

什么是参数曲面?

参数曲面是通过评估向量函数的结果生成的曲面。这个向量函数接受两个数字 U 和 V,并返回一个 3D 点 X、Y 和 Z。每个 (U, V) 点对应一个位于曲面上的 (X, Y, Z) 点。

3D 中的向量函数是三个函数的组合,每个维度一个

  • F(u, v) = [ x(u, v), y(u, v), z(u, v) ];

x 函数在给定 u 和 v 的情况下返回 X 坐标,yz 同样。由于 z 函数返回 Z 坐标,如果 z 始终返回相同的值,则曲面将是 2D 的。

例如,如果我们有一个由以下函数定义的参数曲面

  • x(u, v) = u * v
  • y(u, v) = -u
  • z(u, v) = u * sqrt(v)

并且我们评估 UV 点 (2, 4),那么我们有

  • F(2, 4) = [ 2 * 4, -2, 2 * sqrt(4) ];
  • F(2, 4) = [ 8, -2, 4 ];

所以 (8, -2, 4) 是位于此参数曲面上的一个点,通过评估不同的 UV 点可以找到曲面上的任何其他点。顺便说一句,曲面看起来像这样

**The parametric surface.**

为什么是两个变量?

曲面函数接受两个变量 uv,因为参数曲面可以看作是矩形网格的“变形”版本。向量函数将此网格“变形”为三维曲面。

几何工具库中的参数曲面

几何工具库使用名为 SurfaceBuilder 的类支持参数曲面。它有助于使用参数曲面函数生成顶点坐标和其他属性。以下辅助函数 makeMesh 生成参数曲面网格。注释详细解释了 makeMesh 的工作原理。

function makeMesh(func,resolutionU, resolutionV){
   "use strict";
   if(typeof resolutionV === "undefined" || resolutionV === null)resolutionV = resolutionU;
   if(typeof resolutionU === "undefined" || resolutionU === null)resolutionU = 50;
   if(typeof resolutionV === "undefined" || resolutionV === null)resolutionV = 50;
      // define a color gradient evaluator for
      // demonstration purposes. Instead of X, Y, and Z,
      // generate a Red/Green/Blue color based on
      // the same parameters U and V as the surface
      // function for 3D points.
   var colorGradient = {
     "evaluate":function(u, v) {
       return [1 - u, v, u];
     }
   };
   return new H3DU.SurfaceBuilder()
      .positionNormal(func)
      .attribute(colorGradient, H3DU.Semantic.COLOR)
     // Evaluate the surface and generate a triangle
     // mesh, using resolution+1 different U coordinates,
     // and resolution+1 different V coordinates.
     // Instead of H3DU.Mesh.TRIANGLES, we could use
     // H3DU.Mesh.LINES to create a wireframe mesh,
     // or H3DU.Mesh.POINTS to create a point mesh.
      .evalSurface(H3DU.Mesh.TRIANGLES, resolutionU, resolutionV)
      .toMeshBuffer();
}

在几何工具库中,曲面评估器对象定义了一个方法evaluate,该方法在给定 U 参数和 V 参数的情况下返回一个 3D 点。(默认情况下,U 和 V 都从 0 到 1 之间取值。)

以下代码是一个非常简单的曲面评估器对象。

var evaluator = {
  "evaluate":function(u, v){
    // Take the U parameter as the X coordinate,
    // the V parameter as the Y coordinate, and 0 as
    // the Z coordinate.
    return [u, v, 0];
  }
};

评估器仅在右上象限生成一个正方形

**The parametric surface.**

以下评估器生成一个圆形圆盘

var evaluator = {
  "evaluate":function(u, v){
     // Return disc coordinates.
     return [u*Math.cos(v),u*Math.sin(v),0];
  },
  // Declare the usual range of the coordinates
  "endPoints":function(){ return [0,1,0,Math.PI*2]; }
};

**The parametric surface.**

现在是有趣的部分:这个评估器返回的不是一个圆盘,而是一个锥体,其长度沿着负 Z 轴延伸

var evaluator = {
  "evaluate":function(u, v){
     // Return cone coordinates, using the u
     // parameter as the Z axis.
     return [u*Math.cos(v),u*Math.sin(v),-u];
  },
  // Declare the usual range of the coordinates
  "endPoints":function(){ return [0,1,0,Math.PI*2]; }
};

以下形状已旋转以显示 Z 轴;旋转并不完美。

**The parametric surface.**

请注意,以上所有三个示例都使用一个名为evaluator的值。可以使用类似以下代码为曲面evaluator生成网格缓冲区

var meshBuffer = SurfaceBuilder.surfaceToBuffer(evaluator);

从参数曲面生成的 3D 网格缓冲区与任何其他网格缓冲区一样,用于其他网格缓冲区的相同函数和方法也可以用于此网格缓冲区。有关更多信息,请参阅 H3DU.MeshBufferShape 类的 API 参考。

链接曲面函数

使用曲面评估器对象的技术非常灵活。事实上,您可以链接评估器,使用一个评估器的输出作为另一个评估器的输入。这可以用于将曲面点变换到新的位置。

举个例子,我们将定义一个新的评估器,它移动参数曲面的位置。它接受一个现有曲面评估器和要移动曲面的单位数 X、Y 和 Z。请注意,此类别包含自己的evaluate方法,允许其自身传递给H3DU.SurfaceBuilder类的方法或上面的makeMesh方法。

function SurfaceShifter(evaluator, x, y, z) {
 // Shift the surface by X units.
 this.x = x;
 // Shift the surface by Y units.
 this.y = y;
 // Shift the surface by Z units.
 this.z = z;
 this.evaluator = evaluator;
 // Define the surface shifter function
 this.evaluate = function(u, v){
  // Get the coordinates from the source evaluator
  var retval = this.evaluator.evaluate(u, v);
  // Shift the coordinates
  retval[0]+=this.x;
  retval[1]+=this.y;
  retval[2]+=this.z;
  // And return the new coordinates.
  return retval;
 }
 this.endPoints=function(){
  return this.evaluator.endPoints()
 }
}

以下是其用法示例。我们将使用上面给出的圆盘曲面,并创建一个SurfaceShifter对象,将圆盘水平和垂直移动 3 个单位(默认情况下,圆盘将以原点 (0, 0, 0) 为中心)。

// This is the disc surface from before
var evaluator = {
  "evaluate":function(u, v){
     // Extend the range of v
     v*=Math.PI*2;
     // Return circle coordinates.
     return [u*Math.cos(v),u*Math.sin(v),0];
  },
  "endPoints":function() { return [0,Math.PI*2] }
}
// Create a shifter that results in the circle being moved 3 units
// up and 3 units to the right
evaluator = new SurfaceShifter(evaluator, 3, 3, 0);

参数曲线

几何工具库还包括对生成参数曲线的支持。参数曲线是由向量函数生成的曲线,类似于参数曲面,但现在函数只使用一个变量,如下所示

  • C(u) = [ x(u), y(u), z(u) ];

如前所述,xyz 函数返回曲线的相应坐标。并且每个 (U) 点对应一个位于曲面上的 (X, Y, Z) 点。

曲线函数只接受一个 u 变量,因为参数曲线可以看作是直线的“变形”版本。

参数曲线的一个简单例子是圆。事实上,上面给出的圆盘曲面的相同源代码也可以用作圆的参数曲线函数,因为它只使用变量 u,而不使用 v

请注意,任何只使用 u 的曲面评估器都可以轻松地用作参数曲线评估器,并且任何 v 参数保持相同值(例如 0、1 或任何其他常数)的曲面也可以。

生成参数曲线

几何工具库的 CurveBuilder 类为参数曲线生成顶点。

使用以下代码生成描述参数曲线的网格。它假定 evaluator 是一个参数曲线对象,就像上面的圆形示例一样。

var meshBuffer = CurveBuilder.curveToBuffer(evaluator);

几何工具库中的曲线和曲面评估器

几何工具库发行版包括以下曲线和曲面评估器。下面列出的所有类都包含一个evaluate方法,该方法返回位于曲线或曲面上的 3D 点。

通用曲线包括

  • B 样条曲线。这些曲线由控制点(控制曲线的形状但不一定位于曲线上)和节点矢量(控制控制点的行为)组成。B 样条曲线包括 NURBS 曲线(非均匀有理 B 样条曲线,带权重和非均匀节点),使其成为设置曲线行为的强大方式。B 样条曲线使用 BSplineCurve 类创建。
  • 贝塞尔曲线。这些曲线的第一个和最后一个控制点是曲线的端点。贝塞尔曲线是 B 样条曲线的子集,使用 BSplineCurve.fromBezierCurve 方法创建。
  • 分段曲线。这些曲线由一个或多个其他曲线组成。分段曲线使用 PiecewiseCurve 类创建。

通用曲面包括

  • 贝塞尔曲面。3D 曲面,其中每条网格线都是贝塞尔曲线。贝塞尔曲面使用 BSplineSurface.fromBezierSurface 方法创建。
  • B 样条曲面。3D 曲面,其中每条网格线都是 B 样条或 NURBS 曲线。B 样条曲面使用 BSplineSurface 类创建。

特殊曲面包括

  • 管。以“加厚”3D 曲线形式的 3D 曲面。管使用 CurveTube 类创建,这是几何工具库中的一个补充扩展。
  • 旋转曲面。通过旋转 2D 曲线生成的曲面。旋转曲面使用 SurfaceOfRevolution 类创建,这是几何工具库中的一个补充扩展。

其他页面

我在 CodeProject 上的以下页面也讨论了几何工具库,前身为公有域 HTML 3D 库

© . All rights reserved.