lilillos 2021-06-16 17:01 采纳率: 50%
浏览 350
已采纳

如何在vtk中旋转平面?或者更一般的问题,如何在三维中旋转一个平面?

可将其过程描述为,平面a的法向量为na,目标平面的法向量为nb,当将平面a的法向量na被旋转至与nb同向时,停止旋转。

我自己觉得这个问题与StackOverflow这个问题相同https://stackoverflow.com/questions/9423621/3d-rotations-of-a-plane

期望的效果,圆环应该出现在每个线段拐点处,圆环的平面垂直于折线,即折线垂直穿过每个圆环平面的中心(圆环平面应与图中紫色示意线相同)。

我自己采用了以下2种方案:

1. 按照StackOverflow上的答案,构造了答案中提到的矩阵,但是结果不对。结果如下图所示。

具体代码 

{
            //目标法向量方向
			vtkVector3d vec_normal(x - x_before, y - y_before, z - z_before);
			vec_normal = vec_normal.Normalized();
			//z_direction 为原始法向量方向
			vtkVector3d cross_direction = vec_normal.Cross(z_direction).Normalized();
			
			double theta = vtkMath::AngleBetweenVectors(vec_normal.GetData(), z_direction.GetData());
			double c = theta;
			double s = std::sqrt(1 - theta * theta);
			double C = 1 - theta;

			vtkSmartPointer<vtkMatrix4x4> m = vtkSmartPointer<vtkMatrix4x4>::New();
			double ma[4][4] = { {cross_direction.GetX()*cross_direction.GetX()*C + c,cross_direction.GetX()*cross_direction.GetY()*C - cross_direction.GetZ()*s,cross_direction.GetX()*cross_direction.GetZ()*C + cross_direction.GetY()*s,0}
							 ,{cross_direction.GetY()*cross_direction.GetX()*C + cross_direction.GetZ()*s,cross_direction.GetY()*cross_direction.GetY()*C + c,cross_direction.GetY()*cross_direction.GetZ()*C - cross_direction.GetX()*s,0}
							 ,{cross_direction.GetZ()*cross_direction.GetX()*C - cross_direction.GetY()*s,cross_direction.GetZ()*cross_direction.GetY()*C + cross_direction.GetX()*s,cross_direction.GetZ()*cross_direction.GetZ()*C + c,0} 
							,{0,0,0,1} };
			for (int i = 0; i < 4; i++)
			{
				for (int j = 0; j < 4; j++)
				{
					//void SetElement(int i, int j, double value),i行、j列的值为value
					m->SetElement(i, j, ma[i][j]);
				}
			}

			vtkNew<vtkTransform> trans;
			trans->Translate(x, y, z);
			trans->SetMatrix(m);

			//trans->RotateWXYZ(vtkMath::DegreesFromRadians(theta), cross_direction[0], cross_direction[1], cross_direction[2]);
			//trans->RotateWXYZ(theta, cross_direction[0], cross_direction[1], cross_direction[2]);
			vtkNew<vtkTransformPolyDataFilter> pTransformPolyDataFilter;
			pTransformPolyDataFilter->SetInputData(circle);
			pTransformPolyDataFilter->SetTransform(trans);
			pTransformPolyDataFilter->Update();


			circle = pTransformPolyDataFilter->GetOutput();
}

方法二,利用vtk中的rotatewxyz方法做旋转。自认为思路与stackoverflow一致,都是利用构造新的旋转轴来进行旋转。因为我也无法确认StackOverflow中给出的矩阵的原理是什么。

vtkNew<vtkTransform> trans;
trans->Translate(x, y, z);
trans->RotateWXYZ(vtkMath::DegreesFromRadians(theta), cross_direction[0], cross_direction[1], cross_direction[2]);

效果如图所示,位置对了,但是圆环的方向与折线方向相同,而不是垂直。

 

 

  • 写回答

2条回答 默认 最新

  • lilillos 2021-06-16 21:36
    关注

    自问自答。利用rotatewxyz方法,旋转角 为180-theta.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 一道python难题2
  • ¥15 一道python难题
  • ¥15 用matlab 设计一个不动点迭代法求解非线性方程组的代码
  • ¥15 牛顿斯科特系数表表示
  • ¥15 arduino 步进电机
  • ¥20 程序进入HardFault_Handler
  • ¥15 oracle集群安装出bug
  • ¥15 关于#python#的问题:自动化测试
  • ¥20 问题请教!vue项目关于Nginx配置nonce安全策略的问题
  • ¥15 教务系统账号被盗号如何追溯设备