`
aswang
  • 浏览: 838614 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

vtk学习笔记 --- 投影点集合到指定的平面

阅读更多

在连接矿体的过程中,如果矿体线不是规则的多边形,即矿体线本身不在一个平面上,那么在连接两个矿体线成为矿体的时候,容易出现奇异情况,比如出现椎体等,这个时候,就需要对矿体线做预处理,这里采用投影来规整矿体线。

 

投影点集合时,首先需要确定投影到哪个平面,以及这个平面如何表示。对于第一个问题,尽量选择与矿体线接近的那个平面,这样投影之后,不至于会出现矿体线自相交的情况。第二个问题,在vtk中表示一个平面可以使用vtkPlane来表示,vtkPlane确定一个平面需要两个参数,平面的原点以及法向量。如下代码设置:

vtkPlane plane = new vtkPlane();
plane.SetOrigin(0,0,0);
plane.SetNormal(direct);

  然后,就是在vtk中如何进行投影。vtkPlane自身提供了一个函数:ProjectPoint(double p[],double proj[]),这个函数是将一个点投影到某个平面,那么针对一个点集合时,可以分别针对每个点进行投影操作即可。关键代码如下:

 public vtkPoints projectPoints(vtkPoints pt0,double direct[]){
		vtkPlane plane = new vtkPlane();
		plane.SetOrigin(0,0,0);
		plane.SetNormal(direct);
      
		vtkPoints newPts = new vtkPoints();
		double proj[] = new double[3];
		for(int i=0;i<pt0.GetNumberOfPoints();i++){
			double p[] = pt0.GetPoint(i);
			plane.ProjectPoint(p, proj);
			newPts.InsertNextPoint(proj);
		}
		return newPts;
	}

上面方法的作用就是将一个点集合投影到由点(0,0,0)和法向量direct确定的平面上。

 

在下面的示例中,演示的是将一个折线投影到经过(0,0,0)且垂直于屏幕的平面上:

 

 

/**
 * 将一系列点集合投影到一个平面上
 * 
 * @author  dev
 * @version  1.0, 2012-3-13]
 */
public class ProjectPointsToPlane extends VtkBase {
	private vtkPoints pt0;
	private vtkActor polylineactor ;
	
	public static void main(String[] args) {
		ProjectPointsToPlane pptp = new ProjectPointsToPlane();
		pptp.build();
	}
	
	public void build(){
		vtkPolyData data = readPolyData("E:\\works\\java\\VtkDemo\\src\\data\\vmine-spec.vtk");
		data.SetVerts(null);
        pt0 = OreUtil.filterRepeatPoints(data,data.GetCell(0).GetPointIds());
        
        vtkPolyData polyline = buildClosedPolyLine(pt0);
        polylineactor = makeActor(polyline);
        renderer.AddActor(polylineactor);
        
        renderWindow.LineSmoothingOn();
        postInit();
        
	}
	//将给定的点击pt0投影到平面
	public vtkPoints projectPoints(vtkPoints pt0,double direct[]){
		vtkPlane plane = new vtkPlane();
		plane.SetOrigin(0,0,0);
		plane.SetNormal(direct);
      
		vtkPoints newPts = new vtkPoints();
		double proj[] = new double[3];
		for(int i=0;i<pt0.GetNumberOfPoints();i++){
			double p[] = pt0.GetPoint(i);
			plane.ProjectPoint(p, proj);
			newPts.InsertNextPoint(proj);
		}
		return newPts;
	}
	
	@Override
	public void OnRightButtonDown() {
		//取得相机的投影方向向量
		double[] direct = renderer.GetActiveCamera().GetDirectionOfProjection();
		vtkPoints newPts = projectPoints(pt0,direct);	
		vtkPolyData projPolyline = buildClosedPolyLine(newPts);
	    vtkActor projActor = makeActor(projPolyline);
	    projActor.GetProperty().SetColor(1,0,0);
	    renderer.AddActor(projActor);
		super.OnRightButtonDown();
	}
	//构建封闭的折线
	public static vtkPolyData buildClosedPolyLine(vtkPoints pt){
        vtkPolyData oreLine = new vtkPolyData();
        oreLine.SetPoints(pt);
        
        vtkCellArray polyline = new vtkCellArray();
        polyline.InsertNextCell(pt.GetNumberOfPoints()+1);
        for(int i=0;i<pt.GetNumberOfPoints();i++){
        	polyline.InsertCellPoint(i);
        }
        polyline.InsertCellPoint(0);
        
        oreLine.SetLines(polyline);
        return oreLine;
    }
}
 

执行效果如下图:

 



 

图中红色的折线即为上面白色折线投影之后的样子。

 

  • 大小: 27.4 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics