可通过小球进行旋转的十字光标(vtkResliceCursor)

        前一段事件看到VTK的一个例子:

该案例是vtk.js写的,觉得很有意思,个人正好也要用到,于是萌生了用C++修改VTK源码来实现该功能的想法。原本以为很简单,只需要修改一下vtkResliceCursor就可以了,加上小球,加上几个Actor,就能实现,没想到该功能整花了我差不多一个月的时间。但也学到了不少知识,下面就该功能的实现效果和方法做个大致解说:

我实现的效果:

实现方法:

1,首先在vtkResliceCursor中定义六个小球的位置。因为是X,Y,Z三个轴,每个轴上两个小球,所以总共十六个小球。代码:

void vtkResliceCursor::BuildCursorGeometryWithoutHole()
{
	// 其他源码省略
    .......
	for (int i = 0; i < 3; i++)
	{
		 
		//wulc
		{
			this->SpherePoints[0][i] = this->Center[i] - sphereLength * this->XAxis[i];
			this->SpherePoints[1][i] = this->Center[i] + sphereLength * this->XAxis[i];
			this->SpherePoints[2][i] = this->Center[i] - sphereLength * this->YAxis[i];
			this->SpherePoints[3][i] = this->Center[i] + sphereLength * this->YAxis[i];
			this->SpherePoints[4][i] = this->Center[i] - sphereLength * this->ZAxis[i];
			this->SpherePoints[5][i] = this->Center[i] + sphereLength * this->ZAxis[i];
		}
 
	  }
    // 其他源码省略
    .......
}

sphereLength 是一个自定义的常数,也就是中心到小球的距离。可以是 30 ,40 ,50 .。。。。

 除此之外我们还要定义一个函数,通过该函数可以获取这六个小球的坐标。比如 GetPointPosition(double p[6][3]);

2,在vtkResliceCursorPicker中判断鼠标是否靠近小球中心位置,靠近小球坐标时,将鼠标光标变为手掌形状。判断方法就是鼠标的位置和小球位置的距离,其中有现成的代码:

/----------------wulc---------------------------------------------------
int vtkResliceCursorPicker::IntersectPointWithPoint(double p1[3], double p2[3], double Points[], double tol)
{
	double pts[6][3] = { {0,0,0} };
	for (size_t i = 0; i < 6; i++)
	{
		pts[i][0] = Points[3*i];
		pts[i][1] = Points[3*i + 1];
		pts[i][2] = Points[3 * i + 2];
	}

	int j = 0;
	for ( ; j < 6; j++)
	{
		double X[4] = { pts[j][0], pts[j][1], pts[j][2], 1 };
  
		int i;
		double ray[3], rayFactor, projXYZ[3];


		for (i = 0; i < 3; i++)
		{
			ray[i] = p2[i] - p1[i];
		}
		if ((rayFactor = vtkMath::Dot(ray, ray)) == 0.0)
		{
			return 0;
		}
		 
		const double t = (ray[0] * (X[0] - p1[0]) +
			ray[1] * (X[1] - p1[1]) +
			ray[2] * (X[2] - p1[2])) / rayFactor;

		if (t >= 0.0 && t <= 1.0)
		{
			for (i = 0; i < 3; i++)
			{
				projXYZ[i] = p1[i] + t * ray[i];
				if (fabs(X[i] - projXYZ[i]) > tol)
				{
					break;
				}
			}

			if (i > 2) // within tolerance
			{
				return 1;
			}
		}
	}
	return 0;
}

 3,最后要在vtkResliceCursorActor类中添加小球,代码:

//wulc
  if (this->Renderer == nullptr) return;
  if (axisNormal == 1)//x-z平面
  {
	   
	  double* position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(2);
	  if (fabs(position[0] - 0.0) > 0.001 || fabs(position[1] - 0.0) > 0.001 || fabs(position[2] - 0.0) > 0.001)
	  {
		  this->SphereActor[2]->GetProperty()->SetColor(1, 0, 0);
		  this->SphereActor[3]->GetProperty()->SetColor(1, 0, 0);
		  this->SphereActor[2]->SetPosition(position[0], position[1], position[2]);
		  this->SphereActor[3]->SetPosition(position[3], position[4], position[5]);

		  position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(0);

		  this->SphereActor[0]->GetProperty()->SetColor(0, 0, 1);
		  this->SphereActor[1]->GetProperty()->SetColor(0, 0, 1);
		  this->SphereActor[0]->SetPosition(position[0], position[1], position[2]);
		  this->SphereActor[1]->SetPosition(position[3], position[4], position[5]);
	  }

  }
  else if (axisNormal == 2)//x-y平面
  {
	  double* position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(0);
	  if (fabs(position[0] - 0.0) > 0.001 || fabs(position[1] - 0.0) > 0.001 || fabs(position[2] - 0.0) > 0.001)
	  {
		  this->SphereActor[0]->GetProperty()->SetColor(0, 1, 0);
		  this->SphereActor[1]->GetProperty()->SetColor(0, 1, 0);
		  this->SphereActor[0]->SetPosition(position[0], position[1], position[2]);
		  this->SphereActor[1]->SetPosition(position[3], position[4], position[5]);
		  position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(1);
		  this->SphereActor[2]->GetProperty()->SetColor(1, 0, 0);
		  this->SphereActor[3]->GetProperty()->SetColor(1, 0, 0);
		  this->SphereActor[2]->SetPosition(position[0], position[1], position[2]);
		  this->SphereActor[3]->SetPosition(position[3], position[4], position[5]);
		  
	  }
	  
  }
  else if (axisNormal == 0) //y-z平面
  {
	 

	  double* position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(2);
	  if (fabs(position[0] - 0.0) > 0.001 || fabs(position[1] - 0.0) > 0.001 || fabs(position[2] - 0.0) > 0.001)
	  {
	  	this->SphereActor[0]->GetProperty()->SetColor(0, 1, 0);
	  	this->SphereActor[1]->GetProperty()->SetColor(0, 1, 0);
	  	this->SphereActor[0]->SetPosition(position[0], position[1], position[2]);
	  	this->SphereActor[1]->SetPosition(position[3], position[4], position[5]);
	  	position = this->CursorAlgorithm->GetResliceCursor()->GetSpherePostion(1);
	  	this->SphereActor[2]->GetProperty()->SetColor(0, 0, 1);
	  	this->SphereActor[3]->GetProperty()->SetColor(0, 0, 1);
	  	this->SphereActor[2]->SetPosition(position[0], position[1], position[2]);
	  	this->SphereActor[3]->SetPosition(position[3], position[4], position[5]);
	   
	  }

  }

这就可以了,欢迎小伙伴能够一块讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/716858.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【面试 - 页面优化举例】页面跳转卡顿问题解决 - 页面跳转速度优化

目录 为何要优化如何优化优化1 - 懒加载优化2 - el-tree 子节点默认不展开 为何要优化 页面A跳转到也页面B时&#xff0c;页面出现卡顿情况&#xff1a; 【问题】页面A → 页面B时&#xff0c;页面B进入到了 created 钩子后过了六七秒才进入到 mounted 钩子&#xff1b;【分析经…

遗传算法浅理解

1. 什么是遗传算法&#xff1f; ​ 遗传算法&#xff0c;又称为 Genetic algorithm(GA)Genetic algorithm(GA)。其主要思想就是模拟生物的遗传与变异。它的用途非常广泛&#xff0c;可以用于加速某些求最大或者最小值的算法&#xff08;换句话说就是加速算法收敛&#xff0c;最…

PV180R1K1T1NMMC派克通轴传动结构柱塞泵

PV180R1K1T1NMMC派克通轴传动结构柱塞泵 派克柱塞泵的结构组成部分&#xff1a;柱塞、手把、斜盘、压盘、滑履、泵体、配油盘、传送轴。其优点如下&#xff1a; 1、结构紧凑耐用&#xff0c;具有灵活的安装接口 2、安静的工作 3、效率高 4、降低功耗和减少发热 5、具有“…

升级到tomcat10和Java 21后,idea控制台system.out.println输出中文乱码问题

最近一次性从tomcat 9升级到tomcat 10&#xff0c;同时Java sdk也从1.8升级到21。 升级过程中&#xff0c;当然会遇到很多问题&#xff0c;但是控制台输出中文乱码问题&#xff0c;着实折腾了很久。 1、尝试各种方法 网上说的很多通用方法都试过了&#xff0c;就是不生效。包…

编码在网络安全中的应用和原理

前言:现在的网站架构复杂&#xff0c;大多都有多个应用互相配合&#xff0c;不同应用之间往往需要数据交互&#xff0c;应用之间的编码不统一&#xff0c;编码自身的特性等都很有可能会被利用来绕过或配合一些策略&#xff0c;造成一些重大的漏洞。 什么是编码&#xff0c;为什…

别再这么起号了!TikTok小白起号误区,你中招了吗?

看过不少Tiktok新手的起号失败案例&#xff0c;总结下来就是以下这几个问题&#xff0c;今天结合一些个人起号心得给大家分享怎么成功在TK起号&#xff0c;希望对大家有所帮助。 手机/网络环境 首先我们要确保手机环境和网络环境没有问题&#xff0c;如果被TK判断出是非海外用户…

【YOLOv8改进[注意力]】在YOLOv8中添加ECA高效通道注意力(2020.4)的实践 + 含全部代码和详细修改方式 + 手撕结构图

本文将进行在YOLOv8中添加ECA高效通道注意力的实践,助力YOLOv8目标检测效果的实践,文中含全部代码、详细修改方式以及手撕结构图。助您轻松理解改进的方法。 改进前和改进后的参数对比: 目录 一 ECA 二 在YOLOv8中添加ECA注意力

synchronized死锁

