VTK9.3 触摸屏与鼠标 平移缩放旋转,支持中心点(两指缩放)与鼠标点缩放(鼠标位置缩放)

环境 Qt6.7+vtk9.3+vs2022

效果:

vtk鼠标位置缩放

如视频所示,鼠标不管在哪个位置鼠标滚轮都能按照鼠标位置缩放

注意::以下代码为以前编写的 可能有问题,

往后找2024/10/16的代码,一共4个文件 直接拉出来用

步骤

咋们要实现这个功能,继承vtkInteractorStyleTrackballCamera类

然后重写Dolly()

或者重写OnMouseWheelForward()与OnMouseWheelBackward()

其他不多说 直接代码

class CustomInteractorStyle:public vtkInteractorStyleTrackballCamera{
   
   
public:
	static CustomInteractorStyle* New(){
   
   
		CustomInteractorStyle* self = new CustomInteractorStyle();
	}
	vtkTypeMacro(CustomInteractorStyle,vtkInteractorStyleTrackballCamera);
	//方案一:重写滚轮事件,好处在于可以自定义一个bool变量是否按照鼠标位置进行缩放
	virtual void OnMouseWheelForward()override{
   
   
		if(Zoomflag){
   
   
			Dolly(1.1);
			
		}else{
   
   
			vtkInteractorStyleTrackballCamera::OnMouseWheelForward();
		}
	}
	virtual void OnMouseWheelBackward()override{
   
   
		if(Zoomflag){
   
   
			Dolly(0.9);
		}else{
   
   
			vtkInteractorStyleTrackballCamera::OnMouseWheelBackward();
		}
	}
	//方案二:注意如果选择重写滚轮事件这句话注释掉
	//using vtkInteractorStyleTrackballCamera::Dolly;
protected:
	//方案二:注意如果选择重写滚轮事件这句话注释掉
	//void Dolly(double factor)override{
   
   
	void Dolly(double factor)
	{
   
   
		DollyToPofsition(factor, this->Interactor->GetEventPosition(), this->GetDefaultRenderer());

		//这一句必须加,不然图像不出现,得拖拽一下
		this->GetDefaultRenderer()->ResetCameraClippingRange();
		
		m_rendererwindow->Render();
	}
	void DollyToPosition(double fact, int* position, vtkRenderer* renderer)
	{
   
   
	  vtkCamera* cam = renderer->GetActiveCamera();
	  if (cam->GetParallelProjection())
	  {
   
   
	    int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
	    // 相对于光标缩放
	    int* aSize = renderer->GetRenderWindow()->GetSize();
	    int w = aSize[0];
	    int h = aSize[1];
	    x0 = w / 2;
	    y0 = h / 2;
	    x1 = position[0];
	    y1 = position[1];
	    vtkPVInteractorStyle::TranslateCamera(renderer, x0, y0, x1, y1);
	    cam->SetParallelScale(cam->GetParallelScale() / fact);
	    vtkPVInteractorStyle::TranslateCamera(renderer, x1, y1, x0, y0);
	  }
	  else
	  {
   
   
	    // 相对于光标位置进行缩放
	    double viewFocus[4], originalViewFocus[3], cameraPos[3], newCameraPos[3];
	    double newFocalPoint[4], norm[3];
	
	    // 将焦点移动到光标位置
	    cam->GetPosition(cameraPos);
	    cam->GetFocalPoint(viewFocus);
	    cam->GetFocalPoint(originalViewFocus);
	    cam->GetViewPlaneNormal(norm);
	
	    CustomInteractorStyle::ComputeWorldToDisplay(
	      renderer, viewFocus[0], viewFocus[1], viewFocus[2], viewFocus);
	
	    CustomInteractorStyle::ComputeDisplayToWorld(
	      renderer, double(position[0]), double(position[1]), viewFocus[2], newFocalPoint);
	
	    cam->SetFocalPoint(newFocalPoint);
	
	    // 沿投影方向移入/移出相机
	    cam->Dolly(fact);
	
	    // 寻找新的焦点
	    cam->GetPosition(newCameraPos);
	
	    double newPoint[3];
	    newPoint[0] = originalViewFocus[0] + newCameraPos[0] - cameraPos[0];
	    newPoint[1] = originalViewFocus[1] + newCameraPos[1] - cameraPos[1];
	    newPoint[2] = originalViewFocus[2] + newCameraPos[2] - cameraPos[2];
	
	    cam->SetFocalPoint(newPoint);
	  }
  	}
  	void TranslateCamera(vtkRenderer* renderer, int toX, int toY, int fromX, int fromY)
	{
   
   
	  vtkCamera* cam = renderer->GetActiveCamera();
	  double viewFocus[4], focalDepth, viewPoint[3];
	  double newPickPoint[4], oldPickPoint[4], motionVector[3];
	  cam->GetFocalPoint(viewFocus);
	
	  CustomInteractorStyle::ComputeWorldToDisplay(
	    renderer, viewFocus[0], viewFocus[1], viewFocus[2], viewFocus);
	  focalDepth = viewFocus[2];
	
	  CustomInteractorStyle::ComputeDisplayToWorld(
	    renderer, double(toX), double(toY), focalDepth, newPickPoint);
	  CustomInteractorStyle::ComputeDisplayToWorld(
	    renderer, double(fromX), double(fromY), focalDepth, oldPickPoint);
	
	  //摄像机运动反向
	  motionVector[0] = oldPickPoint[0] - newPickPoint[0];
	  motionVector[1] = oldPickPoint[1] - newPickPoint[1];
	  motionVector[2] = oldPickPoint[2] - newPickPoint[2];
	
	  cam->GetFocalPoint(viewFocus);
	  cam->GetPosition(viewPoint);
	  cam->SetFocalPoint(motionVector[0] + viewFocus[0], motionVector[1] + viewFocus[1], motionVector[2] + viewFocus[2]);
	
	  cam->SetPosition(motionVector[0] + viewPoint[0], motionVector[1] + viewPoint[1], motionVector[2] +viewPoint[2]);
}
private:
	bool Zoomflag = false;
	//自行加函数获取
	vtkGenericOpenGLRenderWindow* m_rendererwindow;
};

