问题
I wanted to ask you if anyone knew how to check if a point was inside a given triangle, on a reference system in space. I am aware that speaking of 2d systems I can obtain this point with the following procedures: To determine if a given point v lies within a given triangle, consider a single vertex, denoted v0, v1 and v2 are the vectors from the other two vertices v0. Expressing the vector from v0 to v in terms of v1 and v2 then gives
v = v0 + av1 + bv2
where a, b are constant. Solve for a, b
a= (det (v v2) - det (v0 v2)) / (det (v1 v2))
b= - (det (v v1) - det (v0 v1)) / (det (v1 v2))
So the point v is inside the triangle if a, b> 0 e a + b <1. I was wondering if there was a similar procedure or not.
After MBo's advice I wrote the following code:
def pointLocatedOnTheTriangularFace(self, point):
vertList = list(self.vertices)
system = []
for i in range(4):
p = vertList[1].coords-vertList[0].coords
q = vertList[2].coords-vertList[0].coords
n = np.cross(p,q)
for i in range(3):
system.append([p[i],q[i],n[i]])
try:
solution = list(np.linalg.solve(system,np.array(point-vertList[0].coords)))
if solution[0] > 0 and solution[1] > 0 and solution[0]+solution[1]<1 and solution[2]==0:
return True
except np.linalg.LinAlgError:
print("The system having the floor {0} {1} {2} with the point {3} does not admit solutions.\n".format(vertList[0].coords,vertList[1].coords,vertList[2].coords,point))
v = vertList.pop(0)
vertList.append(v)
return False
I am working with tetrahedra, and the triangles that interest me are the faces of the tetrahedron. I state that it does not work but I can not understand why. Can anyone tell me what am I doing wrong? I changed the code in the following way and it seems to work.
def pointLocatedOnTheTriangularFace(self, point):
vertList = list(self.vertices)
system = []
for i in range(4):
r = point-vertList[0].coords
p = vertList[1].coords-vertList[0].coords
q = vertList[2].coords-vertList[0].coords
n = np.cross(p,q)
if np.inner(r,n) == 0:
system = [[p[0],q[0]],[p[1],q[1]]]
try:
solution = list(np.linalg.solve(system,np.array([r[0],r[1]])))
if solution[0] > 0 and solution[1] > 0 and solution[0]+solution[1]<1:
return True
except np.linalg.LinAlgError:
print("The system having the floor {0} {1} {2} with the point {3} does not admit solutions.\n".format(vertList[0].coords,vertList[1].coords,vertList[2].coords,point))
v = vertList.pop(0)
vertList.append(v)
return False
With the following tests:
def test_PointPlacedOnTheTriangularFace(self):
tr1Vertices = [vertex([0,4.32978e-17,0.5],1),vertex([-0.433013,0.25,-0.5],2),vertex([-4.32978e-17,-0.5,-0.5],3),vertex([0.433013,0.25,-0.5],4)]
tr1= tetrahedron(tr1Vertices)
point = vertex([0,0,-0.5],1)
self.assertTrue(tr1.pointLocatedOnTheTriangularFace(point.coords), msg="In this test the point is inside the face")
def test_PointNotPlacedLocatedOnTheTriangularFace(self):
tr1Vertices = [vertex([0,4.32978e-17,0.5],1),vertex([-0.433013,0.25,-0.5],2),vertex([-4.32978e-17,-0.5,-0.5],3),vertex([0.433013,0.25,-0.5],4)]
tr1= tetrahedron(tr1Vertices)
point = vertex([1,0,-0.5],1)
self.assertFalse(tr1.pointLocatedOnTheTriangularFace(point.coords), msg="In this test the point is outside the face")
If anyone has any advice for me I will surely treasure it. Thanks.
回答1:
Described 2D approach is essentially decomposition of vector r = v-v0
by basis vectors p=v1-v0
and q=v2-v0
.
In 3D you can decompose vector r
by vectors p
, q
and n = p x q
(where x
denotes vector product operation)
If resulting coefficients a,b,c
fulfill limits a, b > 0, a + b < 1, c=0
, then point v
lies in triangle plane inside it.
For decomposition solve this linear system for unknowns a,b,c
:
rx = a * px + b * qx + c * nx
ry = a * py + b * qy + c * ny
rz = a * pz + b * qz + c * nz
Alternative approach - check that dot product r.dot.n
is zero - in this case point lies in the plane, coefficient с
is zero, and you can solve simplified system for a
and b
choosing a pair of equations and excluding the third summand (same method as in 2D)
来源:https://stackoverflow.com/questions/65023887/point-inside-a-triangle