1

I have a triangle with points A, B, C and Point in space (P). How can I get distance from point to plane? I need to calc distance from P to plane, even when my triangle lie far away(or not above to the point, like on picture).

Point and triangle:

Spektre
  • 49,595
  • 11
  • 110
  • 380
  • Do you mean distance to the supporting plane, or shortest distance to the points of the triangle ? –  Mar 15 '19 at 19:26
  • 1
    I’m voting to close this question because it's a math question and not about programming. – Rob Aug 03 '22 at 01:11

4 Answers4

6

I assume you want to compute perpendicular distance between point and plane given 3 points on it forming a triangle. Here vector math approach:

  1. definitions

    let the triangle points be p0,p1,p2 and tested point p.

  2. plane normal

    first we need to obtain plane normal, that is simple vector multiplication of any two non parallel and non zero vectors inside the plane:

    n = cross( p1-p0 , p2-p0 )
    

    and normalize it to unit vector (to simplify stuff):

    n = n/|n|
    
  3. perpendicular distance

    we can exploit dot product for this so just crate a vector going from any point on the plane into your tested point and dot with unit normal ...

    dist = |dot ( p-p0 , n )|
    

    perp. dist

    the last absolute value (on scalar distance) will just get rid of the sign of the result which tells you if the point p is in direction of normal n or in opposite one sometimes such info is wanted so in such case remove the outermost abs value and use polygon winding and cross product operands order to maintain wanted normal direction.

Here (look for [edit2]) you will find the cross , dot and || equations used if needed:

so if I put all together in code like form:

U.x=p1.x-p0.x; V.x=p2.x-p0.x; // basis vectors on the plane
U.y=p1.y-p0.y; V.y=p2.y-p0.y;
U.z=p1.z-p0.z; V.z=p2.z-p0.z;
n.x=(U.y*V.z)-(U.z*V.y);      // plane normal
n.y=(U.z*V.x)-(U.x*V.z);
n.z=(U.x*V.y)-(U.y*V.x);
dist = sqrt( (n.x*n.x) + (n.y*n.y) + (n.z*n.z) ); // normalized
n.x /= dist;
n.y /= dist;
n.z /= dist;
dist = abs( (p.x-p0.x)*n.x + (p.y-p0.y)*n.y + (p.z-p0.z)*n.z ); // your perpendicular distance
Spektre
  • 49,595
  • 11
  • 110
  • 380
  • That's a really thorough response. Kudos. But, I'd keep the sign for `dist`. It's useful. – 3Dave Jan 09 '20 at 01:33
3

If the point is P(x1,y1,z1) and the plane is ax+by+cz+d = 0

Distance

 dist = Abs(a*x1+b*y1+c*z1+d) / Sqrt(a^2+b^2+c^2)
MBo
  • 77,366
  • 5
  • 53
  • 86
Cartik Sharma
  • 69
  • 1
  • 9
  • @MBo yep that is more like it retracting the downvote ... btw the first approach in the link is what my answer is all about – Spektre Mar 16 '19 at 10:02
  • @Spektre Formula with base point does not include d, without it - includes (`d` was added by me some hours ago) – MBo Mar 16 '19 at 10:02
  • @MBo heh must been cached somewhere I can see it in edit history now but just few minutes ago not in the answer itself ... – Spektre Mar 16 '19 at 10:06
1

Converted it to a code:

var a = pos1.y * (pos2.z - pos3.z) + pos2.y * (pos3.z - pos1.z) + pos3.y * (pos1.z - pos2.z);
var b = pos1.z * (pos2.x - pos3.x) + pos2.z * (pos3.x - pos1.x) + pos3.z * (pos1.x - pos2.x); 
var c = pos1.x * (pos2.y - pos3.y) + pos2.x * (pos3.y - pos1.y) + pos3.x * (pos1.y - pos2.y);
var d = -(pos1.x * (pos2.y * pos3.z - pos3.y * pos2.z) + 
        pos2.x * (pos3.y * pos1.z - pos1.y * pos3.z) + 
        pos3.x * (pos1.y * pos2.z - pos2.y * pos1.z));


var dist = Math.Abs(a * point.x + b * point.y + c * point.z + d) / Math.Sqrt(a * a + b * b + c * c);

It works! Thanks!

Spektre
  • 49,595
  • 11
  • 110
  • 380
1

Just a precision, there is a double sign exchange in the last response. In var d, there is no - and to access the distance one should compute:

var dist = Math.Abs(a * point.x + b * point.y + c * point.z - d) / Math.Sqrt(a * a + b * b + c * c);

Changes nothing to the output, but if you use the plane equation afterwards it is important

svyat1s
  • 868
  • 9
  • 12
  • 21