3D の平面に属する点と、法線 X、Y、Z の原点を記述する平面方程式があります。これは、3D 矢印のようなものを生成するのに十分なはずです。pcl では、これはビューアを介して可能ですが、実際にはこれらの 3D ポイントをクラウド内に保存したいと考えています。それらを生成する方法は?円錐が上にある円柱?
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 はこの法線ベクトルに垂直なベクトルに乗算されます。これらを取得するには、(x 軸の) 法線ベクトルに垂直な任意の単位ベクトルを選択し、それを法線ベクトルと交差させて y 軸を見つけます。
この説明の 2 番目の部分はかなり簡潔ですが、最初の部分の方が重要かもしれません。
アップデート
したがって、コーンの作成方法を説明する最良の方法は、上記の線の延長である円柱から始めることです。線の場合、3D 空間に埋め込まれた 1 次元多様体 (の一部) があります。つまり、ポイントの追加をループする 1 つの変数があります。円柱は 2 次元のオブジェクトなので、角度と距離の 2 次元をループする必要があります。線の場合、距離はすでにわかっています。したがって、上記のループは次のようになります。
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
and perpendicular_2
(つまり、それぞれに垂直な 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_1
ここで、 との計算方法について話すと言いperpendicular_2
ました。NORMAL_X
K を ( , NORMAL_Y
, ) に平行でない任意の単位ベクトルとする(これは、たとえばthenNORMAL_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 から始まりません。