一、点云从点A沿直线运动至B点
过程为:
1、读取点云
本例子用凸包算子convex_hull_object_model_3d生成点云,这个步骤可以换成自己的,直接读取点云即可。
2、设置旋转的角度
3、对点云进行转化
4、显示
5、带动画效果的移动代码
dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 1024, 768, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
tuple_gen_const (220, '', Labels)
Colors := 'color_' + [0:220]
StepSize := 0.05
WaitSeconds := 0.05
Tx := 50
Ty := 50
Tz := 80
DualQuatTrans := [1,0,0,0,0,Tx / 2,Ty / 2,Tz / 2]
DualQuatStart := [1,0,0,0,0,0,0,0]
*创建平移箭头的可视化
create_pose (Tx, Ty, Tz, 0, 0, 0, 'Rp+T', 'gba', 'point', TransPose)
gen_arrow_object_model_3d (0.2, [0,0,0,0,0,0,0], TransPose, OM3DArrow)
X := [-30,30,30,-30,-30,30,30,-30]
Y := [-20,-5,20,20,-20,20,20,20]
Z := [-10,-10,-10,-10,10,0,0,10]
gen_object_model_3d_from_points (X / 2, Y / 2, Z / 2, ObjectModel3DTmp)
convex_hull_object_model_3d (ObjectModel3DTmp, ObjectModel3D)
tuple_gen_const (|OM3DArrow|, 'khaki', ColorOM3DArrow)
* 可视化移动过程
NumOM3D := |[ObjectModel3D,OM3DArrow]| - 1
*visualize_object_model_3d (WindowHandle, [ObjectModel3D,OM3DArrow], [], [], ['color_0',Colors[0:NumOM3D],'alpha'], ['orange','green',ColorOM3DArrow,0.5], '移动点云', [], [], VisPose2)
for Index := 0 to 1 + StepSize by StepSize
*向四元数中插值,步长为0.05
dual_quat_interpolate (DualQuatStart, DualQuatTrans, Index, DualQuatTransInterpolated)
*将对偶四元数转化为3D位姿
dual_quat_to_pose (DualQuatTransInterpolated, PoseTrans)
*对点云进行刚性变换,移动至新的位置
rigid_trans_object_model_3d (ObjectModel3D, PoseTrans, ObjectModel3DTrans)
NumOM3D := |[ObjectModel3D,ObjectModel3DTrans,OM3DArrow]| - 1
*显示
disp_object_model_3d (WindowHandle, [ObjectModel3D,ObjectModel3DTrans,OM3DArrow], [], [], ['color_0',Colors[0:NumOM3D],'alpha'], ['orange','green','white',ColorOM3DArrow,0.5])
wait_seconds (WaitSeconds)
endfor
6、效果图
7、去掉动画效果,简化的代码如下
dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 1024, 768, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
X := [-30,30,30,-30,-30,30,30,-30]
Y := [-20,-5,20,20,-20,20,20,20]
Z := [-10,-10,-10,-10,10,0,0,10]
gen_object_model_3d_from_points (X / 2, Y / 2, Z / 2, ObjectModel3DTmp)
convex_hull_object_model_3d (ObjectModel3DTmp, ObjectModel3D)
*从初始位置,沿x轴移动50,沿y轴移动50,沿z轴移动80
PoseTrans2:=[50,50,80,0,0,0,0]
*对点云进行刚性变换,移动至新的位置
rigid_trans_object_model_3d (ObjectModel3D, PoseTrans2, ObjectModel3DTrans2)
disp_object_model_3d (WindowHandle, [ObjectModel3D,ObjectModel3DTrans2], [], [], ['color_0','color_1','alpha'], ['orange','green',0.5])
二、点云绕Z轴旋转135度
1、带动画效果的旋转代码
指定开始和最终旋转的四元数.
有意思的是写成360度不进行旋转,所以它里面是有判断的,
如果想获得各个角度,可以转正的180和负180度说明,不添加VisPose1,也可以旋转,就是显示点云的时候角度不是很好,效果很不好,halcon窗口会根据点云的位置和大小自动调整点云显示的位置,窗口显示不够稳定
* 使用对偶四元数进行刚性变换
*
dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 1024, 768, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
Instructions[0] := 'Rotate: Left button'
Instructions[1] := 'Zoom: Shift + left button'
Instructions[2] := 'Move: Ctrl + left button'
tuple_gen_const (220, '', Labels)
Colors := 'color_' + [0:220]
*说明,不添加VisPose1,也可以旋转,就是显示的时候角度不是很好,很难看
create_pose (-2, 4, 500, 125, 0, 325, 'Rp+T', 'gba', 'point', VisPose1)
gen_initial_object_model_3d (ObjectModel3DInitial)
disp_object_model_3d (WindowHandle, ObjectModel3DInitial, [], VisPose1, ['disp_pose','color','alpha'], ['true','orange',0.5])
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
* 定义指定开始和最终旋转的四元数.
*有意思的是写成360度不进行旋转,所以它里面是有判断的,
*如果想获得各个角度,可以转正的180和负180度
Rotation := rad(135)
DualQuatStart := [1,0,0,0,0,0,0,0]
DualQuatRotation := [cos(Rotation / 2),0,0,sin(Rotation / 2),0,0,0,0]
StepSize := 0.05
WaitSeconds := 0.05
* Visualize rotation.
for Index := 0 to 1 + StepSize by StepSize
* 依次插入位于开始和最后旋转之间的对偶四元数,步长为0.05。
dual_quat_interpolate (DualQuatStart, DualQuatRotation, Index, DualQuatRotationInterpolated)
* 将双四元数转换为姿势。
dual_quat_to_pose (DualQuatRotationInterpolated, PoseRotation)
* 转换初始三维对象模型并显示它.
rigid_trans_object_model_3d (ObjectModel3DInitial, PoseRotation, ObjectModel3DRotation)
disp_object_model_3d (WindowHandle, [ObjectModel3DInitial,ObjectModel3DRotation], [], VisPose1, ['disp_pose_0','color_0','color_1','alpha'], ['true','orange','green',0.5])
wait_seconds (WaitSeconds)
endfor
2、旋转简化后的代码
实现绕z轴旋转135度,与上面的效果是一样的
dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 1024, 768, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
X := [-30,30,30,-30,-30,30,30,-30]
Y := [-20,-5,20,20,-20,20,20,20]
Z := [-10,-10,-10,-10,10,0,0,10]
gen_object_model_3d_from_points (X / 2, Y / 2, Z / 2, ObjectModel3DTmp)
convex_hull_object_model_3d (ObjectModel3DTmp, ObjectModel3D)
*从初始位置,沿z轴旋转135度
PoseTrans2:=[0,0,0,0,0,135,0]
*对点云进行刚性变换,移动至新的位置
rigid_trans_object_model_3d (ObjectModel3D, PoseTrans2, ObjectModel3DTrans2)
disp_object_model_3d (WindowHandle, [ObjectModel3D,ObjectModel3DTrans2], [], [], ['color_0','color_1','alpha'], ['orange','green',0.5])
3、效果图
三、弧线运动
弧线运动其实就是结合了平移和旋转,将上面的两种方法结合起来而已,不再详细赘述。
1、弧线运动动画效果代码
dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 1024, 768, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
Instructions[0] := 'Rotate: Left button'
Instructions[1] := 'Zoom: Shift + left button'
Instructions[2] := 'Move: Ctrl + left button'
tuple_gen_const (220, '', Labels)
Colors := 'color_' + [0:220]
StepSize := 0.05
WaitSeconds := 0.05
Tx := 50
Ty := 50
Tz := 80
DualQuatTrans := [1,0,0,0,0,Tx / 2,Ty / 2,Tz / 2]
DualQuatStart := [1,0,0,0,0,0,0,0]
* 点云显示的角度,如果不加,点云在动作的时候,窗口会自动调整显示的中心位置,显示效果不加
create_pose (Tx, Ty, Tz, 0, 0, 0, 'Rp+T', 'gba', 'point', TransPose)
create_pose (-31, 32, 990, 125, 0, 325, 'Rp+T', 'gba', 'point', VisPose2)
gen_arrow_object_model_3d (0.2, [0,0,0,0,0,0,0], TransPose, OM3DArrow)
X := [-30,30,30,-30,-30,30,30,-30]
Y := [-20,-5,20,20,-20,20,20,20]
Z := [-10,-10,-10,-10,10,0,0,10]
gen_object_model_3d_from_points (X / 2, Y / 2, Z / 2, ObjectModel3DTmp)
convex_hull_object_model_3d (ObjectModel3DTmp, ObjectModel3DInitial)
d := TransPose[0]
create_pose (-1, 0, 0, 0, 0, 0, 'Rp+T', 'gba', 'point', L)
create_pose (TransPose[0] / 2, TransPose[1] / 2, TransPose[2] / 2, 0, 0, 0, 'Rp+T', 'gba', 'point', P)
screw_to_dual_quat ('point', L[0], L[1], L[2], P[0], P[1], P[2], -rad(90), d, DualQuaternionScrew)
dual_quat_interpolate (DualQuatStart, DualQuaternionScrew, [0:StepSize / 5:1], DualQuatScrewInterpolated)
dual_quat_to_pose (DualQuatScrewInterpolated, ScrewPoses)
NumOM3D := |[ObjectModel3DInitial]| - 1
visualize_object_model_3d (WindowHandle, [ObjectModel3DInitial], [], VisPose2, ['disp_pose_0','color_0','alpha'], ['true','orange',0.5], '', '', Instructions, VisPose2)
for Index := 0 to |ScrewPoses| / 7 - 1 by 1
Pose := ScrewPoses[7 * Index:(Index + 1) * 7 - 1]
rigid_trans_object_model_3d (ObjectModel3DInitial, Pose, ObjectModel3DScrew)
NumOM3D := |[ObjectModel3DInitial,ObjectModel3DScrew]| - 1
disp_object_model_3d (WindowHandle, [ObjectModel3DInitial,ObjectModel3DScrew], [], VisPose2, ['color_0','color_1','alpha'], ['orange','cyan',0.5])
endfor
本文参考例程:explain_dual_quaternions.hdev,例程里面实现了很复杂的运动过程
/*------------------------------------------------------------
// 作 者: 大胡子大叔
// 版权声明: 未经授权请勿转载,谢谢合作!
-------------------------------------------------------------*/