【发布时间】:2016-04-17 18:52:00
【问题描述】:
我编写了一个函数,它应该使用Bernstein polynomials 从参数 u 和 v(它们是 [0, 1] 的元素)的 4x4 控制点矩阵中返回双三次 Bézier surface 上的一个点。但要么我的功能没有发挥应有的作用,要么我对这件事的理解比我想象的还要糟糕。
计算点的函数如下所示:
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的结果是-0.4437500000000001对于x,0.5625对于y和-4.683753385137379e-17对于z,而这不是我所期望的。我的意思是,乍一看,x 和 y 的返回值似乎是合理的,但考虑到控制点矩阵提供的值,z 的返回值看起来完全错误。
据我了解,贝塞尔曲线的点以及贝塞尔曲面的点始终包含在控制多边形的凸包内,这里由 4x4 矩阵的点表示。那么,当控制点的z值范围仅从-1.0到1.0时,曲面的计算点怎么会有z值< -4.0呢?
如果我们假设结果是错误的,那么我计算表面上的点的函数一定有问题,但是虽然交替盯着bezierSurface和贝塞尔表面的数学定义有一段时间,我还没有发现错误。我希望其他人可以。
【问题讨论】:
标签: javascript math