def intersection_line_triangle(line, triangle, tol=1e-6): """Computes the intersection point of a line (ray) and a triangle based on the Moeller Trumbore intersection algorithm Parameters ---------- line : tuple Two points defining the line. triangle : list of list of float XYZ coordinates of the triangle corners. tol : float, optional A tolerance for membership verification. Default is ``1e-6``. Returns ------- point or None """ a, b, c = triangle ab = subtract_vectors(b, a) ac = subtract_vectors(c, a) n = cross_vectors(ab, ac) plane = a, n x = intersection_line_plane(line, plane, tol=tol) if x: if is_point_in_triangle(x, triangle): return x
def intersection_line_triangle(line, triangle, tol=1e-6): """Computes the intersection point of a line (ray) and a triangle based on the Moeller Trumbore intersection algorithm Parameters ---------- line : [point, point] | :class:`compas.geometry.Line` Two points defining the line. triangle : [point, point, point] XYZ coordinates of the triangle corners. tol : float, optional A tolerance for membership verification. Returns ------- [float, float, float] | None The intersection point between the line and the triangle, or None if the line and the plane are parallel. """ a, b, c = triangle ab = subtract_vectors(b, a) ac = subtract_vectors(c, a) n = cross_vectors(ab, ac) plane = a, n x = intersection_line_plane(line, plane, tol=tol) if x: if is_point_in_triangle(x, triangle): return x
def in_triangle(self, triangle): """Determine if the point lies inside the given triangle. Parameters ---------- triangle : :class:`compas.geometry.Polygon` or list of three points. The triangle. Returns ------- bool True, if the point lies in the triangle. False, otherwise. Examples -------- >>> from compas.geometry import Polygon >>> tri = Polygon([Point(0.0, 0.0, 0.0), Point(1.0, 0.0, 0.0), Point(0.5, 1.0, 0.0)]) >>> point = Point(0.5, 0.5, 0.0) >>> point.in_triangle(tri) True """ return is_point_in_triangle(self, triangle)
def _find_closest_component(point, vertices, triangles, closest_tris, closest_vi): distance = None projection = None component = None for tri in closest_tris: # the triangle to process triangle = triangles[tri] # the local triangle frame o, A = _triangle_xform(triangle) # local coordinates b = point - o p = solve(A, b.T).T b = triangle - o t = solve(A, b.T).T # find closest component of triangle # compute distance to closest component if is_point_in_triangle(p, t): p[2] = 0 xyz = A.dot(p[:, None]).T + o distance = 0 # why to list? projection = xyz[0].tolist() component = 'face', tri break if _is_point_in_edgezone(p, t[0], t[1]): rst = _compute_point_on_segment(p, t[0], t[1]) xyz = A.dot(rst.T).T + o d = sqrt(sum((rst - p[None, :])**2)) if distance is None or d < distance: distance = d # why to list? projection = xyz[0].tolist() component = 'edge', (None, None) elif _is_point_in_edgezone(p, t[1], t[2]): rst = _compute_point_on_segment(p, t[1], t[2]) xyz = A.dot(rst.T).T + o d = sqrt(sum((rst - p[None, :])**2)) if distance is None or d < distance: distance = d # why to list? projection = xyz[0].tolist() component = 'edge', (None, None) elif _is_point_in_edgezone(p, t[2], t[0]): rst = _compute_point_on_segment(p, t[2], t[0]) xyz = A.dot(rst.T).T + o d = sqrt(sum((rst - p[None, :])**2)) if distance is None or d < distance: distance = d # why to list? projection = xyz[0].tolist() component = 'edge', (None, None) else: xyz = vertices[closest_vi] d = sqrt(sum((xyz - point)**2)) if distance is None or d < distance: distance = d # why to list? projection = xyz.tolist() component = 'vertex', closest_vi return distance, projection, component
def in_triangle(self, triangle): return is_point_in_triangle(self, triangle)