我有一个具有3D 65.000位置坐标的3D闭合网格物体。 出于照明目的,我需要一个3D表面法线提取器。
你能帮帮我吗?
感谢。
理查德
答案 0 :(得分:3)
好的,这是一个执行此任务的通用算法,与您使用的语言和图形库无关。
现在,我必须强调,这是对为了做到这一点需要完成的事情的粗略描述,有些角落可以削减效率。我得到的是你不需要先计算所有三角形法线然后计算所有顶点法线 - 这两个步骤可以混合在一起制作东西更高效。
某些伪代码可能看起来像
Vector verts[65000]; // 65000 vertex positions
Triangle faces[87000]; // as an example, 87000 triangles
Vector normals[65000]; // 1 normal per vertex - initialised to (0, 0, 0)
// loop over all faces to calculate vertex normals
for (int i=0 ; i<87000 ; i++)
{
Vector v1 = verts[faces[i].vertex1];
Vector v2 = verts[faces[i].vertex2];
Vector v3 = verts[faces[i].vertex3];
Vector edge1 = v2 - v1;
Vector edge2 = v3 - v1;
Vector normal = edge1.CrossProduct(edge2); // or edge2.CrossProduct(edge1)
normal.Normalise();
normals[faces[i].vertex1] += normal;
normals[faces[i].vertex2] += normal;
normals[faces[i].vertex3] += normal;
}
// vertex normals need to be normalised
for (int i=0 ; i<65000 ; i++)
{
normals.Normalise();
}
关于缠绕顺序的其他一些评论 - 如果你弄错了,法线将指向内部,而不是向外。如上所述,只需更改交叉产品的顺序即可解决此问题。
答案 1 :(得分:0)
因为你有索引,我假设它是一个三角形列表/条带或扇形。阅读每个三角形。通过取三角形的2个向量的cross product来计算法线。你有1个问题。如果你不知道三角形的缠绕顺序,那么你可能得到相反的值。哪个软件创建了网格?你能在数据文件或软件中检查绕线顺序是什么吗?是左手还是右手?
答案 2 :(得分:0)
你需要的只是构成三角形两边的向量的交叉乘积,归一化为单位向量。
正如Andrew Keith在评论中所说,当你从“外面”看三角形时,你最好知道三角形是顺时针还是逆时针定义。如果你不能保证一致性,你手上就会弄得一团糟。但可能(或至少希望)创建该对象的代码是理智的。
答案 3 :(得分:0)
我不确定这是否会有所帮助,但请看一下link。
答案 4 :(得分:0)