Malla suavizado con Gauss
Pregunta
deseo de suavizar una malla dada 3D, que utiliza la estructura de Half-Edge para almacenar información de adyacencia, utilizando una función de Gauss. El siguiente es el algoritmo que se propuso:
Suavizar la malla moviendo cada vértice a una posición determinada por un ponderada promedio de sus vecinos inmediatos (Con los pesos determinados por una gaussiana con sigma igual a la longitud media de bordes unidos al vértice, normalizado tal que la suma de pesos a uno).
Así que para cada vértice curr_vertex
, I
- calcular la longitud media de sus bordes unidos
- obtener todos los vértices vecinos
- determinar el peso de cada vértice vecino haciendo lo siguiente: `
= peso exp (- (distancia * distancia) / (2 sigma sigma))
where distance is the 3D distance between the
curr_vertexand the neighbor and
sigma= average length of attached edges of
curr_vertex`
- resumen todos los pesos y dividir el peso de cada vecino por esta suma (etapa de normalización)
- multiplican la posición de cada vértice vecina por su peso correspondiente
- se suman todos los vértices ponderados y añadir el resultado a curr_vertex para producir el nuevo vértice.
Cuando hago esto y dirigir mi algoritmo, en lugar de suavizar lo que realmente sucede es una escala -. Mi mesh solo se agranda sin ninguna aparente suavización
¿Alguna idea de lo que estoy haciendo mal?
Editar: Aquí está el código que tengo:
void R3Mesh::
Smooth(void)
{
R3Mesh *new_mesh = new R3Mesh(*this);
for(int i = 0; i < NVertices(); i++)
{
R3MeshVertex *v = Vertex(i);
map<R3MeshVertex *, double> neighbors; // stores vertex-weight pairs
map<R3MeshVertex *, double>::iterator neighbors_iter;
// store each vertex neighbor by going through
// all adjacent edges and obtaining those edges' vertices
R3MeshHalfEdge *tmp = v->half_edge;
do
{
neighbors.insert(make_pair(tmp->opposite->vertex,0));
tmp = tmp->opposite->next;
}while(tmp != v->half_edge);
// determine the sigma to use for Gaussian
double sigma = v->AverageEdgeLength();
double weight = 0, total_weight = 0;
double distance;
// determine and store the weight of each neighboring vertex
for(neighbors_iter = neighbors.begin(); neighbors_iter != neighbors.end();
neighbors_iter++)
{
distance = R3Distance(v->position, neighbors_iter->first->position);
weight = (1./(sigma*sqrt(2.*3.14)))*exp(-(distance*distance)/(2.*sigma*sigma));
total_weight += weight;
neighbors_iter->second = weight;
}
// determine new position of current vertex
R3Point new_pos = v->position;
for(neighbors_iter = neighbors.begin(); neighbors_iter != neighbors.end();
neighbors_iter++)
{
new_pos += (neighbors_iter->second/total_weight)*(neighbors_iter->first->position);
}
new_pos.Translate(new_pos - v->position);
new_mesh->Vertex(i)->position.Reset(new_pos.X(), new_pos.Y(), new_pos.Z());
neighbors.clear();
}
*this = *new_mesh;
}
Solución
Esto huele de una cabeza palmadas error tipográfico estilo. El algoritmo como usted la describe ve bien a mí.
En primer lugar verificar claramente la normalización de los pesos.
A continuación compruebe su código en el que escriba de nuevo la posición de vértice calculados en la nueva malla suavizada.
Estos son mis conjeturas. No dude en enviar un fragmento de código si los que no funcionan.