正确计算双三次Bézier曲面上的点

时间:2016-01-12 23:36:32

标签: javascript math

我编写了一个函数,它应该使用Bézier surface从参数u和v的4x4控制点矩阵返回一个双点Bernstein polynomials上的点,这些参数是[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);
};

通过bezierSurface调用getSurfacePoint的结果为-0.4437500000000001 x 0.5625 y 和{ {1>} z ,那是不是我所期望的。我的意思是,乍一看,x和y的返回值似乎是合理的,但考虑到控制点矩阵提供的值,z的返回值看起来完全错误。

据我所知,Bézier曲线的点以及Bézier曲面的点总是包含在控制多边形的凸包内,这里用4x4矩阵的点表示。因此,当控制点的z值范围仅从-4.683753385137379e-17变为-1.0时,表面的计算点如何具有z值1.0

如果我们假设结果 错误,我的函数一定有问题来计算表面上的点,但是交替地盯着< -4.0和数学定义Bézier表面有一段时间了,我还没能发现错误。我希望别人可以。

1 个答案:

答案 0 :(得分:1)

  
    

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

  

-4.683753385137379 e-17 ,该值(差不多)为0.结果看起来非常正确。