Propósito: Recientemente escribí código C++ y encontré algunos algoritmos básicos. Se requiere la intersección de una línea y un plano en el espacio.
Representación vectorial de una línea recta: L : r → = P 0 → + t N 0 → L:\overrightarrow{r}=\overrightarrow{P_0}+t\overrightarrow{N_0}L:r=PAG0+tnorte0;其中P 0 → = ( x 0 y 0 z 0 ) \overrightarrow{P_0}=\begin{pmatrix} x_0 \\ y_0 \\ z_0 \end{pmatrix}PAG0=⎝⎛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}norte0=⎝⎛norteX0nortey0nortez0⎠⎞
La representación vectorial del plano: π : N 1 → T ⋅ X + d 1 = 0 \pi: \overrightarrow{N_1}^T \cdot X+d_1=0Pi:norte1T⋅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}norte1=⎝⎛norteX1nortey1nortez1⎠⎞, ddd es un escalar.
Hay tres situaciones para el punto de intersección de una línea con un plano:
1) En un plano
2) Paralelo a un plano
3)
Intersectando
con un plano Por lo tanto, es necesario determinar si la línea corta al plano. En el espacio tradicional, si un plano y una recta son planos, los vectores capilares de la recta y el plano son perpendiculares. Por lo tanto, al calcular N 0 → \overrightarrow{N_0}norte0y N 1 → \overrightarrow{N_1}norte1ángulo entre. Si es perpendicular a la superficie la recta es paralela al plano.
cos ( θ ) − > norte 0 → T ⋅ norte 1 → cos(\theta)->\overrightarrow{N_0}^T \cdot \overrightarrow{N_1}C o s ( θ ) ->norte0T⋅norte1
Si está cerca de 0 significa que es paralelo.
Lo siguiente introducirá la situación de intersección.Si
el plano y la línea se intersecan, para la línea, solo necesita calcular ttt即可。
L : r → = P 0 → + t N 0 → L:\overrightarrow{r}=\overrightarrow{P_0}+t\overrightarrow{N_0}L:r=PAG0+tnorte0Coloca en la fórmula π : N 1 → T ⋅ X + d 1 = 0 \pi: \overrightarrow{N_1}^T \cdot X+d_1=0Pi:norte1T⋅X+d1=0得到如下:
norte 1 → T ⋅ ( PAGS 0 → + t norte 0 → ) + re 1 = 0 = > norte 1 → T ⋅ PAGS 0 → + t norte 1 → T ⋅ norte 0 → + re 1 = 0 t = ( - re 1 - norte 1 → T ⋅ PAGS 0 → ) / norte 1 → T ⋅ norte 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}norte1T⋅(PAG0+tnorte0)+d1=0=>norte1T⋅PAG0+tnorte1T⋅norte0+d1=0t=( - re1−norte1T⋅PAG0) /norte1T⋅norte0
Porque el vector P 0 → \overrightarrow{P_0}PAG0, norte 0 → \overrightarrow{N_0}norte0, norte 1 → \overrightarrow{N_1}norte1son todos conocidos, por lo que t = tnt=t_n que se puede encontrart=tn.
Trae para obtener
rn → = P 0 → + tn N 0 → \overrightarrow{r_n}=\overrightarrow{P_0}+t_n\overrightarrow{N_0}rn=PAG0+tnnorte0
Basado en la fórmula anterior, el código fuente es el siguiente:
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;
}