VTK绘制球体并用定时器实现球体转动

本例子展示VTK实现转动的球体,一个定时器用来使球体绕Z轴转动。效果如下:

代码如下:

#include <vtkActor.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>

namespace {

class vtkTimerCallback2 : public vtkCommand
{
public:
  vtkTimerCallback2() = default;
  ~vtkTimerCallback2() = default;

  int timerId = 0;
  static vtkTimerCallback2* New()
  {
    vtkTimerCallback2* cb = new vtkTimerCallback2;
    cb->TimerCount = 0;
    return cb;
  }
  virtual void Execute(vtkObject* caller, unsigned long eventId,
                       void* vtkNotUsed(callData))
  {
    vtkRenderWindowInteractor* iren =
        dynamic_cast<vtkRenderWindowInteractor*>(caller);
    if (vtkCommand::TimerEvent == eventId)
    {
      ++this->TimerCount;
    }
    if (TimerCount < 36)
    {
      actor->RotateZ(5);
      iren->GetRenderWindow()->Render();
    }
    else
    {
      iren->DestroyTimer();
    }
  }

private:
  int TimerCount = 0;

public:
  vtkActor* actor = nullptr;
};
} // namespace

int main(int, char*[])
{
  vtkNew<vtkNamedColors> colors;

  // Create a sphere
  vtkNew<vtkSphereSource> sphereSource;
  sphereSource->SetCenter(0.0, 0.0, 0.0);
  sphereSource->SetRadius(1.0);
  sphereSource->SetThetaResolution(15);
  sphereSource->SetPhiResolution(15);
  sphereSource->Update();

  // Create a mapper and actor
  vtkNew<vtkPolyDataMapper> mapper;
  mapper->SetInputConnection(sphereSource->GetOutputPort());
  vtkNew<vtkActor> actor;
  actor->SetMapper(mapper);
  actor->RotateX(90);
  actor->GetProperty()->SetRepresentationToWireframe(); // 线框模式

  // Create a renderer, render window, and interactor
  vtkNew<vtkRenderer> renderer;
  vtkNew<vtkRenderWindow> renderWindow;
  renderWindow->AddRenderer(renderer);
  renderWindow->SetSize(640, 480);

  vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;
  renderWindowInteractor->SetRenderWindow(renderWindow);

  // Add the actor to the scene
  renderer->AddActor(actor);

  renderer->SetBackground(colors->GetColor3d("Seashell").GetData());
  // Render and interact
  renderWindow->SetWindowName("RotatingSphere");
  renderWindow->Render();

  // Initialize must be called prior to creating timer events.
  renderWindowInteractor->Initialize();

  // Sign up to receive TimerEvent
  vtkNew<vtkTimerCallback2> cb;
  cb->actor = actor;

  renderWindowInteractor->AddObserver(vtkCommand::TimerEvent, cb);
  int timerId = renderWindowInteractor->CreateRepeatingTimer(100);// 创建定时器
  cb->timerId = timerId;

  // Start the interaction and timer
  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}

通过本例需要掌握的知识点:

1. VTK开发应用程序的基本流程,即:

source -> mapper -> actor -> renderer ->renderwindowvtk->RenderWindowInteractor

2. 观察者模式的使用及vtkCommand类用法。

3.定时器的用法。

4.点、线框、面模式的使用。点模式如下:

actor->GetProperty()->SetRepresentationToPoints();

线框模式代码如下:

actor->GetProperty()->SetRepresentationToWireframe();

面模式如下:

actor->GetProperty()->SetRepresentationToSurface();

