使用JavaScript计算曲线的法线

Sic*_*Boy 1 javascript webgl

现在,这似乎是一个愚蠢的问题,但我如何计算曲线的法线?

为了计算表面的法线,我前段时间写了下面的函数,而不是在此期间考虑这个问题......

function calcNormals (source, destination) {

  var subtract = function (a, b) {

    var vec3 = new Array(3);

    vec3[0] = a[0] - b[0],
    vec3[1] = a[1] - b[1],
    vec3[2] = a[2] - b[2];

    return vec3;

  }


  var crossProduct = function (a, b) {

    var vec3 = new Array(3);

    vec3[0] = a[1] * b[2] - a[2] * b[1];
    vec3[1] = a[2] * b[0] - a[0] * b[2];
    vec3[2] = a[0] * b[1] - a[1] * b[0];

    return vec3;

  }


  var normalize = function (a) {

    var vec3 = new Array(3);

    var len = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];

    if (len > 0) {

      len = 1 / Math.sqrt(len);

      vec3[0] = len * a[0];
      vec3[1] = len * a[1];
      vec3[2] = len * a[2];

    }

    return vec3;

  }


  for (var i = 0; i < source.length / 9; i++) {

    var index = i * 9;

    var v1 = [

     source[index],
     source[index + 1],
     source[index + 2]

    ];

    var v2 = [

      source[index + 3],
      source[index + 4],
      source[index + 5]

    ];

    var v3 = [

      source[index + 6],
      source[index + 7],
      source[index + 8]

    ];

    var p12 = subtract(v2, v1),
        p23 = subtract(v3, v2);

    var cp = crossProduct(p12, p23);

    var normal = normalize(cp);


    for (var n = 0; n < 3; n++) {

      destination.push( normal[0], normal[1], normal[2] );

    }

  }

}
Run Code Online (Sandbox Code Playgroud)

所以,这个函数适用于任意表面:我只需要关心正确方向的顶点,然后传入存储它们的数组,并为计算的法线添加一个空数组.

但原因仅适用于三角形,但我如何计算线的法线?

计算曲线的法线取决于曲线本身最初是如何计算的,或者是否可以像上面所描述的那样使用类似通用的函数,只使用顶点数组作为输入,这样我可以只扩展这个现有函数?

Pet*_* O. 5

曲线有无限多的可能法向量.

通常:

  • 您可以通过获取曲线函数的导数并对其进行标准化来找到曲线的切线向量.
  • 选择与切向量正交的任意向量并对其进行标准化.这是正常的.一个这样的矢量是曲线函数的归一化二阶导数.通过取切线和任意选择的载体,取其交叉积,并对结果进行归一化,得到另一种这样的载体.
  • 取正切和法线向量并取出它们的叉积,并将结果标准化.这是副标准.

tangent-normal-binormal的组合也称为Frenet帧.