离散曲率计算

参考文献:三维模型空洞修补算法的研究  

   

拉普拉斯算子的应用非常广泛,它是椭圆型算子中的一个重要例子。在物理

中,常用于热传导方程、波方程的数学模型以及亥姆霍兹方程。在静电学中,拉普拉斯方程和泊松方程的应用随处可见。Laplace-Beltrami 算子的定义:是梯度的散度   

Laplace-Beltrami 将 Laplace 算子的定义推广到曲面上,对于定义在流形曲面 S上的函数 f ,Laplace-Beltrami 的定义为

                                                               

接下来我们讨论 Laplace − Beltrami 算子的离散化形式

                                               

                              

离散曲率计算_第1张图片

离散曲率计算_第2张图片

过程归纳:求解离散点的权重、边的权重、求解邻域面积、最后求得拉普拉斯算子的模

 1.计算边、点的权重:

                 

void Curvature::calc_weights(){
	 Mesh::VertexIter   v_it,v_end(m_mesh.vertices().end());
	 Mesh::EdgeIter e_it,e_end(m_mesh.edges().end());
	 Mesh::VertexFaceIter  vf_it;
	 Mesh::FaceVertexIter  fv_it;   
	 Mesh::HalfedgeHandle h0,h1,h2;
	 Mesh::VertexHandle v0,v1;
	 Mesh::Point   p0,p1,p2,d0,d1;
	 Mesh::Scalar w,area,b(0.99);
	 for(e_it=m_mesh.edges().begin();e_it!=e_end;++e_it){
		 w=0.0;
		 h0=m_mesh.halfedge_handle(e_it.handle(),0);
		 v0=m_mesh.to_vertex_handle(h0);  //转换为半边结构中的目标点;
		 p0=m_mesh.point(v0);
		 h1=m_mesh.halfedge_handle(e_it.handle(),1);
		 v1=m_mesh.to_vertex_handle(h1);
		 p1=m_mesh.point(v1);
		 if(!m_mesh.is_boundary(h0)){
			 h2=m_mesh.next_halfedge_handle(h0);
			 p2=m_mesh.point(m_mesh.to_vertex_handle(h2));
			 d0=(p0-p2).normalize();
			 d1=(p1-p2).normalize();
			 w+=1.0/tan(acos(std::max(-b,std::min(b,d0|d1))));
		 }
		 if(!m_mesh.is_boundary(h1)){
			 h2=m_mesh.next_halfedge_handle(h1);
			 p2=m_mesh.point(m_mesh.to_vertex_handle(h2));
			 d0=(p0-p2).normalize();
			 d1=(p1-p2).normalize();
			 w+=1.0/tan(acos(std::max(-b,std::min(b,d0|d1))));
		 }
		 w=std::max(w,0.0f);
         //边的权重;
		 weight(e_it)=w;
	 }
	 for(v_it=m_mesh.vertices().begin();v_it!=v_end;++v_it)
	 {
		 area=0.0f;  //面积;
		 for(vf_it=m_mesh.vf_iter(v_it);vf_it;++vf_it)
		 {
			  fv_it=m_mesh.fv_iter(vf_it);  //面对应的点;
			  const Mesh::Point&P=m_mesh.point(fv_it); 
			  fv_it++;//面中的点;
			  const Mesh::Point&Q=m_mesh.point(fv_it);
			  fv_it++;
			  const Mesh::Point&R=m_mesh.point(fv_it);
			  area+=((Q-P)%(R-P)).norm()*0.5f*0.3333f;
		 }  
		 //点的权重;
		 weight(v_it)=(fabs(area)>FLT_MIN?1.0/(2.0*area):0.0);
	 }
  }

2.拉普拉斯算子的模的计算

void Curvature::calc_curvalture(){
	Mesh::VertexIter v_it,v_end(m_mesh.vertices().end());
	Mesh::HalfedgeHandle h;
	Mesh::EdgeHandle e;
	Mesh::VertexVertexIter vv_it;
	Mesh::Point    laplace(0.0,0.0,0.0);
	for(v_it=m_mesh.vertices().begin();v_it!=v_end;++v_it){
		curvature(v_it)=0.0;
		laplace=Mesh::Point(0,0,0);
		if(!m_mesh.is_boundary(v_it.handle())){
			//遍历所有的点;
			for(vv_it=m_mesh.vv_iter(v_it);vv_it;++vv_it){
				h=vv_it.current_halfedge_handle();
				e=m_mesh.edge_handle(h);    //半边对应的边;
				laplace+=weight(e)*(m_mesh.point(vv_it)-m_mesh.point(v_it));
			}
			laplace*=weight(v_it);
			curvature(v_it)=laplace.norm();
			//比较相互邻接的顶点的曲率;
		}
	}
}


                

你可能感兴趣的:(OpenMesh学习)