正确计算双三次曲线上的点;zier曲面

Correctly calculating point on a bicubic Bézier surface

本文关键字:曲线 曲面 zier 三次 计算      更新时间:2023-09-26

我写了一个函数,它应该使用Bernstein多项式从参数u和v的控制点的4x4矩阵返回双三次Bézier曲面上的一个点,参数u和v是[0,1]的元素。但要么我的功能没有正常工作,要么我对此事的理解比我想象的还要糟糕。

计算点的函数如下所示:

var bezierSurface = function (u, v, p) {
  var result = [];
  var p00 = p[0],  p01 = p[1],  p02 = p[2],  p03 = p[3],
      p10 = p[4],  p11 = p[5],  p12 = p[6],  p13 = p[7],
      p20 = p[8],  p21 = p[9],  p22 = p[10], p23 = p[11],
      p30 = p[12], p31 = p[13], p32 = p[14], p33 = p[15];
  var uin = (1 - u),
      vin = (1 - v);
  var bu0 = Math.pow(uin, 3),
      bu1 = 3 * u * Math.pow(uin, 2),
      bu2 = 3 * Math.pow(u, 2) * uin,
      bu3 = Math.pow(u, 3);
  var bv0 = Math.pow(vin, 3),
      bv1 = 3 * v * Math.pow(vin, 2),
      bv2 = 3 * Math.pow(v, 2) * vin,
      bv3 = Math.pow(v, 3);
  for (var i = 0; i < 3; i++) {
    result.push(
      p00[i] * bu0 * bv0 +
      p01[i] * bu0 * bv1 +
      p02[i] * bu0 * bv2 +
      p03[i] * bu0 * bv3 +
      p10[i] * bu1 * bv0 +
      p11[i] * bu1 * bv1 +
      p12[i] * bu1 * bv2 +
      p13[i] * bu1 * bv3 +
      p20[i] * bu2 * bv0 +
      p21[i] * bu2 * bv1 +
      p22[i] * bu2 * bv2 +
      p23[i] * bu2 * bv3 +
      p30[i] * bu3 * bv0 +
      p31[i] * bu3 * bv1 +
      p32[i] * bu3 * bv2 +
      p33[i] * bu3 * bv3
    );
  }
  return result;
};

这可能不是完成任务的最有效方法,但由于我刚刚开始使用参数化曲面,我试图让事情尽可能简单,但甚至没有考虑对曲面进行镶嵌以获得三角形的顶点或类似的东西。

现在,当我用以下参数调用函数时,出现了问题

var getSurfacePoint = function () {
  var u = 0.5,
      v = 0.25;
  var cp = [
    [-1.0, 0.0, -1.0],
    [-0.5, 0.3, -0.8],
    [ 0.5, 0.3, -0.8],
    [ 1.0, 0.0, -1.0],
    [-0.8, 0.3, -0.5],
    [-0.3, 1.0, -0.4],
    [ 0.3, 1.0, -0.4],
    [ 0.8, 0.3, -0.5],
    [-0.8, 0.3,  0.5],
    [-0.3, 1.0,  0.4],
    [ 0.3, 1.0,  0.4],
    [ 0.8, 0.3,  0.5],
    [-1.0, 0.0,  1.0],
    [-0.5, 0.3,  0.8],
    [ 0.5, 0.3,  0.8],
    [ 1.0, 0.0,  1.0]
  ];
  return bezierSurface(u, v, cp);
};

通过getSurfacePoint调用bezierSurface的结果是x-0.4437500000000001y0.5625z则为-4.683753385137379e-17,这是我所期望的而不是。我的意思是,乍一看,x和y的返回值似乎是合理的,但考虑到控制点矩阵提供的值,z的返回值看起来完全错误。

据我所知,Bézier曲线的点和Bézier曲面的点总是被包围在控制多边形的凸包内,这里由4x4矩阵的点表示。那么,当控制点的z值范围仅从-1.01.0时,曲面的计算点如何具有z值< -4.0

如果我们假设结果错误的,那么我计算曲面上的点的函数一定有问题,但尽管交替地盯着bezierSurface和Bézier曲面的数学定义看了一段时间,我还是没能发现错误。我希望其他人可以。

z的返回值看起来完全错误

-4.683753385137379e-17,该值(几乎)为0。结果看起来非常正确。