最新代码话不多说

鼠标平移缩放旋转

左键平移 右键旋转 可以给中心点旋转,滚轮缩放(可以鼠标位置缩放)
VTKStyle.h

#pragma once
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkCamera.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkInteractorStyleRubberBandZoom.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderedAreaPicker.h>
#include <vtkCoordinate.h>
#include <vtkObjectFactory.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkPoints.h>
#include <vtkPolyLine.h>
#include <vtkCellArray.h>
#include <vtkPolyData.h>
#include <vtkActor2D.h>
#include <vtkPolyDataMapper2D.h>
#include <vtkProperty2D.h>
#include <vtkMapper2D.h>
#include <vtkRendererCollection.h>
#include <vtkUnsignedCharArray.h>
#include <vtkPointPicker.h>
#include <vtkIdTypeArray.h>
#include <vtkGlyph3D.h>
#include <vtkActor.h>
#include <vtkProperty.h>
#include <vtkMath.h>
#include <vtkTextActor.h>
#include <vtkUnsignedCharArray.h>
#include <vtkPointData.h>
#include <vtkPropPicker.h>
#include <QStringList>
#include <QString>
#include <windows.h>
#include <QTimer>
#include <thread>
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyData.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyLine.h>
#include <vtkUnsignedCharArray.h>
#include <QResizeEvent>
#include <vtkOrientationMarkerWidget.h>
#include <vtkAxesActor.h>
#include <vtkOutputWindow.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <QColor>
#include <vtkLine.h>
#include <vtkTransform.h>
#include <vtkSTLReader.h>
#include <vtkMaskPoints.h>
#include <vtkTransformPolyDataFilter.h>
#include <QFileDialog>
#include <QShowEvent>
#include "math.h"
#include <QRandomGenerator>

namespace {
   
   
	enum PanAxis {
   
   
		AXIS_X = 0,
		AXIS_Y,
		AXIS_XY
	};
}

//自定义鼠标事件类
class VTKStyle :public vtkInteractorStyleTrackballCamera {
   
   
public:
	static VTKStyle* New();
	vtkTypeMacro(VTKStyle, vtkInteractorStyleTrackballCamera);
public:
	void SetCenter(double* center);
	void setRenderWindow(vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderwindow);
private:
	void TranslatemousePos(int* pos);
	void DollToPosition(double fact, int* position, vtkRenderer* renderer);
	void TranslateCamera(vtkRenderer* renderer, int toX, int toY, int fromX, int fromY);
	void ComputeDisplayCenter();
protected:
	//using vtkInteractorStyleTrackballCamera::Dolly;
	//void Dolly(double factor)override;
	virtual void OnLeftButtonDown()override;
	virtual void OnLeftButtonUp()override;
	virtual void OnRightButtonDown()override;
	virtual void OnRightButtonUp()override;
	virtual void OnMouseWheelForward()override;
	virtual void OnMouseWheelBackward()override;
	virtual void OnMouseMove() override;
private:
	vtkSmartPointer<vtkGenericOpenGLRenderWindow>m_renderWindow;
	bool m_leftBtn = false;
	bool m_rightBtn = false;
	double m_mousePos[3] = {
   
    0,0,0 };
	double m_Center[3] = {
   
    500,500,500 };
	double m_DisplayCenter[2] = {
   
    0,0 };
	double m_RotationFactor = 1.0;
	bool m_mouseEvent = true;
	PanAxis m_AxisOfMovement = AXIS_XY;
};

VTKStyle.cpp

#include "VTKStyle.h"
VTKStyle* VTKStyle::New()
{
   
   
	VTKStyle* self = new VTKStyle();
	self->InitializeObjectBase();
	return self;
}
void VTKStyle::SetCenter(double* center) {
   
   
	m_Center[0] = center[
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老了希望

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值