VTK005_vtk-相机

相机介绍:

      首先,这里的相机并不是我们生活中常说的相机,但也有类似的地方,在计算机图形学中,相机的位置焦点等参数实际上对应生活中人眼的位置和所看的点。无论是OpenGL还是VTK中,都有相机,当前使用的相机将决定我们看到的事物。

      很多做三维设计的朋友都会知道,设计完成后,可以创建多个相机用于作品展示,我们选择相机,实际上也就是选择的我们眼睛的位置,从不同的空间位置查看作品,不用每次都手动调整当前相机位置到比较好的位置。

      在计算机中,相机可以看成空间中的一个矢量(仅仅是看成),起点即为当前相机的位置,也就是我们眼睛的位置,方向就是相机朝向,也就是我们眼睛看的方向。实际上,vtk中的相机还包含其他的参数,比如焦点,俯仰角、偏航角、高程等,甚至很多参数都可以通过已有的其他参数计算出来,但是,为了方便不同的方式使用相机,vtk相机做了很多方法的封装,可以通过不同方式设定相机达到相同的结果。很显然,对于一个相机而言,本身是简单的,常用的方法也不会太多。因此,本文并不会对大量不常用的方法作介绍。

VTK相机:

      在vtk中,如果没有创建自己的相机,vtkRender会默认创建一个相机,在最开始,太会自动调整相机位置及焦点(位置和焦点决定朝向),自动调整使得这个Render中的所有模型居中显示,便于观察。实际上,我们还可以创建自己的相机,并将之应用到一个渲染器,也可以创建多个相机备用。

      如图所示,vtk相机直接继承于vtkobject,对于相机参数的设置,与属性类似,属性的设置可以是vtkActor->GetProperty()->Setxxx(),也可以使直接对属性对象设置好后使用vtkActor->SetProperty(xx)来设置。相机是作用域vtkRender的,因此相机的设置可以使下面两种方式:1、vtkRender->GetActiveCamera()->Setxxx()来设置们2、还可以申请一个相机对象,对相机参数进行设置,然后使用vtkRender->SetActiveCamera来设置到渲染器。

相机常见移动方式介绍:

      1、相机前后左右上下移动,就是相机的正常移动,向前移动,就是向有当前位置向焦点的方向移动,其他方向也类似,我们可以通过vtkCamera->SetPosition()来设置相机的位置,从而实现个方向移动,特别注意,这个是设置的世界坐标。

      2:相机旋转,指的是相机本身俯仰旋转,偏航旋转以及横滚旋转,俯仰旋转为Pitch()函数设置的,调用Pitch(1)就会使相机抬头1度,同样的,负数会向下看。参数就是这一次改变的度数(非总度数)。同理,调用Yaw()是改变偏航角,传入正数会向左看(体现为物体向右移动),Roll()是调整翻滚角,传入正数角度,相机顺时针旋转

class vtkMyCallback : public vtkCommand
{
public:
	static vtkMyCallback *New()
	{
		return new vtkMyCallback;
	}
	virtual void Execute(vtkObject *caller, unsigned long, void*) // 强制实现的方法
	{
		vtkRenderer *ren = reinterpret_cast<vtkRenderer*>(caller);
		cout << ren->GetActiveCamera()->GetPosition()[0] << " "
			<< ren->GetActiveCamera()->GetPosition()[1] << " "
			<< ren->GetActiveCamera()->GetPosition()[2] << "\n";
	}
};

