如何在PCL中绘制法线平面

时间:2013-09-20 16:30:06

标签: geometry point-cloud-library

我有平面方程描述属于3D平面的点和普通X,Y,Z的原点。这应该足以生成类似3D箭头的东西。在pcl中,这可以通过观察者实现,但我希望将这些3D点实际存储在云中。那么如何生成呢?顶部有圆锥的圆柱体?

1 个答案:

答案 0 :(得分:1)

生成垂直于平面的直线:

你有平面方程。这为您提供了飞机法线的方向。如果您使用PCL来获取平面,则这是在ModelCoefficients中。详情请见SampleConsensusModelPerpendicularPlane

第一步是在你提到的点(XYZ)上画一条垂直于法线的线。设(NORMAL_XNORMAL_YNORMAL_Z)是你从平面方程得到的法线。像。的东西。

pcl::PointXYZ pnt_on_line;
for(double distfromstart=0.0;distfromstart<LINE_LENGTH;distfromstart+=DISTANCE_INCREMENT){
  pnt_on_line.x = X + distfromstart*NORMAL_X;
  pnt_on_line.y = Y + distfromstart*NORMAL_Y;
  pnt_on_line.z = Z + distfromstart*NORMAL_Z;
  my_cloud.points.push_back(pnt_on_line);
}

现在你想在你的箭头上放一个帽子,现在pnt_on_line包含你想要放置它的行的末尾。要制作锥体,您可以沿着箭头环绕角度和距离,从中计算局部x和y和z,并将它们转换为点云空间中的点:z部分将通过相乘转换为点云的参照系对于如上所述的法向量,x和y将乘以垂直于该法线向量E的向量。要获得这些,请选择垂直于法线向量的任意单位向量(对于x轴),并将其与法线向量交叉以找到y轴。

这个解释的第二部分相当简洁,但第一部分可能更重要。

<强>更新

因此,描述如何进行锥体的最佳方法可能是从圆柱体开始,这是上述线条的延伸。在线的情况下,存在嵌入3D空间中的(一部分)一维流形。那就是我们有一个变量,我们循环添加点。圆柱是一个二维物体,所以我们必须环绕两个维度:角度和距离。在线的情况下,我们已经有距离。所以上面的循环现在看起来像:

for(double distfromstart=0.0;distfromstart<LINE_LENGTH;distfromstart+=DISTANCE_INCREMENT){
   for(double angle=0.0;angle<2*M_PI;angle+=M_PI/8){
      //calculate coordinates of point and add to cloud
   }
}

现在为了计算新点的坐标,我们已经在线上有点,现在我们只需要将它添加到矢量中,使其在角度的适当方向上远离线。假设我们的圆柱体的半径将是0.1,并且假设我们已经垂直于平面法线计算的标准正交基础(我们将在后面看到如何计算)是perpendicular_1和{{1} (也就是说,两个矢量彼此垂直,长度为1,也垂直于矢量(NORMAL_X,NORMAL_Y,NORMAL_Z)):

perpendicular_2

实际上,这是一个向量求和,如果我们将操作写成向量,它看起来像:

//calculate coordinates of point and add to cloud
pnt_on_cylinder.x = pnt_on_line.x + 0.1 * perpendicular_1.x * 0.1 * cos(angle) + perpendicular_2.x * sin(angle)
pnt_on_cylinder.y = pnt_on_line.y + perpendicular_1.y * 0.1 * cos(angle) + perpendicular_2.y * 0.1 * sin(angle)
pnt_on_cylinder.z = pnt_on_line.z + perpendicular_1.z * 0.1 * cos(angle) + perpendicular_2.z * 0.1 * sin(angle)
my_cloud.points.push_back(pnt_on_cylinder);

现在我说我会谈谈如何计算pnt_on_line+perpendicular_1*cos(angle)+perpendicular_2*sin(angle) perpendicular_1。设K是与(perpendicular_2NORMAL_XNORMAL_Y)不平行的任何单位矢量(这可以通过尝试例如NORMAL_Z然后(1,0,0)来找到)

然后

(0,1,0)

此处perpendicular_1 = K X (NORMAL_X,NORMAL_Y,NORMAL_Z) perpendicular_2 = perpendicular_1 X (NORMAL_X,NORMAL_Y,NORMAL_Z) 是矢量叉积,以上是矢量方程式。另请注意,pnt_on_line的原始计算涉及向量点积和向量求和(我只是为了完整性而写这个)。

如果你可以管理这个,那么通过改变双循环中的几个东西就可以轻松实现锥形:半径只是沿着它的长度变化,直到它在循环结束时为零,而在循环中,distfromstart将不会启动在0。