方法签名
volume_object_model_3d_relative_to_plane( : : ObjectModel3D, Plane, Mode, UseFaceOrientation : Volume)
描述
该算子计算一个3D对象模型的面相对于一个平面的体积。该平面是一个x-y平面。
输入对象模型必须是三角化的或包含多边形集合。对于默认设置,如果网格划分是封闭的且有序的,该算子计算真实的体积。对于网格划分不是封闭的或面不是连续的,计算的体积受到参数Mode和UseFaceOrientation的影响。
体积计算步骤
- 对模型进行三角化
- 投影三角面元的角点到指定平面
- 根据指定的UseFaceOrientation参数计算每个三棱柱的体积
- 分别计算平面之上和平面之下的体积和(计算时,使用体积的正负属性)
- 根据指定的Mode参数,对平面之上和平面之下进行操作
- 仅输出值,而不输出正负属性
参数解释
Mode:
- 'signed' >> 平面以上和平面以下的体积和
- 'unsigned' >> 平面之上的体积和减去平面之下的体积和
- 'positive' >> 仅获取平面之上的体积和
- 'negative' >> 仅获取平面之下的体积和
UseFaceOrientation:
- 'true' >> 使用三角面元相对于指定平面的方向。如果从平面看向三角面元,三角面元的角点索引是按照顺时针方向排列,该点面是远离指定平面的。如果三角面元是远离平面的,则体积具有正属性,否则体积具有负属性。
- 'false' >> 仅考虑三角面元是在指定平面之上还是之下。在平面上为正,在平面下为负。
样例
dev_update_off ()
dev_close_window ()
dev_open_window (0, 0, 698, 531, 'black', WindowHandle)
set_font (WindowHandle, 'Courier New-Bold-14')
*生成立方体
gen_box_object_model_3d ([0, 0, 0.08, 0, 0, 0, 0], 0.1, 0.2, 0.1, ObjectModel3DBox)
* 计算凸包
convex_hull_object_model_3d (ObjectModel3DBox, ObjectModel3DConvexHullBox)
***************************************************************************
* 获取模型的XYZ坐标
***************************************************************************
get_object_model_3d_params (ObjectModel3DConvexHullBox, 'point_coord_x', point_coord_x)
get_object_model_3d_params (ObjectModel3DConvexHullBox, 'point_coord_y', point_coord_y)
get_object_model_3d_params (ObjectModel3DConvexHullBox, 'point_coord_z', point_coord_z)
***************************************************************************
* 获取模型中各个三角面元的角点坐标在点坐标序列中的索引
***************************************************************************
get_object_model_3d_params (ObjectModel3DConvexHullBox, 'triangles', triangles)
***************************************************************************
* 生成平面
***************************************************************************
gen_rectangle2_contour_xld (Rectangle, 0, 0, 0, 0.15, 0.15)
get_contour_xld (Rectangle, Row, Col)
pose_plane := [0, 0, 0, 0, 0, 0, 0]
gen_plane_object_model_3d (pose_plane, Col, Row, ObjectModel3DPlane)
convex_hull_object_model_3d (ObjectModel3DPlane, ObjectModel3DNormals)
***************************************************************************
* 根据指定的参数计算模型相对于平面的体积
***************************************************************************
volume_object_model_3d_relative_to_plane (ObjectModel3DConvexHullBox, pose_plane,'signed', 'true', Volume0)
volume_object_model_3d_relative_to_plane (ObjectModel3DConvexHullBox, pose_plane,'unsigned', 'true', Volume1)
volume_object_model_3d_relative_to_plane (ObjectModel3DConvexHullBox, pose_plane,'positive', 'true', Volume2)
volume_object_model_3d_relative_to_plane (ObjectModel3DConvexHullBox, pose_plane,'negative', 'true', Volume3)
volume_object_model_3d_relative_to_plane (ObjectModel3DConvexHullBox, pose_plane,'signed', 'false', Volume4)
volume_object_model_3d_relative_to_plane (ObjectModel3DConvexHullBox, pose_plane,'unsigned', 'false', Volume5)
volume_object_model_3d_relative_to_plane (ObjectModel3DConvexHullBox, pose_plane,'positive', 'false', Volume6)
volume_object_model_3d_relative_to_plane (ObjectModel3DConvexHullBox, pose_plane,'negative', 'false', Volume7)
***************************************************************************
* 显示模型
***************************************************************************
CamParam := ['area_scan_division', 0.06, 0, 8.5e-006, 8.5e-006, 349, 265, 698, 531]
Pose := [0.0144074,-0.00394058,6.89431,107.148,357.864,262.975,0]
GenParamName1 := ['colored','disp_pose','alpha','disp_lines','color_0','color_1']
GenParamValue1 := [12,'true',0.6,'true','cyan','magenta']
disp_object_model_3d (WindowHandle, [ObjectModel3DPlane, ObjectModel3DConvexHullBox], CamParam, Pose, GenParamName1, GenParamValue1)
***************************************************************************
* 显示坐标点的索引
***************************************************************************
* 设置窗口显示区域
dev_set_part (0,0,CamParam[8],CamParam[7])
* 获取世界坐标系在相机坐标系中的位姿。
* 因为Pose是相机在世界坐标系中的位姿(对应相机坐标系到世界坐标系中的变换),所以需要反转
pose_invert (Pose, PoseInvert)
* 将位姿转换为变换矩阵,获取世界坐标系到相机坐标系的变换矩阵
pose_to_hom_mat3d (Pose, HomMat3D)
* 根据变换矩阵,获取世界坐标系下的点在相机坐标系中的坐标
affine_trans_point_3d (HomMat3D, point_coord_x, point_coord_y, point_coord_z, Qx, Qy, Qz)
* 将相机坐标系中的点转换到图像坐标系
project_3d_point( Qx, Qy, Qz, CamParam , Row, Column)
* 在图像窗口显示点的坐标索引
for Index := 0 to |Row| - 1 by 1
dev_disp_text (Index + '(' + point_coord_x[Index] + ','+ point_coord_y[Index] + ','+ point_coord_z[Index] + ')', 'image', Row[Index], Column[Index], 'red', 'box', 'false')
endfor
***************************************************************************
* 释放模型
***************************************************************************
clear_object_model_3d (ObjectModel3DNormals)
clear_object_model_3d (ObjectModel3DConvexHullBox)
clear_object_model_3d (ObjectModel3DPlane)
clear_object_model_3d (ObjectModel3DBox)
1. 角点编号
2. 点坐标
point_coord_x : [-0.05, 0.05, 0.05, -0.05, -0.05, 0.05, -0.05, 0.05]
point_coord_y : [ -0.1, -0.1, 0.1, 0.1, 0.1, 0.1, -0.1, -0.1]
point_coord_z : [ 0.13, 0.13, 0.13, 0.13, 0.03, 0.03, 0.03, 0.03]
3. 三角面元的点索引
根据定义,每三个索引为一组,对应于一个三角面元。示例中,共包含12个三角面元,对应的角点在角点序列中的索引如下:
01 >> 0, 2, 1,
02 >> 0, 3, 2,
03 >> 4, 2, 3,
04 >> 4, 5, 2,
05 >> 4, 3, 0,
06 >> 4, 0, 6,
07 >> 7, 1, 2,
08 >> 7, 2, 5,
09 >> 7, 0, 1,
10 >> 7, 6, 0,
11 >> 7, 5, 4,
12 >> 7, 4, 6
4. 应用参数 UseFaceOrientation 判断体积具有的正负属性
由于投影之后只有索引为01,02,11,12的面元在指定平面上不共线,能够计算体积信息,其它三角面元的角点在平面的投影是共线的,不需要计算体积。
- UseFaceOrientation = 'true' 沿着指定平面的法线方向看下组成三角面元的角点的索引顺序。
- 01 >> 0, 1, 2 :平面之上, 逆时针,体积具有负属性,0.1 * 0.3 * 0.13 * 0.5 = 0.0013(-)
- 02 >> 0, 3, 3 :平面之上, 逆时针,体积具有负属性,0.1 * 0.3 * 0.13 * 0.5 = 0.0013(-)
- 11 >> 7, 5, 4 : 平面之上,顺时针,体积具有正属性,0.1 * 0.3 * 0.03 * 0.5 = 0.0003(+)
- 12 >> 7, 4, 6 : 平面之上,顺时针,体积具有正属性,0.1 * 0.3 * 0.03 * 0.5 = 0.0003(+)
- UseFaceOrientation = 'false'
- 01 >> 0, 1, 2 : 平面之上,体积具有正属性,0.1 * 0.3 * 0.13 * 0.5 = 0.0013(+)
- 02 >> 0, 3, 3 : 平面之上,体积具有正属性,0.1 * 0.3 * 0.13 * 0.5 = 0.0013(+)
- 11 >> 7, 5, 4 : 平面之上,体积具有正属性,0.1 * 0.3 * 0.03 * 0.5 = 0.0003(+)
- 12 >> 7, 4, 6 : 平面之上,体积具有正属性,0.1 * 0.3 * 0.03 * 0.5 = 0.0003(+)
5. 分别计算平面之上和平面之下的体积
- 平面之上(UseFaceOrientation = 'true'): (-0.0013) + (-0.0013) + (0.0003) + (0.003) = 0.002
- 平面之下(UseFaceOrientation = 'true'): ( 0) + ( 0) + ( 0) + ( 0) = 0
- 平面之上(UseFaceOrientation = 'false'):( 0.0013) + ( 0.0013) + (0.0003) + (0.003) = 0.0032
- 平面之下(UseFaceOrientation = 'false'):( 0) + ( 0) + ( 0) + ( 0) = 0
6. 应用参数Mode对指定平面之上和之下的体积进行运算
- UseFaceOrientation = 'true'
- Mode = 'signed': 0.002 + 0 = 0.002
- Mode = 'unsigned': 0.002 - 0 = 0.002
- Mode = 'positive': 0.002
- Mode = 'negative': 0
- UseFaceOrientation = 'false'
- Mode = 'signed': 0.0032 + 0 = 0.0032
- Mode = 'unsigned': 0.0032 - 0 = 0.0032
- Mode = 'positive': 0.0032
- Mode = 'negative': 0