使用JavaScript计算曲线的法线

使用JavaScript计算曲线的法线,javascript,webgl,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]

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

为了计算曲面的法线,我不久前编写了以下函数,同时没有考虑这个问题

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] );

    }

  }

}
函数calcNormals(源、目标){
var减法=函数(a,b){
var vec3=新数组(3);
vec3[0]=a[0]-b[0],
vec3[1]=a[1]-b[1],
vec3[2]=a[2]-b[2];
返回vec3;
}
var叉积=函数(a,b){
var vec3=新数组(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];
返回vec3;
}
变量规格化=函数(a){
var vec3=新数组(3);
var len=a[0]*a[0]+a[1]*a[1]+a[2]*a[2];
如果(len>0){
len=1/数学sqrt(len);
vec3[0]=len*a[0];
vec3[1]=len*a[1];
vec3[2]=len*a[2];
}
返回vec3;
}
对于(变量i=0;i
因此,该函数适用于任意曲面:我只需要关心顶点的方向是否正确,然后传入存储它们的数组,并为计算出的法线添加一个空数组

但是因果关系只适用于三角形,但是如何计算直线的法线呢


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

一条曲线有无限多个可能的法线向量

一般来说:

  • 通过求导数,可以找到曲线的切线向量 曲线的函数的定义和规格化
  • 选择与切线向量正交的任意向量 并使其正常化。这是正常的。一个这样的载体 是曲线函数的归一化二阶导数。另一个 这样的向量是通过取切线和任意选择的 向量,取它们的叉积,并对结果进行规格化
  • 取切线和法向量,取它们的 交叉积,并对结果进行规格化。这是副法线

切线法线副法线的组合也称为Frenet框架。

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

一般来说:

  • 通过求导数,可以找到曲线的切线向量 曲线的函数的定义和规格化
  • 选择与切线向量正交的任意向量 并使其正常化。这是正常的。一个这样的载体 是曲线函数的归一化二阶导数。另一个 这样的向量是通过取切线和任意选择的 向量,取它们的叉积,并对结果进行规格化
  • 取切线和法向量,取它们的 交叉积,并对结果进行规格化。这是副法线

切线法线副法线的组合也称为Frenet帧。

您是在寻找曲线的法线吗?那将是一架飞机。通过计算顶点的切线和双切线,你会得到相同的数据。“直线”不就是退化三角形吗?你是在寻找曲线的法线吗?那将是一架飞机。通过计算顶点的切线和双切线,你会得到相同的数据。“直线”不就是退化三角形吗?谢谢你的回答,彼得!考虑到一条直线没有两个可能的方向,与三角形不同,我有点希望需要额外的参数,比如定义一些基本方向,但我希望我可以独立于创建曲线的函数来计算法线。但是,我的数学还不太熟练,所以这将是一个挑战…你可以通过使用差商
(f(x+h)-f(x))/h
来近似导数,并为
h
选择一个适当的小值。我在我的答案中添加了更多关于寻找正常人的信息。谢谢你的回答,彼得!考虑到一条直线没有两个可能的方向,与三角形不同,我有点希望需要额外的参数,比如定义一些基本方向,但我希望我可以独立于创建曲线的函数来计算法线。但是,我的数学还不太熟练,所以这将是一个挑战…你可以通过使用差商
(f(x+h)-f(x))/h
来近似导数,并为
h
选择一个适当的小值。在我的回答中,我添加了更多关于寻找正常人的信息。