首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >高斯网格平滑

高斯网格平滑
EN

Stack Overflow用户
提问于 2010-02-24 02:11:00
回答 1查看 2.7K关注 0票数 1

我希望平滑给定的三维网格,它使用半边结构存储邻接信息,使用高斯函数。提出的算法如下:

通过将每个顶点移动到由其近邻的加权平均值确定的位置来平滑网格(由高斯确定的权重与附加到顶点的边的平均长度相等,归一化使权重之和变为1)。

所以对于每个顶点curr_vertex,i

vertices

  • determine

  • 计算其附加边的平均长度

  • ,通过执行以下操作获得所有相邻顶点的权重:

权重=exp(-(距离)/(2._sigma_sigma))

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

step)

  • multiply (
  1. )将每个邻域的权重除以这个和(归一化表示每个相邻顶点的位置与其相应的权重
  2. 相加,并将结果加到curr_vertex中以生成新的顶点。

)

当我这样做,运行我的算法,而不是平滑实际发生的是一个尺度-我的网格只是扩大,没有任何明显的平滑。

对我做错了什么有什么想法吗?

编辑:下面是我的代码:

代码语言:javascript
复制
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;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2010-02-24 16:37:26

这有点像一个打头的打字错误。你所描述的算法在我看来很好。

首先要清楚地验证权重的归一化。

接下来,检查您的代码,其中您将计算出的顶点pos写回新的光滑网格中。

这是我的猜测。如果这些代码不起作用,可以随意发布代码片段。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2323209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档