Esempio n. 1
0
def intersection_line_segment(line, segment, tol=1e-6):
    """Compute the intersection of a line and a segment.

    Parameters
    ----------
    line : tuple
        Two points defining a line.
    segment : tuple
        Two points defining a line segment.
    tol : float, optional
        A tolerance for membership verification.
        Default is ``1e-6``.

    Returns
    -------
    tuple
        Two intersection points.

        If the line and segment intersect and the second intersection point lies on the segment, the two points are identical.
        If the line and segment are skew and the second apparent intersection point lies on the segment, the two points are different.

        In all other cases the return is `(None, None)`.

    """
    x1, x2 = intersection_line_line(line, segment, tol=tol)

    if not x1 or not x2:
        return None, None

    if not is_point_on_segment(x2, segment, tol=tol):
        return None, None

    return x1, x2
Esempio n. 2
0
def intersection_line_segment(line, segment, tol=1e-6):
    """Compute the intersection of a line and a segment.

    Parameters
    ----------
    line : [point, point] | :class:`compas.geometry.Line`
        Two points defining a line.
    segment : [point, point] | :class:`compas.geometry.Line`
        Two points defining a line segment.
    tol : float, optional
        A tolerance for membership verification.

    Returns
    -------
    tuple[[float, float, float], [float, float, float]] | tuple[None, None]
        Two intersection points.
        If the line and segment intersect and the second intersection point lies on the segment, the two points are identical.
        If the line and segment are skew and the second apparent intersection point lies on the segment, the two points are different.
        In all other cases there are no intersection points.

    """
    x1, x2 = intersection_line_line(line, segment, tol=tol)

    if not x1 or not x2:
        return None, None

    if not is_point_on_segment(x2, segment, tol=tol):
        return None, None

    return x1, x2
Esempio n. 3
0
def is_polygon_self_intersecting(polygon):
    """Computes if as polygon is self intersecting in plane, or self overlapping in space.

    Parameters
    ----------
    polygon : list of lists
        A list of polygon point coordinates.

    Returns
    -------
    bool_1
        ``True`` if self overlapping.
        ``False`` otherwise.
    bool_2
        ``True`` if self intersecting.
        ``False`` otherwise.

    """
    edges = []
    for i in range(-1, len(polygon) - 1):
        edges.append((i, i + 1))

    for u1, v1 in edges:
        for u2, v2 in edges:
            if u1 == u2 or v1 == v2 or u1 == v2 or u2 == v1:
                continue
            else:
                a = polygon[u1]
                b = polygon[v1]
                c = polygon[u2]
                d = polygon[v2]

                int_1, int_2 = intersection_line_line((a, b), (c, d))

                if int_1 or int_2:
                    if distance_point_point(int_1, int_2) > 0:
                        overlapping = True
                    if is_point_on_segment(int_1,
                                           (a, b)) or is_point_on_segment(
                                               int_2, (c, d)):
                        intersecting = True

    return overlapping, intersecting
Esempio n. 4
0
    def on_segment(self, segment):
        """Determine if the point lies on the given segment.

        Parameters
        ----------
        segment : :class:`compas.geometry.Line` or tuple of points.
            The segment.

        Returns
        -------
        bool
            True, if the point lies on the segment.
            False, otherwise.

        Examples
        --------
        >>> from compas.geometry import Line
        >>> line = Line(Point(1.0, 0.0, 0.0), Point(1.0, 1.0, 0.0))
        >>> point = line.point(1.5)
        >>> point.on_segment(line)
        False
        """
        return is_point_on_segment(self, segment)
Esempio n. 5
0
def intersection_segment_segment(ab, cd, tol=1e-6):
    """Compute the intersection of two lines segments.

    Parameters
    ----------
    ab : tuple
        XYZ coordinates of two points defining a line segment.
    cd : tuple
        XYZ coordinates of two points defining another line segment.
    tol : float, optional
        A tolerance for membership verification.
        Default is ``1e-6``.

    Returns
    -------
    tuple
        Two intersection points.

        If the segments intersect and the intersection points lie on the respective segments, the two points are identical.
        If the segments are skew and the apparent intersection points lie on the respective segments, the two points are different.

        In all other cases the return is `(None, None)`.

    Examples
    --------
    The 2 intersection points of intersecting segments are identical.

    >>> s1 = [0, 0, 0], [1, 0, 0]
    >>> s2 = [0, 0, 0], [0, 1, 0]
    >>> intersection_segment_segment(s1, s2)
    ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0])

    Unlike lines, segments don't extend beyond their start and end points.

    >>> s1 = [0, 0, 0], [1, 0, 0]
    >>> s2 = [2, 0, 0], [0, 1, 0]
    >>> intersection_segment_segment(s1, s2)
    (None, None)

    Skew segments have two different intersection points.

    >>> s1 = [0, 0, 0], [1, 0, 0]
    >>> s2 = [0, 0, 1], [0, 1, 1]
    >>> intersection_segment_segment(s1, s2)
    ([0.0, 0.0, 0.0], [0.0, 0.0, 1.0])

    Parallel segments don't intersect.

    >>> s1 = [0, 0, 0], [1, 0, 0]
    >>> s2 = [0, 0, 0], [1, 0, 0]
    >>> intersection_segment_segment(s1, s2)
    (None, None)

    """
    x1, x2 = intersection_line_line(ab, cd, tol=tol)

    if not x1 or not x2:
        return None, None

    if not is_point_on_segment(x1, ab, tol=tol):
        return None, None

    if not is_point_on_segment(x2, cd, tol=tol):
        return None, None

    return x1, x2