1

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

4

1 回答 1

1

要生成垂直于平面的线:

你有平面方程。这为您提供了平面法线的方向。如果您使用 PCL 来获取飞机,则在 ModelCoefficients 中。在此处查看详细信息:SampleConsensusModelPerpendicularPlane

第一步是在您提到的点 ( X, Y, Z) 处画一条垂直于法线的线。让 ( NORMAL_X, NORMAL_Y, NORMAL_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_X, NORMAL_Y, NORMAL_Z) 的单位向量(这可以通过尝试例如(1,0,0)then来找到(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 开始。

于 2013-09-24T11:13:38.840 回答