<think>根据用户需求,他想要在C++中使用VTK绘制球体并设置球体参数。参考之前的引用内容(虽然引用的是Python代码,但原理相同),我们可以使用`vtkSphereSource`类来创建球体,并设置其参数。 ### 步骤说明 1. **创建球体源**:使用`vtkSphereSource`创建球体,设置中心点坐标、半径等参数。 2. **设置球体参数**:包括设置球体的经度和纬度方向的分辨率(控制球体的精细程度)。 3. **创建映射器**:将球体数据映射为图形数据。 4. **创建演员**:将映射器添加到演员,以便在场景中显示。 5. **创建渲染器、渲染窗口和交互器**:完成可视化流程。 ### C++代码示例 以下是完整的C++代码示例: ```cpp #include <vtkSmartPointer.h> #include <vtkSphereSource.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> int main() { // 1. 创建球体源并设置参数 vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New(); sphereSource->SetCenter(0.0, 0.0, 0.0); // 设置球心坐标 sphereSource->SetRadius(5.0); // 设置球体半径 sphereSource->SetThetaResolution(30); // 设置经度方向的分辨率(控制经线数量) sphereSource->SetPhiResolution(30); // 设置纬度方向的分辨率(控制纬线数量) sphereSource->Update(); // 更新数据 // 2. 创建映射器 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputConnection(sphereSource->GetOutputPort()); // 3. 创建演员 vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); // 4. 创建渲染器并添加演员 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); renderer->SetBackground(0.1, 0.2, 0.4); // 设置背景颜色 // 5. 创建渲染窗口 vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetSize(800, 600); // 设置窗口大小 // 6. 创建交互器 vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); renderWindowInteractor->SetRenderWindow(renderWindow); // 启动渲染 renderWindow->Render(); renderWindowInteractor->Start(); return 0; } ``` ### 关键参数说明 1. **`SetCenter(double x, double y, double z)`**:设置球体中心坐标,默认值为(0,0,0)[^1]。 2. **`SetRadius(double r)`**:设置球体半径,默认值为0.5[^2]。 3. **`SetThetaResolution(int res)`**:设置经度方向的分辨率(即经线数量),默认值为8。值越大球体越光滑,但计算量也越大。 4. **`SetPhiResolution(int res)`**:设置纬度方向的分辨率(即纬线数量),默认值为8。同样,值越大球体越光滑。 ### 数学原理 球体表面的参数方程可表示为: $$ \begin{cases} x = x_0 + r \sin \phi \cos \theta \\ y = y_0 + r \sin \phi \sin \theta \\ z = z_0 + r \cos \phi \end{cases} $$ 其中: - $(x_0, y_0, z_0)$ 为球心坐标 - $r$ 为半径 - $\theta \in [0, 2\pi]$ 为经度角(由`SetThetaResolution`控制离散点数) - $\phi \in [0, \pi]$ 为纬度角(由`SetPhiResolution`控制离散点数) 通过增加$\theta$和$\phi$的分辨率,可以提高球体表面的三角面片数量,从而获得更光滑的效果[^1][^2]。 ### 性能优化建议 对于需要高性能的场景,可适当降低分辨率的设置值(如设为8-16),以平衡渲染效果与效率。而对于高质量渲染,则可设置为30以上。 §§相关问题§§ 1. 如何修改代码以绘制半透明球体? 2. 如何在球体表面添加纹理贴图? 3. 如何同时显示多个球体并设置不同颜色? 4. VTK中还有哪些其他方法可以绘制球体? </think>在 C++ 中使用 VTK 绘制球体并设置参数主要通过 `vtkSphereSource` 类实现,下面是详细步骤和代码实现: ### 1. 创建球体对象并设置参数 ```cpp #include <vtkSmartPointer.h> #include <vtkSphereSource.h> #include <vtkPolyDataMapper.h> #include <vtkActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> int main() { // 创建球体源对象 vtkSmartPointer<vtkSphereSource> sphereSource = vtkSmartPointer<vtkSphereSource>::New(); // 设置球体参数 sphereSource->SetCenter(1.0, 2.0, 3.0); // 球心坐标 (x, y, z) sphereSource->SetRadius(4.0); // 球体半径 sphereSource->SetThetaResolution(50); // 经度方向分辨率 sphereSource->SetPhiResolution(50); // 纬度方向分辨率 sphereSource->SetStartTheta(0); // 起始经度角(度) sphereSource->SetEndTheta(270); // 终止经度角(度) sphereSource->SetStartPhi(0); // 起始纬度角(度) sphereSource->SetEndPhi(180); // 终止纬度角(度) sphereSource->Update(); // 更新数据 } ``` ### 2. 关键参数说明 1. **球心位置**:`SetCenter(x, y, z)` 设置球体中心点坐标,默认原点 (0,0,0)[^2] 2. **半径设置**:`SetRadius(r)` 控制球体大小,默认值为 0.5[^2] 3. **分辨率控制**: - `SetThetaResolution(n)`:经度方向分段数(默认 8),值越大球体越光滑 - `SetPhiResolution(n)`:纬度方向分段数(默认 8) $$ \text{总面片数} = \theta_{\text{res}} \times \phi_{\text{res}} $$ 4. **球体切片**: - `SetStartTheta()`/`SetEndTheta()`:经度范围 [0, 360°] - `SetStartPhi()`/`SetEndPhi()`:纬度范围 [0, 180°] - 例如设置 `EndTheta=270` 得到 3/4 球体 ### 3. 完整可视化流程 ```cpp // ...(接上面的球体创建代码) // 创建映射器 vtkSmartPointer<vtkPolyDataMapper> mapper = vtkSmartPointer<vtkPolyDataMapper>::New(); mapper->SetInputConnection(sphereSource->GetOutputPort()); // 创建演员 vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New(); actor->SetMapper(mapper); // 创建渲染器和窗口 vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(actor); renderer->SetBackground(0.1, 0.2, 0.4); // 设置背景色 vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->SetSize(800, 600); // 设置窗口大小 // 创建交互器并启动 vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); interactor->SetRenderWindow(renderWindow); renderWindow->Render(); interactor->Start(); ``` ### 4. 数学原理 球体的参数方程: $$ \begin{cases} x = x_c + r \sin\phi \cos\theta \\ y = y_c + r \sin\phi \sin\theta \\ z = z_c + r \cos\phi \end{cases} $$ 其中: - $(x_c, y_c, z_c)$ 为球心坐标 - $r$ 为半径 - $\theta \in [\theta_{\text{start}}, \theta_{\text{end}}]$(经度角) - $\phi \in [\phi_{\text{start}}, \phi_{\text{end}}]$(纬度角) 通过离散化 $\theta$ 和 $\phi$ 生成三角面片网格[^1][^2] ### 5. 性能优化建议 - 降低分辨率(设为 8-16)可提升渲染性能 - 使用 `SetPhiResolution(0)` 自动计算合适的分辨率 - 部分球体(如半球)可减少 50% 面片数
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值