gpt4 book ai didi

javascript - 如何计算二十面体的法线?

转载 作者:行者123 更新时间:2023-11-30 16:57:14 26 4
gpt4 key购买 nike

我想计算原点为 {0.0, 0.0, 0.0} 的二十面体的法线,但我不知道该怎么做!

例如,当我之前构建一个立方体时,获得法线相当简单,因为立方体的每个面都平行于 x、y 或 z 轴,并且包含顶点和法线的数组看起来像那样:

var vertices = [
-1.0, -1.0, 1.0, 1.0, -1.0, 1.0,
1.0, 1.0, 1.0, -1.0, 1.0, 1.0,

-1.0, -1.0, -1.0, -1.0, 1.0, -1.0,
1.0, 1.0, -1.0, 1.0, -1.0, -1.0,

-1.0, 1.0, -1.0, -1.0, 1.0, 1.0,
1.0, 1.0, 1.0, 1.0, 1.0, -1.0,

-1.0, -1.0, -1.0, 1.0, -1.0, -1.0,
1.0, -1.0, 1.0, -1.0, -1.0, 1.0,

1.0, -1.0, -1.0, 1.0, 1.0, -1.0,
1.0, 1.0, 1.0, 1.0, -1.0, 1.0,

-1.0, -1.0, -1.0, -1.0, -1.0, 1.0,
-1.0, 1.0, 1.0, -1.0, 1.0, -1.0
];

var normals = [
0.0, 0.0, 1.0, 0.0, 0.0, 1.0,
0.0, 0.0, 1.0, 0.0, 0.0, 1.0,

0.0, 0.0, -1.0, 0.0, 0.0, -1.0,
0.0, 0.0, -1.0, 0.0, 0.0, -1.0,

0.0, 1.0, 0.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.0, 1.0, 0.0,

0.0, -1.0, 0.0, 0.0, -1.0, 0.0,
0.0, -1.0, 0.0, 0.0, -1.0, 0.0,

1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
1.0, 0.0, 0.0, 1.0, 0.0, 0.0,

-1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
-1.0, 0.0, 0.0, -1.0, 0.0, 0.0
];

但是现在,在我的二十面体上工作,事情变得有点复杂......

编辑 1:

按照给出的答案的说明,我尝试以这种方式计算法线:

首先我将顶点存储在一个多维数组中:

var r = (1 + Math.sqrt(5)) / 2;

var triangles = [

[ [-1.0, r, 0.0], [0.0, 1.0, r], [1.0, r, 0.0] ],
[ [1.0, r, 0.0], [0.0, 1.0, -r], [-1.0, r, 0.0] ],
[ [1.0, r, 0.0], [0.0, 1.0, r], [r, 0.0, 1.0] ],
[ [1.0, r, 0.0], [r, 0.0, -1.0], [0.0, 1.0, -r] ],
[ [r, 0.0, -1.0], [1.0, r, 0.0], [r, 0.0, 1.0] ],
[ [-1.0, -r, 0.0], [1.0, -r, 0.0], [0.0, -1.0, r] ],
[ [-1.0, -r, 0.0], [0.0, -1.0, -r], [1.0, -r, 0.0] ],
[ [-1.0, -r, 0.0], [0.0, -1.0, r], [-r, 0.0, 1.0] ],
[ [-1.0, -r, 0.0], [-r, 0.0, -1.0], [0.0, -1.0, -r] ],
[ [-r, 0.0, 1.0], [-r, 0.0, -1.0], [-1.0, -r, 0.0] ],
[ [-1.0, r, 0.0], [-r, 0.0, 1.0], [0.0, 1.0, r] ],
[ [-1.0, r, 0.0], [0.0, 1.0, -r], [-r, 0.0, -1.0] ],
[ [-1.0, r, 0.0], [-r, 0.0, -1.0], [-r, 0.0, 1.0] ],
[ [1.0, -r, 0.0], [r, 0.0, 1.0], [0.0, -1.0, r] ],
[ [1.0, -r, 0.0], [0.0, -1.0, -r], [r, 0.0, -1.0] ],
[ [1.0, -r, 0.0], [r, 0.0, -1.0], [r, 0.0, 1.0] ],
[ [0.0, -1.0, -r], [-r, 0.0, -1.0], [0.0, 1.0, -r] ],
[ [0.0, -1.0, -r], [0.0, 1.0, -r], [r, 0.0, -1.0] ],
[ [0.0, 1.0, r], [-r, 0.0, 1.0], [0.0, -1.0, r] ],
[ [0.0, 1.0, r], [0.0, -1.0, r], [r, 0.0, 1.0] ]

];

