Beispiel #1
0
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
Beispiel #2
0
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
Beispiel #3
0
    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)
Beispiel #4
0
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
Beispiel #5
0
 def in_triangle(self, triangle):
     return is_point_in_triangle(self, triangle)