• 3D可视化字母出现频率_vtkLinearExtrusionFilter



    开发环境

    1. Windows 11 家庭中文版
    2. Microsoft Visual Studio Community 2019
    3. VTK-9.3.0.rc0
    4. vtk-example
    5. 参考代码
    6. 目的:学习与总结

    demo解决问题:统计输入文本中字母出现的频率,不区分大小写,使用3D可是化方式进行显示,频率高的字母z方向同比例进行拉伸;运行需要跟一个参数:文本文件路径

    关键类:vtkLinearExtrusionFilter、vtkVectorText

    知识点

    1. 线形拉伸参数设置:
        extrude[i]->SetInputConnection(letters[i]->GetOutputPort());
        //#define VTK_VECTOR_EXTRUSION 1    //向量拉伸,与setVector有关
        //#define VTK_NORMAL_EXTRUSION 2    //法向拉伸,这里与VTK_VECTOR_EXTRUSION一致,都是z方向
        //#define VTK_POINT_EXTRUSION 3     //点平面拉伸,可以理解为2d平面效果
        extrude[i]->SetExtrusionType(VTK_NORMAL_EXTRUSION); 
        extrude[i]->SetVector(0, 0, 1.0);                                       //打开z方向向量拉伸/挤压
        extrude[i]->SetScaleFactor((double)freq[i] / maxFreq * 2.50);           //计算出现频率作为缩放系数
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    VTK_POINT_EXTRUSION 设置效果:
    2. vtkVectorText: vtk3D文本
    3. 相机参数设置:

      //重点掌握:灵活配置参数
      //https://blog.csdn.net/liushao1031177/article/details/116903698
      ren->ResetCamera();
      ren->SetBackground(colors->GetColor3d("Silver").GetData());
      ren->GetActiveCamera()->Elevation(30.0);  //使用焦点作为旋转中心,围绕投影方向的负片和向上视图矢量的叉积旋转相机。 结果是场景的垂直旋转。
      ren->GetActiveCamera()->Azimuth(-30.0);   //围绕以焦点为中心的向上视图矢量旋转相机。请注意,向上查看矢量是通过 SetViewUp 设置的任何矢量,不一定垂直于投影方向。 结果是相机的水平旋转。
      ren->GetActiveCamera()->Dolly(1.25);      //将相机与焦点的距离除以给定的Dolly值。 使用大于 1 的值向焦点推入,使用小于 1 的值推移远离焦点
      ren->ResetCameraClippingRange();          //根据可见actor的边界重置摄像机剪裁范围。这样可以确保没有props被切断
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    prj name: AlphaFrequency

    //
    // Create bar charts of frequency of letters.//创建字母频率的条形图。
    //
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    #include 
    
    int main(int argc, char* argv[])
    {
      vtkNew<vtkNamedColors> colors;
    
      std::vector<vtkSmartPointer<vtkVectorText>> letters;              //渲染三维文本
      std::vector<vtkSmartPointer<vtkLinearExtrusionFilter>> extrude;   //数据对象进行线性过滤
      std::vector<vtkSmartPointer<vtkPolyDataMapper>> mappers;
      std::vector<vtkSmartPointer<vtkPolyDataMapper>> mappers;
      std::vector<vtkSmartPointer<vtkActor>> actors;
    
      char filename[512];
      char text[2];
      static char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      int i, j, freq[26], maxFreq;
      float x, y;
      FILE* fPtr;
      int c;
    
      //
      // count the letters
      //
      if ((argc == 1) || ((argc == 2) && !(strcmp("-S", argv[1]))))
      {
        cerr << "Please provide filename: " << argv[0] << " filename\n";
        strcpy(filename, "./Makefile");
        cerr << "Using the file " << filename << " as input\n";
      }
      else
      {
        strcpy(filename, argv[1]);
      }
    
      //读取MakeFile文件
      if ((fPtr = fopen(filename, "r")) == NULL)
      {
        cerr << "Cannot open file: " << filename << "\n";
        exit(1);
      }
    
      //统计MakeFile文件中字母出现的频率
      for (i = 0; i < 26; i++) freq[i] = 0;
      while ((c = fgetc(fPtr)) != EOF)
      {
        if (isalpha(c))
        {
          c = tolower(c);
          freq[c - 97]++;//索引为c - 97的字母频率加1
        }
      }
    
      //找到出现频率最大的 maxFreq
      for (maxFreq = 0, i = 0; i < 26; i++)
        if (freq[i] > maxFreq)
          maxFreq = freq[i];
    
      //
      // graphics stuff
      //
      vtkNew<vtkRenderer> ren;
      vtkNew<vtkRenderWindow> renWin;
      renWin->AddRenderer(ren);
      vtkNew<vtkRenderWindowInteractor> iren;
      iren->SetRenderWindow(renWin);
      //
      // Setup letters
      //
      text[1] = '\0';
      for (i = 0; i < 26; i++)
      {
        // data
        text[0] = alphabet[i];
        letters.push_back(vtkSmartPointer<vtkVectorText>::New());
        letters[i]->SetText(text);
    
        // filter
        extrude.push_back(vtkSmartPointer<vtkLinearExtrusionFilter>::New());    //线形拉伸过滤器
        extrude[i]->SetInputConnection(letters[i]->GetOutputPort());
        //#define VTK_VECTOR_EXTRUSION 1    //向量拉伸,与setVector有关
        //#define VTK_NORMAL_EXTRUSION 2    //法向拉伸,这里与VTK_VECTOR_EXTRUSION一致,都是z方向
        //#define VTK_POINT_EXTRUSION 3     //点平面拉伸,可以理解为2d平面效果
        extrude[i]->SetExtrusionType(VTK_VECTOR_EXTRUSION);
        extrude[i]->SetVector(0, 0, 1.0);                                       //打开z方向向量拉伸/挤压
        extrude[i]->SetScaleFactor((double)freq[i] / maxFreq * 2.50);           //计算出现频率作为缩放系数
    
        // mapper
        mappers.push_back(vtkSmartPointer<vtkPolyDataMapper>::New());
        mappers[i]->SetInputConnection(extrude[i]->GetOutputPort());
        mappers[i]->ScalarVisibilityOff();
    
        // actor
        actors.push_back(vtkSmartPointer<vtkActor>::New());
        actors[i]->SetMapper(mappers[i]);
        actors[i]->GetProperty()->SetColor(colors->GetColor3d("Peacock").GetData());
        if (freq[i] <= 0)//没有出现过的字母就不显示
        {
          actors[i]->VisibilityOff();
        }
        ren->AddActor(actors[i]);
      }
      //
      // Position actors
      //
      for (y = 0.0, j = 0; j < 2; j++, y += (-3.0))     //2行
      {
        for (x = 0.0, i = 0; i < 13; i++, x += 1.5)     //13列
        {
          actors[j * 13 + i]->SetPosition(x, y, 0.0);   //x表示横向,间距1.5;y表示纵向,间距3
        }
      }
    
      //重点掌握:灵活配置参数
      //https://blog.csdn.net/liushao1031177/article/details/116903698
      ren->ResetCamera();
      ren->SetBackground(colors->GetColor3d("Silver").GetData());
      ren->GetActiveCamera()->Elevation(30.0);  //使用焦点作为旋转中心,围绕投影方向的负片和向上视图矢量的叉积旋转相机。 结果是场景的垂直旋转。
      ren->GetActiveCamera()->Azimuth(-30.0);   //围绕以焦点为中心的向上视图矢量旋转相机。请注意,向上查看矢量是通过 SetViewUp 设置的任何矢量,不一定垂直于投影方向。 结果是相机的水平旋转。
      ren->GetActiveCamera()->Dolly(1.25);      //将相机与焦点的距离除以给定的Dolly值。 使用大于 1 的值向焦点推入,使用小于 1 的值推移远离焦点
      ren->ResetCameraClippingRange();          //根据可见actor的边界重置摄像机剪裁范围。这样可以确保没有props被切断
    
      renWin->SetSize(640, 480);
      renWin->SetWindowName("AlphaFrequency");
    
      // interact with data
      renWin->Render();
      iren->Start();
    
      return EXIT_SUCCESS;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
  • 相关阅读:
    7.2.4 【MySQL】匹配范围值
    Ubuntu Server版 之 共享文件 samba和NFS 两种方法
    第十五届全国交通运输领域青年学术会议,和鲸 Heywhale 携手龙船科技联合发布科研服务解决方案
    JVM相关知识点
    面试官:如何实现微服务全链路灰度发布?
    TypeScript中的泛型使用详解
    工程物料管理信息化建设(十二)——关于工程物料管理系统最后的思考
    出血性脑卒中临床智能诊疗建模
    降钙素(Cys(Acm)²·⁷)-α-CGRP (human)、125448-83-1
    前端面试中Vue的有经典面试题三
  • 原文地址:https://blog.csdn.net/chengfenglee/article/details/134281621