Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Patch Normals Algorithm

I'm trying hard to reproduce a MATLAB algorithm called "patchnormal" which first calculates the normal vectors of all faces, and after that calculates the vertex normals from the face normals weighted by the angles of the faces. (See illustration below)

There doesn't seem to be a free library available for 3D mesh in WPF C# oriented to such mathematical use. Or is there ?

So the question is : How do I compute this (red) vector for all my vertices? Can it be optimized to be used in real time simulation ?

PatchNormal Illustration Image
(source: hostingpics.net)

like image 747
Raztou3D Avatar asked Sep 17 '12 08:09

Raztou3D


People also ask

What are vertex normals used for?

Vertex normals (sometimes called pseudo-normals) are values stored at each vertex that are most commonly used by a renderer to determine the reflection of lighting or shading models, such as phong shading. For example, the normal of a surface is used to calculate which direction light reflects off this surface.

How many normals does a vertex have?

In fact, from a practical and technical point of view, each triangle has its own set of 3 vertex normals.

How do you find the vertex normal?

The algorithm to compute such vertex normals is as follows: First, allocate an array of normals, one for each vertex in the mesh, and initialize them to zero (Point3( 0,0,0)). Then for each face, compute its face normal, and add it into each of the three vertex normals that the face contributes to.


1 Answers

You can compute the angle between two edges as follows:

given:  edge vectors E and F for a given face of your vertex,

E_normalized = normalize(E)
F_normalized = normalize(F)
cross_normal = cross(E_normalized, F_normalized)
sin_theta = length( cross_normal )
cos_theta = dot(E_normalized, F_normalized)

results:
    face normal = normalize(cross_normal)
    face angle theta = atan2(sin_theta, cos_theta)

Then, weight the normals accordingly:

total_vector = vec(0,0,0)
for(each face adjacent to a particular vertex):
    [compute normal and theta as above]
    total_vector += normal * theta
return normalize(total_vector)

To optimize for real-time, I would first profile to see what was actually slowing things down. I'd guess that computing atan2() several times per vertex might turn out to be expensive, but improving on that would really require finding some substitute for angle-weighted normals.

like image 166
comingstorm Avatar answered Oct 02 '22 19:10

comingstorm