Proof and source code of distance calculation from space vertex to plane

Purpose: I recently wrote C++ code and encountered some basic algorithms. Such as calculating the distance from a vertex to a plane.

The previous article has introduced the plane and its mathematical expression:
geometric expression P lane PlaneP l a n e : plane normal vectorN = ( n 0 n 1 n 2 ) N=\begin{pmatrix} n_0 \\ n_1 \\ n_2 \end{pmatrix}N=n0n1n2, and a vertex P 0 = ( x 0 y 0 z 0 ) P_0=\begin{pmatrix} x_0 \\ y_0 \\ z_0 \end{pmatrix}P0=x0y0z0
Vertex expression: P 1 = ( x 1 y 1 z 1 ) P_1=\begin{pmatrix} x_1 \\ y_1 \\ z_1 \end{pmatrix}P1=x1y1z1

Calculate P 1 P_1P1To plane P lane PlanePlane distance . _ _ _
P lane PlaneThe expression of P l a n e can be transformed inton 0 ( x − x 0 ) + n 1 ( y − y 0 ) + n 2 ( z − z 0 ) = 0 n_0(x-x_0)+n_1(y-y_0 )+n_2(z-z_0)=0n0(xx0)+n1(yy0)+n2(zz0)=0 , calculaten 0 x + n 1 y + n 2 z + d = 0 n_0x+n_1y+n_2z+d=0n0x+n1y+n2z+d=0其中 d = − n 0 x 0 − n 1 y 0 − n 2 z 0 = − N T ⋅ P 0 d=-n_0x_0-n_1y_0-n_2z_0=-N^T \cdot P_0 d=n0x0n1y0n2z0=NTP0

The derivation formula is as follows:
insert image description here

Calculate the red vertex P 1 P_1P1To the blue plane P lane PlanePlane distance . _ _ _ The yellow vertex is a point P 0 P_0on the planeP0. Vertex-to-plane distance definition: the distance of its point perpendicular to the plane (indicated by the gray line segment in the figure).

Based on the vertical triangle algorithm, the length of the gray line segment is dist distdist
d i s t = ∥ P 0 − P 1 ∥ ⋅ c o s ( θ )    ( 1 ) dist=\lVert P_0-P_1 \rVert \cdot cos(\theta) \space \space (1) dist=P0P1c o s ( θ ) ( 1 )  
increaseθ \thetaθ are two vectorsP 0 P 1 P_0P_1P0P1and plane normal vector NNFor example ,
cos ( θ ) = ∣ NT ⋅ ( P 0 − P 1 ) ∣ ∥ P 0 − P 1 ∥ ⋅ ∥ N ∥ ( 2 ) cos(\theta) = \cfrac {|N^T \cdot (P_0-P_1)|}{\lVert P_0-P_1 \rVert \cdot \lVert N \rVert} \space \space(2)c o s ( i )=P0P1NNT(P0P1)  ( 2 )
Substituting formula (2) into formula (1) can be obtained as follows:
dist = ∣ NT ⋅ ( P 0 − P 1 ) ∣ ∥ N ∥ ( 3 ) dist=\cfrac {|N^T \cdot (P_0 -P_1)|}{ \lVert N \rVert} \space \space (3)dist=NNT(P0P1)  ( 3 )
Put the vectorP 0 = ( x 0 y 0 z 0 ) P_0=\begin{pmatrix} x_0 \\ y_0 \\ z_0 \end{pmatrix}P0=x0y0z0, P 1 = ( x 1 y 1 z 1 ) P_1=\begin{pmatrix} x_1 \\ y_1 \\ z_1 \end{pmatrix} P1=x1y1z1, N = ( n 0 n 1 n 2 ) N=\begin{pmatrix} n_0 \\ n_1 \\ n_2 \end{pmatrix} N=n0n1n2The equation
dist = ∣ NT ⋅ P 0 − NT ⋅ P 1 ∣ ∥ N ∥ = ∣ − d − NT ⋅ P 1 ∣ ∥ N ∥ = ∣ NT ⋅ P 1 + d ∣ ∥ N ∥ ( 4 ) dist=\cfrac {|N^T \cdot P_0 - N^T \cdot P_1|}{ \lVert N \rVert}=\cfrac {|-d - N^T \cdot P_1|}{ \lVert N \rVert} =\cfrac {|N^T \cdot P_1 + d|}{ \lVert N \rVert} \space \space (4)dist=NNTP0NTP1=NdNTP1=NNTP1+d  (4)

The above vector form can be rewritten into an algebraic form:
dist = ∣ n 0 x 1 + n 1 y 1 + n 2 z 1 + d ∣ n 0 2 + n 1 2 + n 2 2 ( 5 ) dist = \cfrac {|n_0x_1 + n_1y_1+n_2z_1+d|}{\sqrt{n_0^2+n_1^2+n_2^2}} \space \space (5)dist=n02+n12+n22 n0x1+n1y1+n2z1+d  (5)

The source code is as follows, it is written based on vector mode. It requires you to configure the Eigen library:

float Pnt3d2PlaneDist(Eigen::Vector4f& fn, Eigen::Vector3f& pnt)
	{
    
    
		Eigen::Vector3f n = Eigen::Vector3f(fn[0], fn[1], fn[2]);
		float sd = n.norm();
		if (sd < 1e-8)
			return std::numeric_limits<float>::max();
		float sb = std::abs(n.dot(pnt) + fn[3]);
		float d = sb / sd;
		return d;
	}

See the website for details: https://mathinsight.org/distance_point_plane

Guess you like

Origin blog.csdn.net/weixin_43851636/article/details/125334394