VTK平面多边形的绘制(包括环形)

2 篇文章 0 订阅

VTK绘制多边形的一般过程为:

 vtkPoints可以视为多边形的顶点,而vtkCellArray存储vtkPoints的id(索引),同时也决定着细分多边形的胞元形状。例如一个简单的多边形——三角形的构成如下:

vtkNew<vtkPoints> points;
points->SetNumberOfPoints(3);
points->SetPoint(0,0,0,0);//id + position
points->SetPoint(1,1,0,0);
points->SetPoint(2,0,1,0);
vtkNew<vtkCellArray> poly;
poly->AllocateEstimate(1,3);//胞元数量+胞元大小
poly->InsertNextCell(3);//胞元大小
poly->InsertCellPoint(0);//id
poly->InsertCellPoint(1);//id
poly->InsertCellPoint(2);//id

运行结果如图:

同理,四边形的需要四个点,如下图,按顺序将点 0123 存入vtkPoints和vtkCellArray即可。

对于圆形,可以选择两种策略,一是将圆形分割为多个点围成的圈;二是将圆分为多个三角形。

第一种只需要存储 0123 的点序列即可。第二种需要存储多三角形顶点序列:102,203,304,401。

根据细分的思想,我们可以绘制任意形状的多边形。较为复杂的环形的绘制同理,以最基础的空心矩形环为例:

需要存储点序列为:0451,1562,2673,3740。可以看成四个梯形拼接而成,也就是说梯形是矩形环的胞元。需要注意的是,如果按照0123,4567的存储方式只能得到矩形,而非中空的效果

如果将矩形特化为正方形,同时提高细分的程度,我们就能得到另一种常见的环形——圆环。圆环的胞元应该是扇面的形状,但如果细分程度够高,可以用梯形胞元替代。按照下图,将点序0132,2354,4576,6710存入,就能得到圆环。当然了,为了接近于圆形,需要更多的点。

    vtkNew<vtkPoints> points;
    points->SetNumberOfPoints(720);//内外圈顶点和
    double center[3]{0,0,0};//圆环中心
    double r[2]{20,10};//外半径,内半径
    double x{0},y{0};
    //外圈
    for(int i=0;i<360;++i){
        x = center[0]+r[0]*cos(2.0*i*vtkMath::Pi()/360);
        y = center[0]+r[0]*sin(2.0*i*vtkMath::Pi()/360);
        points->SetPoint(i,x,y,0);
    }
    //内圈
    for(int i=0;i<360;++i){
        x = center[0]+r[1]*cos(2.0*i*vtkMath::Pi()/360);
        y = center[0]+r[1]*sin(2.0*i*vtkMath::Pi()/360);
        points->SetPoint(i+360,x,y,0);
    }

    vtkNew<vtkCellArray> poly;
    poly->AllocateEstimate(360,4);
    vtkIdType id[4];
    int tid{0};
    for(int i=0;i<360;++i){
        id[0] = i;
        id[1] = 360+i;
        tid = 361+i;
        id[2] = tid<720?tid:360;
        tid = i+1;
        id[3] = tid<360?tid:0;
        poly->InsertNextCell(4,id);
    }
    vtkNew<vtkPolyData> data;
    data->SetPoints(points);
    data->SetPolys(poly);
    vtkNew<vtkPolyDataMapper>mapper;
    mapper->SetInputData(data);
    vtkNew<vtkActor>actor;
    actor->SetMapper(mapper);
    vtkNew<vtkRenderer> ren;
    ren->AddActor(actor);
    vtkNew<vtkRenderWindow> renw;
    renw->AddRenderer(ren);
    vtkNew<vtkRenderWindowInteractor> reni;
    reni->SetRenderWindow(renw);
    renw->Render();
    reni->Initialize();
    reni->Start();

上述代码运行结果如下:

我们将代码稍加修改,使得代码能输出三角环,四角环,N环,乃至圆环,也就是vtkDiskSource的基本原理了。代码如下,numCells为胞元的数量,顶点数量为胞元的两倍。通过numCells可以空控制环的类型:

    vtkNew<vtkPoints> points;
    int numCells = 3;
    if(numCells<3) return 0;
    int numPoints = numCells*2;
    points->SetNumberOfPoints(numPoints);//内外圈顶点和
    double center[3]{0,0,0};//圆环中心
    double r[2]{20,10};//外半径,内半径
    double x{0},y{0};
    //外圈
    for(int i=0;i<numCells;++i){
        double rad = 6.28318531*i/numCells;
        x = center[0]+r[0]*cos(rad);
        y = center[0]+r[0]*sin(rad);
        points->SetPoint(i,x,y,0);
    }
    //内圈
    for(int i=0;i<numCells;++i){
        double rad = 6.28318531*i/numCells;
        x = center[0]+r[1]*cos(rad);
        y = center[0]+r[1]*sin(rad);
        points->SetPoint(i+numCells,x,y,0);
    }

    vtkNew<vtkCellArray> poly;
    poly->AllocateEstimate(numCells,4);
    vtkIdType id[4];
    int tid{0};
    for(int i=0;i<numCells;++i){
        id[0] = i;
        id[1] = numCells+i;
        tid = numCells+1+i;
        id[2] = tid<numPoints?tid:numCells;
        tid = i+1;
        id[3] = tid<numCells?tid:0;
        poly->InsertNextCell(4,id);
    }
    vtkNew<vtkPolyData> data;
    data->SetPoints(points);
    data->SetPolys(poly);
    vtkNew<vtkPolyDataMapper>mapper;
    mapper->SetInputData(data);
    vtkNew<vtkActor>actor;
    actor->SetMapper(mapper);
    vtkNew<vtkRenderer> ren;
    ren->AddActor(actor);
    vtkNew<vtkRenderWindow> renw;
    renw->AddRenderer(ren);
    vtkNew<vtkRenderWindowInteractor> reni;
    reni->SetRenderWindow(renw);
    renw->Render();
    reni->Initialize();
    reni->Start();

部分示例如下: 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值