I need an algorithm (3D), which would determine if point belongs to a triangle. And also if it does I want to know the distance between some point in triangle and a another poin
This can be split into 2 problems.
Withe the example below, you can do a check, for eg:
if (isect_point_tri_prism_v3(p, v1, v2, v2) and
(dist_signed_squared_point_tri_plane_v3(p, v1, v2, v2) < (eps * eps)):
# do stuff
... where eps
is the distance to consider points 'on the triangle'.
This code example uses functional Python so should be easy to move to other languages, it uses only simple arithmetic, no sqrt
or complex functions.
# ----------------
# helper functions
def sub_v3v3(v0, v1):
return (v0[0] - v1[0], v0[1] - v1[1], v0[2] - v1[2])
def dot_v3v3(v0, v1):
return ((v0[0] * v1[0]) + (v0[1] * v1[1]) + (v0[2] * v1[2]))
def cross_v3v3(v0, v1):
return ((v0[1] * v1[2]) - (v0[2] * v1[1]),
(v0[2] * v1[0]) - (v0[0] * v1[2]),
(v0[0] * v1[1]) - (v0[1] * v1[0]))
def closest_to_line_v3(p, l0, l1):
"""
Return the closest point to p on the line defined by (l0, l1)
"""
u = sub_v3v3(l1, l0)
h = sub_v3v3(p, l0)
l = dot_v3v3(u, h) / dot_v3v3(u, u)
return (l0[0] + u[0] * l,
l0[1] + u[1] * l,
l0[2] + u[2] * l)
def point_in_slice_v3(p, v, l0, l1):
cp = closest_to_line_v3(v, l0, l1)
q = sub_v3v3(cp, v)
rp = sub_v3v3(p, v)
# For languages which allow divide-by-zero,
# this is taken into account and returns false.
h = dot_v3v3(q, rp) / dot_v3v3(q, q)
return (h >= 0.0 and h <= 1.0)
# --------------
# main functions
def isect_point_tri_prism_v3(p, v0, v1, v2):
"""
Return True when the point is inside the triangular prism.
Zero area triangles always return false.
"""
return (point_in_slice_v3(p, v0, v1, v2) and
point_in_slice_v3(p, v1, v2, v0) and
point_in_slice_v3(p, v2, v0, v1))
def dist_signed_squared_point_tri_plane_v3(p, v0, v1, v2):
"""
Return the squared distance to the triangle,
positive values are 'in-front' of the triangle, negative behind.
(using CCW coordinate system - OpenGL).
Remove the 'copysign' call for the non-signed version.
(if you don't need to know which side of the triangle the point is on).
"""
from math import copysign
n = cross_v3v3(sub_v3v3(v2, v1), sub_v3v3(v0, v1))
rp = sub_v3v3(p, v1)
len_sq = dot_v3v3(n, n)
side = dot_v3v3(rp, n)
fac = side / len_sq
return copysign(len_sq * (fac * fac), side)