2010-02-24 114 views
0

我希望使用高斯函數來平滑給定的3D網格,該網格使用半邊結構來存儲鄰接信息。以下是提議的算法:高斯網格平滑

由每個頂點 移動到由加權 平均近鄰 而確定的位置(通過高斯 與西格瑪等於所確定的權重平滑網狀平均長度 附加到頂點, 規範化,使權重總和 爲1)。

所以對於各頂點curr_vertex,我

  1. 計算其附連的邊緣的平均長度
  2. 獲得所有相鄰頂點的
  3. 通過執行以下操作確定的每個相鄰頂點的重量: `

weight = exp( - (distance * distance)/(2。 西格瑪西格瑪))

where distance is the 3D distance between the curr_vertex and the neighbor and西格瑪= average length of attached edges of curr_vertex`

  • 總結所有的權重,並通過將該和除以每個鄰居的權重(歸一化步驟)
  • 將每個相鄰頂點的位置乘以其相應的權重
  • 將所有加權頂點相加並將結果添加到curr_vertex以產生新頂點。
  • 當我這樣做,並運行我的算法,而不是平滑實際發生的是一個規模 - 我的網格只是變大而沒有任何明顯的平滑。

    有關我在做什麼錯的任何想法?

    編輯: 下面是我的代碼:

    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; 
    } 
    

    回答

    1

    這意味頭打耳光錯字風格的bug。你所描述的算法對我來說看起來很好。

    首先明確驗證權重的規範化。

    接下來檢查您的代碼,將計算的頂點pos寫回到新平滑網格中。

    這些是我的猜測。如果這些不起作用,請隨意發佈代碼段。

    +0

    請看看我的功能 – Myx 2010-02-26 01:07:39

    +0

    試着初始化new_pos到原點,而不是v-> position。總結完全一樣,你現在,然後刪除行: new_pos。翻譯(new_pos - v-> position); 這應該工作。 – 2010-02-26 18:15:26