点击打开链接http://blog.163.com/god_sun/blog/static/56399926201110108481537/
java代码:
import vtk.vtkActor; import vtk.vtkCamera; import vtk.vtkCellArray; import vtk.vtkExtractEdges; import vtk.vtkFloatArray; import vtk.vtkInteractorStyleTrackballActor; import vtk.vtkPoints; import vtk.vtkPolyData; import vtk.vtkPolyDataMapper; import vtk.vtkRenderWindow; import vtk.vtkRenderWindowInteractor; import vtk.vtkRenderer; import vtk.* ; //Then we define our class. public class Lifangti { static { if (!vtkNativeLibrary.LoadAllNativeLibraries()) { for (vtkNativeLibrary lib : vtkNativeLibrary.values()) { if (!lib.IsLoaded()) { System.out.println(lib.GetLibraryName() + " not loaded"); } } } vtkNativeLibrary.DisableOutputWindow(null); } public static void makeLifangti(){ int i ; //可以看到图中有27个小正方体组成了一个大的正方体 //x[8][3],就是每一个小正方体的 8个点的x,y,z值 //java float类型后面需加上f 表示float类型数据 //float[][] x= {{0,0,0},{0.3f,0,0},{0.3f,0.3f,0},{0,0.3f,0}, {0,0,0.3f},{0.3f,0,0.3f},{0.3f,0.3f,0.3f},{0,0.3f,0.3f}}; double[][] x={{0,0,0},{0.3,0,0},{0.3,0.3,0},{0,0.3,0}, {0,0,0.3},{0.3,0,0.3},{0.3,0.3,0.3},{0,0.3,0.3}}; //这个查阅VTK文档发现解释的跟我理解的不一样。。。很有可能是我看不懂。。。 //我的理解是 这样的, 一个正方体 是由 6个面组成,我们程序也正是打算以面位最小的CELL 来组成我们要的正方体 //当然,我们也可以用线来画,那样只能画出正方体的边框,就不能用下面用到的PolyData,而要用vtkLine这个对象作为CELL //既然选定了 由面来组成,那就产生了六个面,第一个面 是由上面定义的8个点的 0,1,2,3四个点组成,以下以此类推。 //特别注意的是,这里的0,1,2,3 这几个点,并不是对应的 x[8][3],这里的第0,1,2,3具体为什么下面会说。 //每个数代表点数据的索引下标 int[][] pts= {{0,1,2,3},{4,5,6,7},{0,1,5,4}, {1,2,6,5},{2,3,7,6},{3,0,4,7}}; //concrete dataset represents vertices, lines, polygons, and triangle strips, 这是文档里的描述,已经比较清楚了。 vtkPolyData cube =new vtkPolyData(); //这个用来保存,我们所说的 点之间的拓扑结构,因为根据VTK的流程 ,我们必须这么做,一步步打包。 vtkCellArray polys =new vtkCellArray(); //这个是关于颜色的属性值,在这里不做重点介绍。 vtkFloatArray scalars =new vtkFloatArray(); //还是同样的道理,因为我们是用自己定义的点,不是用VTK里面的 vtksphere,vtkcone等 source,所以必须把点放到vtkPoints里 vtkPoints points =new vtkPoints(); //把我们定义好的点,放到points里,这里的i 才是真正的索引,如果我们的循环从i=8开始 //真正的点的索引,以及cell中引用的,将会跟这个索引一致 for (i=0;i<8;i++) points.InsertPoint(i, x[i]); //插入点的拓扑结构, //2011年11月10日 - god_sun - 随枫¤心慧 //第一个参数 虽然是vtkIdType类型的,但事实上也是一个int型的,文档里的解释第一个参数是 点的个数,第二个是点的内容。 //设置单元由几个点组成,每个单元指定对应的点 for (i=0;i<6;i++) { polys.InsertNextCell(4); for(int j=0;j<4;j++){ polys.InsertCellPoint(pts[i][j]); } } for (i=0;i<8;i++) scalars.InsertTuple1(i,i); //接下来就开始了VTK的pipeline流程。 cube.SetPoints(points); cube.SetPolys(polys); cube.GetPointData().SetScalars(scalars); ////这段代码是为了显示立方体周围的边框。。。但是设置visibilityOn 或者visibilityOff看起来不是非常明显。 //以前photoshop的时候画一个立方体,会在周围再画上边框,这样会感觉更饱满一些。。。 //vtk5之后使用SetInputData(cube);之前格式为SetInput(cube) vtkExtractEdges extract=new vtkExtractEdges(); extract.SetInputData(cube); vtkPolyDataMapper mapEdges=new vtkPolyDataMapper(); mapEdges.SetInputConnection(extract.GetOutputPort()); mapEdges.SetScalarVisibility(0); vtkActor edgeActor=new vtkActor(); edgeActor.SetMapper(mapEdges); edgeActor.VisibilityOn(); vtkPolyDataMapper cubeMapper =new vtkPolyDataMapper(); cubeMapper.SetInputData(cube); cubeMapper.SetScalarRange(0,7); int No=0; //p,j,k是为了设置立方体的不同位置。 float p=0.0f,j=0.0f,k=0.0f; vtkRenderer renderer =new vtkRenderer(); for (p=0.0f;p<0.9;p=p+0.3f) { for (j=0.0f;j<0.9;j=j+0.3f) { for(k=0.0f;k<0.9;k=k+0.3f) { vtkActor cubeActor =new vtkActor(); //设置ACTOR的不同位置,来显示最终的图形。 cubeActor.SetPosition(p,j,k); vtkActor tempactor =new vtkActor (); cubeActor.SetMapper(cubeMapper); renderer.AddActor(cubeActor); } } } vtkCamera camera =new vtkCamera(); camera.SetPosition(1,1,1); camera.SetFocalPoint(0,0,0); vtkRenderWindow reWin = new vtkRenderWindow(); reWin.AddRenderer(renderer); vtkRenderWindowInteractor iren =new vtkRenderWindowInteractor(); iren.SetRenderWindow(reWin); //如果去掉这个style那么,交互的时候,整个立方体会一起转动 //如果加上,则是每个立方体单独转动 vtkInteractorStyleTrackballActor style =new vtkInteractorStyleTrackballActor(); iren.SetInteractorStyle(style); renderer.SetActiveCamera(camera); renderer.ResetCamera(); renderer.SetBackground(0,1,1); reWin.SetSize(300,300); reWin.Render(); iren.Initialize(); iren.Start(); } public static void main(String[] args) { // TODO Auto-generated method stub makeLifangti(); } }
c++代码如下:
#include <vtkActor.h> #include <vtkCamera.h> #include <vtkCellArray.h> #include <vtkFloatArray.h> #include <vtkPointData.h> #include <vtkPoints.h> #include <vtkPolyData.h> #include <vtkPolyDataMapper.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkRenderer.h> #include <vtkInteractorStyleTrackballActor.h> #include <vtkExtractEdges.h> typedef vtkActorCollection* vtkActorCollection_Array; int main() { int i ; //可以看到图中有27个小正方体组成了一个大的正方体 //x[8][3],就是每一个小正方体的 8个点的x,y,z值 float x[8][3]={{0,0,0},{0.3,0,0},{0.3,0.3,0},{0,0.3,0}, {0,0,0.3},{0.3,0,0.3},{0.3,0.3,0.3},{0,0.3,0.3}}; //这个查阅VTK文档发现解释的跟我理解的不一样。。。很有可能是我看不懂。。。 //我的理解是 这样的, 一个正方体 是由 6个面组成,我们程序也正是打算以面位最小的CELL 来组成我们要的正方体 //当然,我们也可以用线来画,那样只能画出正方体的边框,就不能用下面用到的PolyData,而要用vtkLine这个对象作为CELL //既然选定了 由面来组成,那就产生了六个面,第一个面 是由上面定义的8个点的 0,1,2,3四个点组成,以下以此类推。 //特别注意的是,这里的0,1,2,3 这几个点,并不是对应的 x[8][3],这里的第0,1,2,3具体为什么下面会说。 vtkIdType pts[6][4]={{0,1,2,3},{4,5,6,7},{0,1,5,4}, {1,2,6,5},{2,3,7,6},{3,0,4,7}}; //concrete dataset represents vertices, lines, polygons, and triangle strips, 这是文档里的描述,已经比较清楚了。 vtkPolyData *cube = vtkPolyData::New(); //这个用来保存,我们所说的 点之间的拓扑结构,因为根据VTK的流程 ,我们必须这么做,一步步打包。 vtkCellArray *polys = vtkCellArray::New(); //这个是关于颜色的属性值,在这里不做重点介绍。 vtkFloatArray *scalars = vtkFloatArray::New(); //还是同样的道理,因为我们是用自己定义的点,不是用VTK里面的 vtksphere,vtkcone等 source,所以必须把点放到vtkPoints里 vtkPoints *points = vtkPoints::New(); //把我们定义好的点,放到points里,这里的i 才是真正的索引,如果我们的循环从i=8开始 //真正的点的索引,以及cell中引用的,将会跟这个索引一致 for (i=0;i<8;i++)points->InsertPoint(i,x[i]); //插入点的拓扑结构, 2011年11月10日 - god_sun - 随枫¤心慧 //第一个参数 虽然是vtkIdType类型的,但事实上也是一个int型的,文档里的解释第一个参数是 点的个数,第二个是点的内容。 for (i=0;i<6;i++) polys->InsertNextCell(4,pts[i]); for (i=0;i<8;i++) scalars->InsertTuple1(i,i); //接下来就开始了VTK的pipeline流程。 cube->SetPoints(points); cube->SetPolys(polys); cube->GetPointData()->SetScalars(scalars); ////这段代码是为了显示立方体周围的边框。。。但是设置visibilityOn 或者visibilityOff看起来不是非常明显。 //以前photoshop的时候画一个立方体,会在周围再画上边框,这样会感觉更饱满一些。。。 vtkExtractEdges *extract=vtkExtractEdges::New(); extract->SetInput(cube); vtkPolyDataMapper *mapEdges=vtkPolyDataMapper::New(); mapEdges->SetInputConnection(extract->GetOutputPort()); mapEdges->SetScalarVisibility(0); vtkActor *edgeActor=vtkActor::New(); edgeActor->SetMapper(mapEdges); edgeActor->VisibilityOn(); vtkPolyDataMapper *cubeMapper = vtkPolyDataMapper::New(); cubeMapper->SetInput(cube); cubeMapper->SetScalarRange(0,7); int No=0; //p,j,k是为了设置立方体的不同位置。 float p=0.0,j=0.0,k=0.0; vtkRenderer *renderer = vtkRenderer::New(); for (p=0.0;p<0.9;p=p+0.3) { for (j=0.0;j<0.9;j=j+0.3) { for(k=0.0;k<0.9;k=k+0.3) { vtkActor *cubeActor = vtkActor::New(); //设置ACTOR的不同位置,来显示最终的图形。 cubeActor->SetPosition(p,j,k); vtkActor *tempactor = vtkActor ::New(); cubeActor->SetMapper(cubeMapper); renderer->AddActor(cubeActor); } } } vtkCamera *camera =vtkCamera::New(); camera->SetPosition(1,1,1); camera->SetFocalPoint(0,0,0); vtkRenderWindow *reWin = vtkRenderWindow::New(); reWin->AddRenderer(renderer); vtkRenderWindowInteractor *iren = vtkRenderWindowInteractor::New(); iren->SetRenderWindow(reWin); //如果去掉这个style那么,交互的时候,整个立方体会一起转动 //如果加上,则是每个立方体单独转动 vtkInteractorStyleTrackballActor *style = vtkInteractorStyleTrackballActor::New(); iren->SetInteractorStyle(style); renderer->SetActiveCamera(camera); renderer->ResetCamera(); renderer->SetBackground(0,1,1); reWin->SetSize(300,300); reWin->Render(); iren->Initialize(); iren->Start(); points->Delete(); cube->Delete(); cubeMapper->Delete(); renderer->Delete(); reWin->Delete(); iren->Delete(); polys->Delete(); scalars->Delete(); return 0; } 如何使用 自己定义好的点,来画图 自己定义的点插入到 vtkpoints中 定义好的拓扑结构插入到 vtkcellarray中 无非就是这种方式。
绘制上图的思路:
8个点定义一个立方体的8个顶点;
每4个点组成一个面,总共6个面;
8个点插入到VTKpoints中;
6个面插入到拓扑结构中VTKcellarray中;
组装好一个立方体,然后平移这个立方体9次,即可形成最终的一个大立方体;
每个小立方体可单独旋转;