Kämmeingriff mit Gaußglättung
Frage
Ich möchte eine bestimmte 3D-Mesh glätten, die die Halbrandstruktur zum Speichern von Nachbarschaftsinformationen verwendet, eine Gauß-Funktion verwendet wird. Im Folgenden ist der Algorithmus, der vorgeschlagen wurde:
Glätten Sie die Masche durch jede Ecke bewegt zu einer Position, durch eine gewichtete bestimmt Durchschnitt seiner unmittelbaren Nachbarn (Mit Gewichten bestimmt durch eine Gaußsche mit Sigma gleich der durchschnittlichen Länge von Kanten an den Scheitelpunkt befestigt ist, normalisiert, so dass die Gewichtungen sum Eins).
Also für jeden Vertex curr_vertex
, I
- Berechnung der durchschnittlichen Länge der befestigten Kanten
- erhalten alle der benachbarten Ecken
- bestimmt das Gewicht jeden benachbarten Scheitelpunktes durch folgende Maßnahmen: `
Gewicht = exp (- (Entfernung * Abstand) / (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`
- Summe all Gewichte und teilt jedes Gewicht des Nachbarn durch diese Summe (Normalisierungsschritt)
- multiplizieren die Position jedes benachbarten Scheitel durch sein entsprechendes Gewicht
- fügen Sie alle gewichteten Eckpunkte und fügen Sie das Ergebnis zu curr_vertex die neue Ecke zu erzeugen.
Wenn ich das tue und meine Algorithmus laufen, statt Glätten, was tatsächlich passiert ist eine Skala, -. Nur ohne sichtbare Glättung vergrößert wird mesh mein
Alle Gedanken auf, was ich falsch mache?
Edit: Hier ist der Code, dass ich:
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;
}
Lösung
Diese schmatzt eines Head-slapping Typo Stil Bug. Der Algorithmus, wie Sie sieht gut aus mir beschrieben.
Sie zunächst die Normalisierung der Gewichte eindeutig verifiziert.
Als nächstes Code überprüfen, wo Sie die berechneten Vertex pos in die neue geglättete Mesh schreiben zurück.
Das sind meine Vermutungen. Fühlen Sie sich frei, einen Code-Schnipsel zu schreiben, wenn diese nicht funktionieren.