Сглаживание сетки по Гауссу - PullRequest
0 голосов
/ 24 февраля 2010

Я хочу сгладить заданную трехмерную сетку, которая использует структуру Half-Edge для хранения информации о смежности, используя функцию Гаусса. Ниже приведен алгоритм, который был предложен:

Сгладьте сетку, перемещая каждую вершину в положение, определяемое взвешенным средний из его непосредственных соседей (с весами, определенными гауссианом с сигмой, равной средней длине ребер, прикрепленных к вершине, нормируется так, что сумма весов к одному).

То есть для каждой вершины curr_vertex, я

  1. рассчитать среднюю длину присоединенных ребер
  2. получить все соседние вершины
  3. определить вес каждой соседней вершины, выполнив следующее: `

вес = ехр (- (расстояние * расстояние) / (2 1020 * сигма * сигма)) * * 1 021

where distance is the 3D distance between the curr_vertex and the neighbor and 1026 * сигма * curr_vertex`

  1. Суммируйте все веса и разделите вес каждого соседа на эту сумму (шаг нормализации)
  2. умножить положение каждой соседней вершины на соответствующий ей вес
  3. сложите все взвешенные вершины и добавьте результат в 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;
}

1 Ответ

1 голос
/ 24 февраля 2010

Это попахивает ошибкой в ​​стиле опечатки. Алгоритм, как вы описали, выглядит хорошо для меня.

Сначала четко проверьте нормализацию весов.

Затем проверьте ваш код, в который вы записываете вычисленную вершину pos в новую сглаженную сетку.

Это мои догадки. Не стесняйтесь опубликовать фрагмент кода, если он не работает.

...