Opengl 高斯网格平滑

Opengl 高斯网格平滑,opengl,mesh,gaussian,smoothing,Opengl,Mesh,Gaussian,Smoothing,我希望使用高斯函数平滑给定的3D网格,该网格使用半边结构存储邻接信息。以下是提出的算法: 通过移动每个顶点平滑网格 到由加权平均值确定的位置 其近邻的平均数 (权重由高斯函数确定) σ等于平均长度 附加到顶点的边的数目, 使权重和 对一) 因此,对于每个顶点,I 计算其附着边的平均长度 获取所有相邻顶点 通过执行以下操作确定每个相邻顶点的权重: ` 重量= exp(-(距离*距离)/(2.sigmasigma)) 其中,距离是当前顶点与相邻顶点之间的3D距离,并且sigma=当前顶点附着边的平均

我希望使用高斯函数平滑给定的3D网格,该网格使用半边结构存储邻接信息。以下是提出的算法:

通过移动每个顶点平滑网格 到由加权平均值确定的位置 其近邻的平均数 (权重由高斯函数确定) σ等于平均长度 附加到顶点的边的数目, 使权重和 对一)

因此,对于每个顶点,I

  • 计算其附着边的平均长度
  • 获取所有相邻顶点
  • 通过执行以下操作确定每个相邻顶点的权重: `
  • 重量= exp(-(距离*距离)/(2.sigmasigma))

    其中,距离是当前顶点
    与相邻顶点之间的3D距离,并且
    sigma
    =当前顶点附着边的平均长度`

  • 将所有权重相加,并将每个邻居的权重除以该和(标准化步骤)
  • 将每个相邻顶点的位置乘以其相应的权重
  • 将所有加权顶点相加,并将结果添加到curr_顶点以生成新顶点
  • 当我这样做并运行我的算法时,实际发生的不是平滑而是缩放-我的网格只是放大了,没有任何明显的平滑

    有没有想过我做错了什么

    编辑: 以下是我的代码:

    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;
    }
    
    void R3Mesh::
    平滑(空)
    {
    R3Mesh*新网格=新R3Mesh(*此);
    对于(int i=0;ihalf_edge;
    做
    {
    insert(make_pair(tmp->contract->vertex,0));
    tmp=tmp->对向->下一步;
    }而(tmp!=v->半边);
    //确定用于高斯分布的西格玛
    双西格玛=v->平均边缘长度();
    双倍重量=0,总重量=0;
    双倍距离;
    //确定并存储每个相邻顶点的权重
    for(neights_iter=neights.begin();neights_iter!=neights.end();
    邻居(iter++)
    {
    距离=R3距离(v->位置,相邻位置->第一->位置);
    重量=(1./(西格玛*sqrt(2.*3.14))*exp(-(距离*距离)/(2.*西格玛*西格玛));
    总重量+=重量;
    邻居→第二个=重量;
    }
    //确定当前顶点的新位置
    R3点新位置=v->位置;
    for(neights_iter=neights.begin();neights_iter!=neights.end();
    邻居(iter++)
    {
    新位置+=(相邻位置->第二个/总重量)*(相邻位置->第一个->位置);
    }
    新位置翻译(新位置-v->位置);
    新建网格->顶点(i)->位置.重置(新建位置X(),新建位置Y(),新建位置Z());
    邻居。清除();
    }
    *this=*新网格;
    }
    
    这有点像一个打字错误。你所描述的算法在我看来很好

    首先,明确验证权重的标准化

    接下来检查代码,将计算出的顶点位置写回新的平滑网格


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

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

    首先,明确验证权重的标准化

    接下来检查代码,将计算出的顶点位置写回新的平滑网格


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

    请查看我的功能尝试将新位置初始化到原点,而不是v->position。按照现在的情况进行总结,然后删除行:new_pos.Translate(new_pos-v->position);那应该行。请看一下我的功能尝试将新位置初始化到原点,而不是v->position。按照现在的情况进行总结,然后删除行:new_pos.Translate(new_pos-v->position);这应该行得通。