https://www.cnblogs.com/zfyouxi/p/5234459.html
我的目标是:画一条直线,读进去一个STL模型,把模型沿着直线的方向摆放;目前正在做,参考这个博客的,如果我写好了会来贴代码!good luck!
更新:
2019.1.31 搞这个,理论和推倒都符合逻辑了,但是因为调用顺序没对,所以耽误我两天时间,下面我把具体思路理一下。
1、首先需要知道你的模型的方向向量:物体向量 ObjectVector
这个向量的求法:把STL模型都进去,用鼠标沿模型摆放方向点两个点,可以求出向量的;我是这么搞的
2、知道目标向量:目标向量(这里是我的直线的方向向量) TargetVector。
直线上的两个点是X1,X2
3、通过ObjectVector 和 TargetVector计算 旋转角 和 法向量 n
//旋转角度计算公式是下面的:
(这个计算的是弧度)
(得到旋转角)
//法向量计算:(即旋转轴)
//计算两个空间向量的法向量
double[3] CalclulateN (double a[3], double b[3])
{
double n[3] ;
n[0] = a[1] * b[2] - a[2] * b[1];
n[1] = a[2] * b[0] - a[0] * b[2];
n[2] = a[0] * b[1] - a[1] * b[0];
return n;
}
4、下面就是平移和旋转了
STLmapper->SetInputConnection(image->GetoutPort());
STLactor->SetMapper(STLmapper);
STLactor->SetScale(0.5, 0.5, 0.5);//这个是缩小物体的,因为我的STL模型比较大
STLactor->SetOrigin(0,0,0);
STLactor->SetPosition(X1[0],X1[1],X1[2]);//先将物体直接放与直线一端,直线的尾部端点
STLactor->RotateWXYZ(theta , n[0],n[1],n[2]);//绕法向量作为旋转轴旋转theta角度
5、到此3D显示时把直线和STLactor 都显示出来就OK!
6、但是,如果这个直线是人为动态指定的,比如我用鼠标画线line1,那么第一次按照上面的步骤,STLactor自会转向直线的方向;
(下面的步骤是在窗口不关闭的情况下说的,如果你窗口关掉,重新执行程序,结果依然是对的!!!!!!)
如果窗口不关闭,我这时候再画一条直线,结果就会出错(大家可以试试),原因是:第一次旋转结束后,STLactor的方向向量已经发生了变化,不再是我们第一步得到的ObjectVector,而变成前一次的直线向量TargetVector
有两种方法解决:
(1)第二次执行的时候先绕前面一次的旋转轴和旋转向量 反旋转回去;
再执行这一次的移动和旋转;
if(times==0)
{
STLactor->SetOrigin(0,0,0);
STLactor->SetPosition(X[0],X[1],X[2]);
STLactor->RotateWXYZ(theta, n[0],n[1],n[2]);
ANTI_RADIAN = theta;
NORMALVECTOR[0] = n[0],NORMALVECTOR[1] = n[1],NORMALVECTOR[2] = n[2];
}
else
{
STLactor->RotateWXYZ(-ANTI_RADIAN, NORMALVECTOR[0],NORMALVECTOR[1],NORMALVECTOR[2]);
STLactor->SetOrigin(0,0,0);
STLactor->SetPosition( X[0],X[1],X[2]);//新直线的位置
STLactor->RotateWXYZ(theta, n[0],n[1],n[2]);
ANTI_RADIAN = theta;
NORMALVECTOR[0] = n[0],NORMALVECTOR[1] = n[1],NORMALVECTOR[2] = n[2];
}
(2)更新物体的方向向量为上一次的直线向量,与新直线的方向向量重新计算旋转角和法向量,执行 3 和 4 。
结果图:一个窗口内不断画直线。这里我是点两个点,画直线,然后actor沿直线方向摆放!
绿色的是我的直线;
不知道我说明白了不,^_^