1、死锁案例 /*** descpription: 死锁案例* date 2024/6/17*/ public class DeadLockDemo {public static void main(String[] args) {Object objA new Object();Object objB new Object();new Thread(() ->{synchronized (objA){System.out.println(Thread.currentThrea…

【产品经理】ERP订单处理3-解密促销策略

由于订单到电商ERP系统中&#xff0c;订单金额已经不能支持改动&#xff0c;故电商前台端的优惠券活动、满减活动、支付优惠活动无法使用&#xff0c;故电商ERP只涉及赠品的活动。 一、订单金额阶梯送 顾名思义&#xff1a;订单金额在某个或者某几个金额范围内赠送商品。 字…

设备物联网关在实际生产中的作用解析-天拓四方

随着物联网技术的迅猛发展&#xff0c;设备物联网关作为连接物理世界与数字世界的核心组件&#xff0c;其应用已经渗透到工业、农业、医疗等多个领域。本案例将聚焦于设备物联网关在某制造企业中的应用&#xff0c;详细解析其在实际生产中的重要作用。 案例背景 某制造企业面…

Browserslist: caniuse-lite is outdated。浏览器列表:caniuse lite已经过时???

一、最近运行项目启动时提示 Browserslist: caniuse-lite is outdated. Please run: npx update-browserslist-dblatest Why you should do it regularly: https://github.com/browserslist/update-db#readme 这要是这一句&#xff0c;Browserslist: caniuse-lite is outdated.…

离散数学-代数系统证明题归类

什么是独异点&#xff1f; 运算 在B上封闭&#xff0c;运算 可结合&#xff0c;且存在幺元。 学会合理套用题目公式结合律 零元&#xff1f; 群中不可能有零元 几个结论要熟记&#xff1a; 1.当群的阶为1时&#xff0c;它的唯一元素视作幺元e 2.若群的阶大于1时&#xff0c;…

成都爱尔胡建斌院长提醒一张眼底照,眼病早知道

眼底藏在眼睛后方&#xff0c;平时没注意无察觉&#xff0c;其实非常重要。它包含的部位多掌控着视觉问题&#xff0c;稍不注意就是视觉受损&#xff0c;视觉缺失&#xff0c;严重的甚至失明致盲。 眼球前面的角膜、晶体等&#xff0c;被称为眼前段&#xff0c;后面则被称之为…

Springboot微服务整合缓存的时候报循环依赖的错误 两种解决方案

错误再现 Error starting ApplicationContext. To display the conditions report re-run your application with debug enabled. 2024-06-17 16:52:41.008 ERROR 20544 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPLI…

如何通过改善团队合作来提高招聘效率

当招聘顶尖人才时&#xff0c;时间就是一切。招聘效率取决于团队快速响应和完成任务的能力&#xff0c;但招聘经理和面试官并不总是最关心重要的招聘任务。更重要的是&#xff0c;求职者的经历取决于准备好的面试官是否准时出现。有时候最好的候选人会接受另一份工作&#xff0…

gitlab仓库中用git bash生成不是默认路径的ssh秘钥

使用命令 ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 会在默认路径生成秘钥&#xff0c;&#xff08;C:\Users\用户\.ssh\&#xff09; 想要修改默认路径使用如下命令&#xff1a; ssh-keygen -t rsa -b 4096 -C "your_emailexample.com"…

MyBatis 获取参数的两种方式

${paramName} 使用这种方式的结果是直接替换。底层是用 Statement 实现的。 优点 使用 ${sort} 可以实现排序查询&#xff0c;而使用 #{sort} 就不能实现排序查询了&#xff0c;因为当使⽤ #{sort} 查询时&#xff0c;如果传递的值为 String 则会加单引号&#xff0c;就会导致 …

知乎号开始运营了,宣传一波

知乎号开始发布一些小说、散文还有诗歌了&#xff0c;欢迎大家多来关注 知乎链接&#xff1a;姜亚轲 每篇小说都改编成网易云音乐&#xff0c;文章中也有链接&#xff0c;我做的词&#xff0c;Suno编曲和演唱&#xff0c;欢迎大家来听听

AutoCAD 2024 mac/win版:智绘未来,设计更精彩

AutoCAD 2024是一款由Autodesk开发的计算机辅助设计(CAD)软件&#xff0c;作为AutoCAD系列的最新版本&#xff0c;它在设计、绘图和制造领域展现出了卓越的性能和广泛的应用前景。 AutoCAD 2024 win/Mac版获取 AutoCAD 2024在功能方面进行了大量增强和改进。它引入了智能对象捕…

Chromium 开发指南2024 Mac篇-编译前的准备工作(一)

1.引言 Chromium 是一款开源的网页浏览器项目&#xff0c;作为 Google Chrome 浏览器的基础&#xff0c;其卓越的性能和广泛的应用使其成为众多开发者研究和学习的对象。对于希望深入了解浏览器内核&#xff0c;或是计划在 Chromium 基础上开发自定义浏览器的开发者来说&#…