Я хочу сгладить заданную трехмерную сетку, которая использует структуру Half-Edge для хранения информации о смежности, используя функцию Гаусса. Ниже приведен алгоритм, который был предложен:
Сгладьте сетку, перемещая каждую вершину
в положение, определяемое взвешенным
средний из его непосредственных соседей
(с весами, определенными гауссианом
с сигмой, равной средней длине
ребер, прикрепленных к вершине,
нормируется так, что сумма весов
к одному).
То есть для каждой вершины curr_vertex
, я
- рассчитать среднюю длину присоединенных ребер
- получить все соседние вершины
- определить вес каждой соседней вершины, выполнив следующее:
`
вес =
ехр (- (расстояние * расстояние) / (2 1020 * сигма * сигма)) * * 1 021
where distance is the 3D distance between the
curr_vertex and the neighbor and
1026 * сигма * curr_vertex`
- Суммируйте все веса и разделите вес каждого соседа на эту сумму (шаг нормализации)
- умножить положение каждой соседней вершины на соответствующий ей вес
- сложите все взвешенные вершины и добавьте результат в curr_vertex, чтобы получить новую вершину.
Когда я делаю это и запускаю свой алгоритм, вместо сглаживания получается масштаб - моя сетка просто увеличивается без видимого сглаживания.
Есть мысли о том, что я делаю не так?
Edit:
Вот код, который у меня есть:
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;
}