int main()
{
	vtkSmartPointer<vtkRenderWindow> m_pRenderWin = vtkRenderWindow::New();
	vtkSmartPointer<vtkRenderWindowInteractor> m_pInteractor = vtkRenderWindowInteractor::New();
	vtkSmartPointer<vtkInteractorStyleTrackballCamera> m_pInteractorStyle = vtkInteractorStyleTrackballCamera::New();
	vtkSmartPointer<vtkActor> m_actor = vtkActor::New();
	vtkSmartPointer<vtkRenderer> m_render = vtkRenderer::New();
	vtkSmartPointer<vtkEarthSource> m_earth = vtkEarthSource::New();
	vtkSmartPointer<vtkPolyDataMapper> m_earthMap = vtkPolyDataMapper::New();
	vtkSmartPointer<vtkTransform> m_trans = vtkTransform::New();
	vtkSmartPointer<vtkCamera> m_pCamera = vtkCamera::New();

	m_earth->SetRadius(15);
	m_earth->SetOnRatio(6);		// 设置精度(0~16)16精度最低
//	m_earth->OutlineOff();		// 打开绘制大陆作为填充多边形或线框轮廓  效果不是很好
	m_earthMap->SetInputConnection(m_earth->GetOutputPort());

	m_trans->Translate(0, 0, 0);
	m_trans->RotateX(0);		// 沿x轴正方向顺时针旋转
	m_actor->SetMapper(m_earthMap);
	m_actor->SetUserTransform(m_trans);
	m_actor->GetProperty()->SetDiffuse(0.6);		// 设置漫反射分量
	m_actor->GetProperty()->SetSpecular(0.3);		// 设置镜面反射分量
	m_actor->GetProperty()->SetSpecularPower(20);	// 设置镜面反射
//	m_actor->VisibilityOff();						// 隐藏模型
	m_render->AddActor(m_actor);
//-------------------------------------------------------------------------
// 相机设置
	m_pCamera->SetPosition(0, 0, 50);
	m_pCamera->SetFocalPoint(0, 0, 0);
//-------------------------------------------------------------------------
	m_render->SetActiveCamera(m_pCamera);

	vtkMyCallback* mol = vtkMyCallback::New();
	m_render->AddObserver(vtkCommand::StartEvent, mol);	// 为渲染器添加观察器(回调函数)
	mol->Delete();

	m_render->SetViewport(0.0, 0.0, 1.0, 1.0);
	m_render->SetBackground(0.5, 0.3, 0.2);
	m_render->SetGradientBackground(true);		// 背景色渐变

	m_pRenderWin->AddRenderer(m_render);
	m_pRenderWin->SetSize(800, 600);
	m_pRenderWin->Render();

	m_pInteractor->SetInteractorStyle(m_pInteractorStyle);
	m_pInteractor->SetRenderWindow(m_pRenderWin);

	m_pRenderWin->Render();
// -----------相机设置------------------------
	for (int i = 0; i < 200; ++i)
	{
		m_pCamera->Pitch(0.1);    // 自行更改为 Yaw和Roll尝试
		m_pRenderWin->Render();
	}
// ----------------------------

	m_pInteractor->Start();

	return 0;
}

      3:相机还能绕着某一点移动,即绕一点旋转(类似于蚂蚁在乒乓球上面爬),这个点就是焦点。但是,只有两个方向,可以是竖直面上上下旋转,水平面上左右旋转,如果相机焦点是在物体中心,表现结果就是物体在旋转

      Elevation:上下旋转,传入角度为正则相机向上旋转(物体向下旋转)。Azimuth,相机绕焦点向右旋转,如果焦点在物体中心,看起来就是物体向左旋转,大家可以将上面的程序更改位使用Elevation和Azimuth函数,看看效果。

相机常用方法:

      上面所讲的SetPositionPitchYawRollElevationAzimuth六个方法这里就不做介绍了。

      (1)Zoom:视角设置,正常视角为45度,也可以设置成其他度数,看看效果。

      (2)SetClippingRange:设置近裁剪平面和远裁剪平面的位置,同样,也有Get方法。

      (3)SetFocalPoint:设置焦点。

      (4)Dolly:向焦点或者远离焦点移动。传入参数1.1代表每次向前移动0.1倍相机至焦点距离,传入0.9代表每次远离0.1倍距离。

      (5)SetViewUp:设置相机查看方向(就是相机正上方的方向),Roll就会影响这个方向。OrthogonalizeViewUp可以强制重新计算上方向。

      (6)SetRoll:设置相机横滚角,相对于世界空间的。同样有获取横滚角

      还有很多其他方法,但大多不是很常用。还可以为相机添加观察者等,每次更改就调用回调函数,这里不做介绍,详细学习可以访问vtkCamera类列表。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值