如何计算二十面体的法线
How to calculate normals for an icosahedron?
我想计算原点为{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;
但不知怎么的,它并没有正常工作!
我可以在屏幕上看到二十面体,但表面三角形的照明似乎完全错误。
我用前面提到的立方体函数而不是构造二十面体的立方体函数运行了同样的程序,它运行得非常好,所以我认为误差必须位于这个新函数中才能计算法线。
也许有人知道我做错了什么?
如果有任何帮助,我将不胜感激!
附言:请原谅我英语不好。
编辑2:问题解决了!
我改变了三角形数组中向量的顺序,现在所有三角形的行为都像它们应该的那样!
我在这篇文章中也更新了三角形阵列,所以进一步剪切的现在代表了正确的顺序,AFAIK。
我认为您需要的是"叉积",两个向量的向量积。叉积将始终垂直于由两个向量定义的平面。
http://en.wikipedia.org/wiki/Cross_product
对于二十面体的每个三角形,都有描述边的向量(例如,如果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)
希望这能有所帮助。
如果您只对结果感兴趣,下面是我从Blender导出的Wavefront二十面体.obj文件,其中包含三角形顶点、纹理和法线。
# Blender v2.77 (sub 0) OBJ File: 'icosahedron.blend'
# www.blender.org
mtllib icosahedron.mtl
o Icosphere
v 0.000000 -1.000000 0.000000
v 0.723600 -0.447215 0.525720
v -0.276385 -0.447215 0.850640
v -0.894425 -0.447215 0.000000
v -0.276385 -0.447215 -0.850640
v 0.723600 -0.447215 -0.525720
v 0.276385 0.447215 0.850640
v -0.723600 0.447215 0.525720
v -0.723600 0.447215 -0.525720
v 0.276385 0.447215 -0.850640
v 0.894425 0.447215 0.000000
v 0.000000 1.000000 0.000000
vt 0.6739 0.5441
vt 0.5057 0.4329
vt 0.6731 0.1917
vt 0.5162 0.7848
vt 0.8418 0.4311
vt 0.8321 0.7831
vt 0.3418 0.5689
vt 0.3321 0.2169
vt 1.0162 0.2152
vt 1.0057 0.5671
vt 1.1731 0.8083
vt 0.1731 0.8083
vt 0.1739 0.4559
vt 0.0162 0.2152
vt 0.0057 0.5671
vn 0.1876 -0.7947 0.5774
vn 0.6071 -0.7947 0.0000
vn -0.4911 -0.7947 0.3568
vn -0.4911 -0.7947 -0.3568
vn 0.1876 -0.7947 -0.5774
vn 0.9822 -0.1876 0.0000
vn 0.3035 -0.1876 0.9342
vn -0.7946 -0.1876 0.5774
vn -0.7946 -0.1876 -0.5774
vn 0.3035 -0.1876 -0.9342
vn 0.7946 0.1876 0.5774
vn -0.3035 0.1876 0.9342
vn -0.9822 0.1876 0.0000
vn -0.3035 0.1876 -0.9342
vn 0.7946 0.1876 -0.5774
vn 0.4911 0.7947 0.3568
vn -0.1876 0.7947 0.5774
vn -0.6071 0.7947 0.0000
vn -0.1876 0.7947 -0.5774
vn 0.4911 0.7947 -0.3568
usemtl None
s off
f 1/1/1 2/2/1 3/3/1
f 2/2/2 1/1/2 6/4/2
f 1/1/3 3/3/3 4/5/3
f 1/1/4 4/5/4 5/6/4
f 1/1/5 5/6/5 6/4/5
f 2/2/6 6/4/6 11/7/6
f 3/3/7 2/2/7 7/8/7
f 4/5/8 3/3/8 8/9/8
f 5/6/9 4/5/9 9/10/9
f 6/4/10 5/6/10 10/11/10
f 2/2/11 11/7/11 7/8/11
f 3/3/12 7/8/12 8/9/12
f 4/5/13 8/9/13 9/10/13
f 5/6/14 9/10/14 10/11/14
f 6/4/15 10/12/15 11/7/15
f 7/8/16 11/7/16 12/13/16
f 8/14/17 7/8/17 12/13/17
f 9/15/18 8/14/18 12/13/18
f 10/12/19 9/15/19 12/13/19
f 11/7/20 10/12/20 12/13/20
- 根据元素和容器大小计算边距
- 从Rally获取一个特定的标记,以便计算另一个字段中的值
- 砌体不能填补小缺口
- 使用D3.js计算带有字母间距的文本长度
- 使用CSS或JavaScript计算分页符的数量
- 可以't计算自定义谷歌地图的js
- 如何计算每个元素's的高度,并将这些值用作函数中的变量
- JavaScript计算帮助(乘以时间)
- 如何计算对象文字中的键
- JavaScript循环无法正确计算/显示结果
- 与域在同一台计算机上运行的NODEJS服务器的CORS错误
- 四舍五入JavaScript计算
- 如何将元素从iframe附加到父体
- 计算HTML中的页数
- 如何计算二十面体的法线
- 如何在二十面体上使三角形侧面积增加和减少,而形状却不保持“完整”
- 有百分比宽度的位置固定元件可以从体宽计算吗?
- 计算如果数字字符串循环|十六进制网格圆形世界
- Javascript:根据属性计算产品变体的数量
- 计算SVG/string中的所有十六进制颜色代码