Objectif : J'ai récemment écrit du code C++ et rencontré quelques algorithmes de base. L'intersection d'une ligne et d'un plan dans l'espace est requise.
Représentation vectorielle d'une droite : 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=⎝⎛X0y0z0⎠⎞, 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=⎝⎛nX0ny0nz0⎠⎞
La représentation vectorielle du plan : π : N 1 → T ⋅ X + d 1 = 0 \pi: \overrightarrow{N_1}^T \cdot X+d_1=0Pi:N1J⋅X+d1=0;使用N 1 → = ( nx 1 ny 1 nz 1 ) \overrightarrow{N_1}=\begin{pmatrix} n_x^1 \\ n_y^1 \\ n_z^1 \end{pmatrix}N1=⎝⎛nX1ny1nz1⎠⎞, jjd est un scalaire.
Il existe trois situations pour le point d'intersection d'une droite avec un plan :
1) Sur un plan
2) Parallèle à un plan
3)
Intersection
avec un plan Par conséquent, il est nécessaire de déterminer si la ligne coupe le plan. Dans l'espace traditionnel, si un plan et une droite sont des plans, les vecteurs capillaires de la droite et du plan sont perpendiculaires. Donc, en calculant N 0 → \overrightarrow{N_0}N0et N 1 → \overrightarrow{N_1}N1angle entre. Si elle est perpendiculaire à la surface, la droite est parallèle au plan.
cos ( θ ) − > N 0 → T ⋅ N 1 → cos(\theta)->\overrightarrow{N_0}^T \cdot \overrightarrow{N_1}c o s ( θ ) ->N0J⋅N1
S'il est proche de 0, cela signifie qu'il est parallèle.
Ce qui suit présentera la situation d'intersection.
Si le plan et la ligne se croisent, pour la ligne, il suffit de calculer ttt即可。
L : r → = P 0 → + t N 0 → L:\overrightarrow{r}=\overrightarrow{P_0}+t\overrightarrow{N_0}L:r=P0+tN0Mettez dans la formule π : N 1 → T ⋅ X + d 1 = 0 \pi: \overrightarrow{N_1}^T \cdot X+d_1=0Pi:N1J⋅X+d1=0得到如下 :
N 1 → T ⋅ ( P 0 → + t N 0 → ) + ré 1 = 0 = > N 1 → T ⋅ P 0 → + t N 1 → T ⋅ N 0 → + ré 1 = 0 t = ( − ré 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}N1J⋅(P0+tN0)+d1=0=>N1J⋅P0+tN1J⋅N0+d1=0t=( -d _1−N1J⋅P0) /N1J⋅N0
Parce que le vecteur P 0 → \overrightarrow{P_0}P0, N 0 → \overrightarrow{N_0}N0, N 1 → \overrightarrow{N_1}N1sont tous connus, donc les t = tnt=t_n que l'on peut trouvert=tn.
Amenez pour obtenir
rn → = P 0 → + tn N 0 → \overrightarrow{r_n}=\overrightarrow{P_0}+t_n\overrightarrow{N_0}rn=P0+tnN0
Basé sur la formule ci-dessus, le code source est le suivant :
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;
}