空間線から平面への交点の計算証明とソースコード

目的: 最近 C++ コードを作成し、いくつかの基本的なアルゴリズムに遭遇しました。空間内の線と平面の交差が必要です。

直線のベクトル表現: L : r → = P 0 → + t N 0 → L:\overrightarrow{r}=\overrightarrow{P_0}+t\overrightarrow{N_0}L:r =P0 +tN0 ;其中P 0 → = ( x 0 y 0 z 0 ) \overrightarrow{P_0}=\begin{pmatrix} x_0 \\ y_0 \\ z_0 \end{pmatrix}P0 =バツ0y0z0, N 0 → = ( nx 0 ny 0 nz 0 ) \overrightarrow{N_0}=\begin{pmatrix} n_x^0 \\ n_y^0 \\ n_z^0 \end{pmatrix}N0 =nバツ0ny0nz0
平面のベクトル表現: π : N 1 → T ⋅ X + d 1 = 0 \pi: \overrightarrow{N_1}^T \cdot X+d_1=0円周率:N1 Tバツ+d1=0N 1 を使用 → = ( nx 1 ny 1 nz 1 ) \overrightarrow{N_1}=\begin{pmatrix} n_x^1 \\ n_y^1 \\ n_z^1 \end{pmatrix}N1 =nバツ1ny1nz1dddはスカラーです。

線と平面の交点には 3 つの状況があります:
1) 平面上
2) 平面に平行
3)
平面と
交差
ここに画像の説明を挿入
したがって、線が平面と交差するかどうかを判断する必要があります。従来の空間では、平面と直線が平面であれば、直線と平面のヘア ベクトルは垂直になります。したがって、N 0 → \overrightarrow{N_0}を計算すると、N0 そしてN 1 → \overrightarrow{N_1}N1 間の角度。線が表面に対して垂直であれば、線は平面に対して平行になります。
cos ( θ ) − > N 0 → T ⋅ N 1 → cos(\theta)->\overrightarrow{N_0}^T \cdot \overrightarrow{N_1}c o s ( θ ) >N0 TN1
0 に近い場合は平行であることを意味します。

以下に交差の場合を紹介します
平面と直線が交差する場合、直線についてはttを計算するだけで済みますL : r → = P 0 → + t N 0 → L:\overrightarrow{r}=\overrightarrow{P_0}+t\overrightarrow{ N_0 }
L:r =P0 +tN0 π : N 1 → T ⋅ X + d 1 = 0 \pi: \overrightarrow{N_1}^T \cdot X+d_1=0 に代入します。円周率:N1 Tバツ+d1=0結果は以下の通り:
N 1 → T ⋅ ( P 0 → + t N 0 → ) + d 1 = 0 = > N 1 → T ⋅ P 0 → + t N 1 → T ⋅ N 0 → + d 1 = 0 t = ( − d 1 − N 1 → T ⋅ P 0 → ) / N 1 → T ⋅ N 0 → \overrightarrow{N_1}^T \cdot (\overrightarrow{P_0}+t\overrightarrow{N_0})+d_1= 0 \\ =>\overrightarrow{N_1}^T \cdot \overrightarrow{P_0}+t \overrightarrow{N_1}^T \cdot \overrightarrow{N_0}+d_1=0 \\ t=(-d_1 - \overrightarrow{ N_1}^T \cdot \overrightarrow{P_0})/\overrightarrow{N_1}^T \cdot \overrightarrow{N_0}N1 T(P0 +tN0 )+d1=0=>N1 TP0 +tN1 TN0 +d1=0t=( d1N1 TP0 ) /N1 TN0
なぜなら、ベクトルP 0 → \overrightarrow{P_0}P0 N 0 → \overrightarrow{N_0}N0 N 1 → \overrightarrow{N_1}N1 はすべて既知であるため、求められるt = tnt=t_nt=t
を取り込んで
rn → = P 0 → + tn N 0 → \overrightarrow{r_n}=\overrightarrow{P_0}+t_n\overrightarrow{N_0}r =P0 +tN0

上記の式に基づくと、ソース コードは次のようになります。

bool LineRayToPlanePnt(Eigen::Vector3f& o_orign, Eigen::Vector3f& o_dir, Eigen::Vector4f& fn, Eigen::Vector3f& inter_pnt)
	{
    
    
		Eigen::Vector3f N = Eigen::Vector3f(fn[0], fn[1], fn[2]);
		float D = fn[3];
		if (std::abs(o_dir.dot(N)) < 1e-8)
		{
    
    
			return false;
		}
		float t = -(o_orign.dot(N) + D) / (o_dir.dot(N));
		inter_pnt = o_orign + t*o_dir;
	}

おすすめ

転載: blog.csdn.net/weixin_43851636/article/details/125337590