我希望使用高斯函數來平滑給定的3D網格,該網格使用半邊結構來存儲鄰接信息。以下是提議的算法:高斯網格平滑
由每個頂點 移動到由加權 平均近鄰 而確定的位置(通過高斯 與西格瑪等於所確定的權重平滑網狀平均長度 附加到頂點, 規範化,使權重總和 爲1)。
所以對於各頂點curr_vertex
,我
- 計算其附連的邊緣的平均長度
- 獲得所有相鄰頂點的
- 通過執行以下操作確定的每個相鄰頂點的重量: `
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;
}
請看看我的功能 – Myx 2010-02-26 01:07:39
試着初始化new_pos到原點,而不是v-> position。總結完全一樣,你現在,然後刪除行: new_pos。翻譯(new_pos - v-> position); 這應該工作。 – 2010-02-26 18:15:26