可通过小球进行旋转的十字光标(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]);
	   
	  }

  }

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值