Purpose: I recently wrote C++ code and encountered some basic algorithms. The intersection of a line and a plane in space is required.
Vector representation of a straight line: 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 → = ( n x 0 n y 0 n z 0 ) \overrightarrow{N_0}=\begin{pmatrix} n_x^0 \\ n_y^0 \\ n_z^0 \end{pmatrix} N0=⎝⎛nx0ny0nz0⎠⎞
The vector representation of the plane: π : N 1 → T ⋅ X + d 1 = 0 \pi: \overrightarrow{N_1}^T \cdot X+d_1=0Pi:N1T⋅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⎠⎞, d d d is a scalar.
There are three situations for the intersection point of a line to a plane:
1) On a plane
2) Parallel to a plane
3)
Intersecting
with a plane Therefore, it is necessary to determine whether the line intersects the plane. In traditional space, if a plane and a straight line are planes, the hair vectors of the straight line and the plane are perpendicular. Therefore, by calculating N 0 → \overrightarrow{N_0}N0and N 1 → \overrightarrow{N_1}N1angle between. If it is perpendicular to the surface the line is parallel to the plane.
cos ( θ ) − > N 0 → T ⋅ N 1 → cos(\theta)->\overrightarrow{N_0}^T \cdot \overrightarrow{N_1}c o s ( θ ) −>N0T⋅N1
If it's close to 0 it means it's parallel.
The following will introduce the intersection situation.
If the plane and the line intersect, for the line, only need to calculate ttt即可。
L : r → = P 0 → + t N 0 → L:\overrightarrow{r}=\overrightarrow{P_0}+t\overrightarrow{N_0} L:r=P0+tN0Put into the formula π : N 1 → T ⋅ X + d 1 = 0 \pi: \overrightarrow{N_1}^T \cdot X+d_1=0Pi:N1T⋅X+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} N1T⋅(P0+tN0)+d1=0=>N1T⋅P0+tN1T⋅N0+d1=0t=(−d1−N1T⋅P0)/N1T⋅N0
Because the vector P 0 → \overrightarrow{P_0}P0, N 0 → \overrightarrow{N_0} N0, N 1 → \overrightarrow{N_1} N1are all known, so the t = tnt=t_n that can be foundt=tn.
Bring in to get
rn → = P 0 → + tn N 0 → \overrightarrow{r_n}=\overrightarrow{P_0}+t_n\overrightarrow{N_0}rn=P0+tnN0
Based on the above formula, the source code is as follows:
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;
}