然后,根据给定的答案,我编写了这个函数来计算法线...

var normals = [ ];

triangles.forEach(function (triangle) {
var v1 = triangle[0],
v2 = triangle[1],
v3 = triangle[2];
var p12 = new Array(3);
p12[0] = v2[0] - v1[0];
p12[1] = v2[1] - v1[1];
p12[2] = v2[2] - v1[2];
var p23 = new Array(3);
p23[0] = v3[0] - v2[0];
p23[1] = v3[1] - v2[1];
p23[2] = v3[2] - v2[2];
var cp = new Array(3);
var x1 = p12[0],
y1 = p12[1],
z1 = p12[2];
var x2 = p23[0],
y2 = p23[1],
z2 = p23[2];
cp[0] = y1 * z2 - z1 * y2;
cp[1] = z1 * x2 - x1 * z2;
cp[2] = x1 * y2 - y1 * x2;
var x = Math.pow(cp[0], 2),
y = Math.pow(cp[1], 2),
z = Math.pow(cp[2], 2);
var len = Math.sqrt(x + y + z);
var normal = new Array(3);
normal[0] = cp[0] / len;
normal[1] = cp[1] / len;
normal[2] = cp[2] / len;
for (var i = 0; i < 3; i++) {
normals.push(normal);
}
});

...最终解压并使用它们:

var unpackedNormals = [ ];

for (var n in normals) {
unpackedNormals = unpackedNormals.concat(normals[n]);
}

var vertexNormalData = unpackedNormals;

但不知何故,它并没有像它应该的那样工作!

我可以在屏幕上看到二十面体,但表面三 Angular 形的光照似乎完全错误。

我用我之前提到的立方体函数而不是构建二十面体的函数运行了同一个程序,并且一切正常,所以我认为错误必须位于这个计算法线的新函数中。

也许有人知道我做错了什么?

如有任何帮助,我将不胜感激!

PS:请原谅我的英语不好。

编辑 2:问题已解决!

我改变了三 Angular 形数组中向量的顺序,现在所有的三 Angular 形都表现得像它们应该的那样!

我也在这篇文章中更新了三 Angular 形数组,所以进一步向上的片段现在代表正确的顺序,AFAIK。

最佳答案

我认为您需要的是“叉积”,即两个向量的向量积。叉积将始终垂直于两个向量定义的平面。

http://en.wikipedia.org/wiki/Cross_product

对于二十面体的每个三 Angular 形,您都有描述边的向量(例如,如果 v1、v2 和 v3 是描述顶点的向量,则边为 p12 = v2-v1、p23 = v3-v2 和 p31 = v1 -v3).例如,您的法线将是标准化的三个向量中的两个的叉积(除以它的模数)

n123 = (p12 x p23) / (|p12 x p23|)

你应该知道的有用的东西:

  • 两个向量的差异

    p12 = v2 - v1 = [x2, y2, z2] - [x1, y1, z1] = [x2-x1, y2-y1, z2-z1]
  • 向量的模数(长度):

    |v| = |[x, y, z]| = sqrt(x^2 + y^2 + z^2)

希望这对您有所帮助。

关于javascript - 如何计算二十面体的法线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29488574/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com