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

  1. Berechnung der durchschnittlichen Länge der befestigten Kanten
  2. erhalten alle der benachbarten Ecken
  3. bestimmt das Gewicht jeden benachbarten Scheitelpunktes durch folgende Maßnahmen: `
  

Gewicht =   exp (- (Entfernung * Abstand) / (2. sigma Sigma))

where distance is the 3D distance between thecurr_vertexand the neighbor andsigma= average length of attached edges ofcurr_vertex`

  1. Summe all Gewichte und teilt jedes Gewicht des Nachbarn durch diese Summe (Normalisierungsschritt)
  2. multiplizieren die Position jedes benachbarten Scheitel durch sein entsprechendes Gewicht
  3. 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;
}
War es hilfreich?

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top