如何在 PCL 中绘制平面的法线



我有一个平面方程,描述了3D中属于平面的点以及法线X,Y,Z的原点。这应该足以生成类似 3D 箭头的东西。在 pcl 中,这可以通过查看器实现,但我想将这些 3D 点实际存储在云中。那么如何生成它们呢?顶部有锥体的圆柱体?

生成垂直于平面的直线:

你有平面方程。这为您提供了平面法线的方向。如果使用 PCL 获取平面,则在模型系数中。请参阅此处的详细信息:样本共识模型垂直平面

第一步是在你提到的点(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_1perpendicular_2(即,两个彼此垂直的向量,长度为 1,也垂直于向量 (NORMAL_X,NORMAL_Y,NORMAL_Z)):

//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_1perpendicular_2.设 K 是任何不平行于 (NORMAL_XNORMAL_YNORMAL_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)

这里X是向量叉积,上面是向量方程。另请注意,pnt_on_line的原始计算涉及向量点积和向量求和(我只是为了阐述的完整性而写这个)。

如果你能做到这一点,那么只需在双循环中改变几件事,圆锥就很容易了:半径只是沿着它的长度变化,直到它在循环结束时为零,而在循环中,distfromstart 不会从 0 开始。

最新更新