I have a triangulated polyhedron (not necessarily convex) and the following information:
A list of the position of each vertex. A list of the vertex triples that define each face. A list of the vertex normals (Here the vertex normals are vectors from each vertex that are calculated by averaging face normals (see below) around each vertex).
I would like to calculate the list of face normals (The normalized vectors perpendicular to the plane of each face, pointing outward).
I have a triangulated polyhedron (not necessarily convex) and the following information:
A list of the position of each vertex. A list of the vertex triples that define each face. A list of the vertex normals (Here the vertex normals are vectors from each vertex that are calculated by averaging face normals (see below) around each vertex).
I would like to calculate the list of face normals (The normalized vectors perpendicular to the plane of each face, pointing outward).
Share Improve this question edited Feb 4, 2016 at 16:06 Wilt 44.5k15 gold badges160 silver badges214 bronze badges asked Dec 3, 2012 at 18:43 user1873329user1873329 1112 silver badges4 bronze badges 4- That is nice, why didn't you calculate it if you wanted to ? Did you use the Newell's method (opengl/wiki/Calculating_a_Surface_Normal) ? – mmgp Commented Dec 3, 2012 at 18:51
- I would like to be able to use this, but I don't know which way is "out" of the polyhedron, and so I can't deteremine in what order to take the cross product. Ideally there should be some way using the vertex nromals to determine which cross product is correct, but I'm just not sure how. – user1873329 Commented Dec 3, 2012 at 19:49
- One way to locally define an orientation is to consider a PCA from a k-neighborhood (a set of the k points closest to a given point), but this may not give a globally consistent orientation. I also remember several works from Nina Amenta regarding estimation by Voronoi poles and other methods, have you checked this author or anything related ? – mmgp Commented Dec 3, 2012 at 20:23
- A simple suggestion is to average the 3 normals that you already have at each vertex. If that value is not precise enough, then pute the face normal yourself, and keep the orientation that matches the normal puted by averaging. – nbonneel Commented Dec 4, 2012 at 1:37
2 Answers
Reset to default 7You can simply determines the orientation of crossed normal by dot it with one of vertex normal or average of all 3 vertices.
Here is the pseudo code:
Vec3 CalcNormalOfFace( Vec3 pPositions[3], Vec3 pNormals[3] )
{
Vec3 p0 = pPositions[1] - pPositions[0];
Vec3 p1 = pPositions[2] - pPositions[0];
Vec3 faceNormal = crossProduct( p0, p1 );
Vec3 vertexNormal = pNormals[0]; // or you can average 3 normals.
float dot = dotProduct( faceNormal, vertexNormal );
return ( dot < 0.0f ) ? -faceNormal : faceNormal;
}
Native three.js code to do this with three vertices a
, b
and c
:
You can get a
, b
and c
from your THREE.Face3
and geometry vertices:
var a = geometry.vertices[ face.a ];
var b = geometry.vertices[ face.b ];
var c = geometry.vertices[ face.c ];
and then you do:
var normal = new THREE.Vector3().crossVectors(
new THREE.Vector3().subVectors( b, a ),
new THREE.Vector3().subVectors( c, a )
).normalize();
But there are also convenience methods in the THREE.Geometry
class to do vertex and face calculations for you: puteVertexNormals
and puteFaceNormals
.