Пример #1
0
def is_intersection_line_line(l1, l2, tol=1e-6):
    """Verifies if two lines intersect.

    Parameters
    ----------
    l1 : [point, point] | :class:`compas.geometry.Line`
        A line.
    l2 : [point, point] | :class:`compas.geometry.Line`
        A line.
    tol : float, optional
        A tolerance for intersection verification.

    Returns
    --------
    bool
        True if the lines intersect in one point.
        False if the lines are skew, parallel or lie on top of each other.

    """
    a, b = l1
    c, d = l2

    e1 = normalize_vector(subtract_vectors(b, a))
    e2 = normalize_vector(subtract_vectors(d, c))

    # check for parallel lines
    if abs(dot_vectors(e1, e2)) > 1.0 - tol:
        return False

    # check for intersection
    if abs(dot_vectors(cross_vectors(e1, e2), subtract_vectors(c, a))) < tol:
        return True
    return False
Пример #2
0
def closest_point_on_line(point, line):
    """Computes closest point on line to a given point.

    Parameters
    ----------
    point : [float, float, float] | :class:`compas.geometry.Point`
        XYZ coordinates.
    line : [point, point] | :class:`compas.geometry.Line`
        Two points defining the line.

    Returns
    -------
    [float, float, float]
        XYZ coordinates of closest point.

    Examples
    --------
    >>>

    See Also
    --------
    :func:`basic.transformations.project_point_line`

    """
    a, b = line
    ab = subtract_vectors(b, a)
    ap = subtract_vectors(point, a)
    c = vector_component(ap, ab)
    return add_vectors(a, c)
Пример #3
0
def distance_point_line_sqrd(point, line):
    """Compute the squared distance between a point and a line.

    Parameters
    ----------
    point : sequence of float
        XYZ coordinates of the point.
    line : list, tuple
        Line defined by two points.

    Returns
    -------
    float
        The squared distance between the point and the line.

    Notes
    -----
    For more info, see [1]_.

    References
    ----------
    .. [1] Wikipedia. *Distance from a point to a line*.
           Available at: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line.

    """
    a, b = line
    ab = subtract_vectors(b, a)
    pa = subtract_vectors(a, point)
    pb = subtract_vectors(b, point)
    length = length_vector_sqrd(cross_vectors(pa, pb))
    length_ab = length_vector_sqrd(ab)
    return length / length_ab
Пример #4
0
def angle_points(a, b, c, deg=False):
    r"""Compute the smallest angle between the vectors defined by three points.

    Parameters
    ----------
    a : sequence of float
        XYZ coordinates.
    b : sequence of float
        XYZ coordinates.
    c : sequence of float
        XYZ coordinates.
    deg : boolean
        returns angle in degrees if True

    Returns
    -------
    float
        The smallest angle between the vectors in radians (in degrees if deg == True).
        The angle is always positive.

    Notes
    -----
    The vectors are defined in the following way

    .. math::

        \mathbf{u} = \mathbf{b} - \mathbf{a} \\
        \mathbf{v} = \mathbf{c} - \mathbf{a}

    Z components may be provided, but are simply ignored.

    """
    u = subtract_vectors(b, a)
    v = subtract_vectors(c, a)
    return angle_vectors(u, v, deg)
Пример #5
0
def normal_triangle(triangle, unitized=True):
    """Compute the normal vector of a triangle.

    Parameters
    ----------
    triangle : list of list
        A list of triangle point coordinates.

    Returns
    -------
    list
        The normal vector.

    Raises
    ------
    ValueError
        If the triangle does not have three vertices.

    """
    assert len(triangle) == 3, "Three points are required."
    a, b, c = triangle
    ab = subtract_vectors(b, a)
    ac = subtract_vectors(c, a)
    n = cross_vectors(ab, ac)
    if not unitized:
        return n
    lvec = 1 / length_vector(n)
    return [lvec * n[0], lvec * n[1], lvec * n[2]]
Пример #6
0
def closest_point_on_line(point, line):
    """Computes closest point on line to a given point.

    Parameters
    ----------
    point : sequence of float
        XYZ coordinates.
    line : tuple
        Two points defining the line.

    Returns
    -------
    list
        XYZ coordinates of closest point.

    Examples
    --------
    >>>

    See Also
    --------
    :func:`basic.transformations.project_point_line`

    """
    a, b = line
    ab = subtract_vectors(b, a)
    ap = subtract_vectors(point, a)
    c = vector_component(ap, ab)
    return add_vectors(a, c)
Пример #7
0
def is_intersection_line_line(l1, l2, tol=1e-6):
    """Verifies if two lines intersect.

    Parameters
    ----------
    l1 : tuple
        A sequence of XYZ coordinates of two 3D points representing two points on the line.
    l2 : tuple
        A sequence of XYZ coordinates of two 3D points representing two points on the line.
    tol : float, optional
        A tolerance for intersection verification. Default is ``1e-6``.

    Returns
    --------
    bool
        ``True``if the lines intersect in one point.
        ``False`` if the lines are skew, parallel or lie on top of each other.
    """
    a, b = l1
    c, d = l2

    e1 = normalize_vector(subtract_vectors(b, a))
    e2 = normalize_vector(subtract_vectors(d, c))

    # check for parallel lines
    if abs(dot_vectors(e1, e2)) > 1.0 - tol:
        return False

    # check for intersection
    d_vector = cross_vectors(e1, e2)
    if dot_vectors(d_vector, subtract_vectors(c, a)) == 0:
        return True

    return False
Пример #8
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 : tuple
        The intersectin point.
    None
        If the intersection does not exist.

    """
    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
Пример #9
0
def is_intersection_segment_plane(segment, plane, tol=1e-6):
    """Determine if a line segment intersects with a plane.

    Parameters
    ----------
    segment : tuple
        Two points defining the segment.
    plane : tuple
        The base point and normal defining the plane.
    tol : float, optional
        A tolerance for intersection verification.
        Default is ``1e-6``.

    Returns
    -------
    bool
        ``True`` if the segment intersects with the plane, ``False`` otherwise.
    """
    pt1 = segment[0]
    pt2 = segment[1]
    p_cent = plane[0]
    p_norm = plane[1]

    v1 = subtract_vectors(pt2, pt1)
    dot = dot_vectors(p_norm, v1)

    if fabs(dot) > tol:
        v2 = subtract_vectors(pt1, p_cent)
        fac = -dot_vectors(p_norm, v2) / dot
        if fac > 0. and fac < 1.:
            return True
        return False
    else:
        return False
Пример #10
0
def is_parallel_line_line(line1, line2, tol=1e-6):
    """Determine if two lines are parallel.

    Parameters
    ----------
    line1 : [point, point] or :class:`compas.geometry.Line`
        Line 1.
    line2 : [point, point] or :class:`compas.geometry.Line`
        Line 2.
    tol : float, optional
        A tolerance for colinearity verification.
        Default is ``1e-6``.

    Returns
    -------
    bool
        ``True`` if the lines are colinear.
        ``False`` otherwise.

    """
    a, b = line1
    c, d = line2
    e1 = normalize_vector(subtract_vectors(b, a))
    e2 = normalize_vector(subtract_vectors(d, c))
    return abs(dot_vectors(e1, e2)) > 1.0 - tol
Пример #11
0
def angle_points(a, b, c, deg=False):
    r"""Compute the smallest angle between the vectors defined by three points.

    Parameters
    ----------
    a : [float, float, float] | :class:`compas.geometry.Point`
        XYZ coordinates.
    b : [float, float, float] | :class:`compas.geometry.Point`
        XYZ coordinates.
    c : [float, float, float] | :class:`compas.geometry.Point`
        XYZ coordinates.
    deg : bool, optional
        If True, returns the angle in degrees.

    Returns
    -------
    float
        The smallest angle in radians (in degrees if ``deg == True``).
        The angle is always positive.

    Notes
    -----
    The vectors are defined in the following way

    .. math::

        \mathbf{u} = \mathbf{b} - \mathbf{a} \\
        \mathbf{v} = \mathbf{c} - \mathbf{a}

    Z components may be provided, but are simply ignored.

    """
    u = subtract_vectors(b, a)
    v = subtract_vectors(c, a)
    return angle_vectors(u, v, deg)
Пример #12
0
def normal_triangle(triangle, unitized=True):
    """Compute the normal vector of a triangle.

    Parameters
    ----------
    triangle : [point, point, point] | :class:`compas.geometry.Polygon`
        A list of triangle point coordinates.
    unitized : bool, optional
        If True, unitize the normal vector.

    Returns
    -------
    [float, float, float]
        The normal vector.

    Raises
    ------
    AssertionError
        If the triangle does not have three vertices.

    """
    assert len(triangle) == 3, "Three points are required."
    a, b, c = triangle
    ab = subtract_vectors(b, a)
    ac = subtract_vectors(c, a)
    n = cross_vectors(ab, ac)
    if not unitized:
        return n
    lvec = 1 / length_vector(n)
    return [lvec * n[0], lvec * n[1], lvec * n[2]]
Пример #13
0
def is_intersection_segment_plane(segment, plane, tol=1e-6):
    """Determine if a line segment intersects with a plane.

    Parameters
    ----------
    segment : [point, point] | :class:`compas.geometry.Line`
        A line segment.
    plane : [point, vector] | :class:`compas.geometry.Plane`
        A plane.
    tol : float, optional
        A tolerance for intersection verification.

    Returns
    -------
    bool
        True if the segment intersects with the plane.
        False otherwise.

    """
    pt1 = segment[0]
    pt2 = segment[1]
    p_cent = plane[0]
    p_norm = plane[1]

    v1 = subtract_vectors(pt2, pt1)
    dot = dot_vectors(p_norm, v1)

    if fabs(dot) > tol:
        v2 = subtract_vectors(pt1, p_cent)
        fac = -dot_vectors(p_norm, v2) / dot
        if fac > 0. and fac < 1.:
            return True
        return False
    else:
        return False
Пример #14
0
 def is_on_same_side(p1, p2, segment):
     a, b = segment
     v = subtract_vectors(b, a)
     c1 = cross_vectors(v, subtract_vectors(p1, a))
     c2 = cross_vectors(v, subtract_vectors(p2, a))
     if dot_vectors(c1, c2) >= 0:
         return True
     return False
Пример #15
0
def normal_polygon(polygon, unitized=True):
    """Compute the normal of a polygon defined by a sequence of points.

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

    Returns
    -------
    list
        The normal vector.

    Raises
    ------
    ValueError
        If less than three points are provided.

    Notes
    -----
    The points in the list should be unique. For example, the first and last
    point in the list should not be the same.

    """
    p = len(polygon)

    assert p > 2, "At least three points required"

    nx = 0
    ny = 0
    nz = 0

    o = centroid_points(polygon)
    a = polygon[-1]
    oa = subtract_vectors(a, o)

    for i in range(p):
        b = polygon[i]
        ob = subtract_vectors(b, o)
        n = cross_vectors(oa, ob)
        oa = ob

        nx += n[0]
        ny += n[1]
        nz += n[2]

    if not unitized:
        return nx, ny, nz

    length = length_vector([nx, ny, nz])

    return nx / length, ny / length, nz / length
Пример #16
0
def normal_polygon(polygon, unitized=True):
    """Compute the normal of a polygon defined by a sequence of points.

    Parameters
    ----------
    polygon : sequence[point] | :class:`compas.geometry.Polygon`
        A list of polygon point coordinates.
    unitized : bool, optional
        If True, unitize the normal vector.

    Returns
    -------
    [float, float, float]
        The normal vector.

    Raises
    ------
    AssertionError
        If less than three points are provided.

    Notes
    -----
    The points in the list should be unique. For example, the first and last
    point in the list should not be the same.

    """
    p = len(polygon)

    assert p > 2, "At least three points required"

    nx = 0
    ny = 0
    nz = 0

    o = centroid_points(polygon)
    a = polygon[-1]
    oa = subtract_vectors(a, o)

    for i in range(p):
        b = polygon[i]
        ob = subtract_vectors(b, o)
        n = cross_vectors(oa, ob)
        oa = ob

        nx += n[0]
        ny += n[1]
        nz += n[2]

    if not unitized:
        return [nx, ny, nz]

    return normalize_vector([nx, ny, nz])
Пример #17
0
def distance_point_point(a, b):
    """Compute the distance bewteen a and b.

    Parameters
    ----------
    a : sequence of float
        XYZ coordinates of point a.
    b : sequence of float
        XYZ coordinates of point b.

    Returns
    -------
    float
        Distance bewteen a and b.

    Examples
    --------
    >>> distance_point_point([0.0, 0.0, 0.0], [2.0, 0.0, 0.0])
    2.0

    See Also
    --------
    distance_point_point_xy

    """
    ab = subtract_vectors(b, a)
    return length_vector(ab)
Пример #18
0
def centroid_polygon_edges(polygon):
    """Compute the centroid of the edges of a polygon.

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

    Returns
    -------
    list
        The XYZ coordinates of the centroid.

    Notes
    -----
    The centroid of the edges is the centroid of the midpoints of the edges, with
    each midpoint weighted by the length of the corresponding edge proportional
    to the total length of the boundary.
    """
    L = 0
    cx = 0
    cy = 0
    cz = 0
    p = len(polygon)
    for i in range(-1, p - 1):
        p1 = polygon[i]
        p2 = polygon[i + 1]
        d = length_vector(subtract_vectors(p2, p1))
        cx += 0.5 * d * (p1[0] + p2[0])
        cy += 0.5 * d * (p1[1] + p2[1])
        cz += 0.5 * d * (p1[2] + p2[2])
        L += d
    return [cx / L, cy / L, cz / L]
Пример #19
0
def is_intersection_line_plane(line, plane, tol=1e-6):
    """Determine if a line (ray) intersects with a plane.

    Parameters
    ----------
    line : tuple
        Two points defining the line.
    plane : tuple
        The base point and normal defining the plane.
    tol : float, optional
        A tolerance for intersection verification.
        Default is ``1e-6``.

    Returns
    -------
    bool
        ``True`` if the line intersects with the plane.
        ``False`` otherwise.
    """
    pt1 = line[0]
    pt2 = line[1]
    p_norm = plane[1]

    v1 = subtract_vectors(pt2, pt1)
    dot = dot_vectors(p_norm, v1)

    if fabs(dot) > tol:
        return True
    return False
Пример #20
0
def distance_point_point_sqrd(a, b):
    """Compute the squared distance bewteen points a and b.

    Parameters
    ----------
    a : sequence of float
        XYZ coordinates of point a.
    b : sequence of float
        XYZ coordinates of point b.

    Returns
    -------
    d2 : float
        Squared distance bewteen a and b.

    Examples
    --------
    >>> distance_point_point_sqrd([0.0, 0.0, 0.0], [2.0, 0.0, 0.0])
    4.0

    See Also
    --------
    distance_point_point_sqrd_xy

    """
    ab = subtract_vectors(b, a)
    return length_vector_sqrd(ab)
Пример #21
0
def is_intersection_line_plane(line, plane, tol=1e-6):
    """Determine if a line (ray) intersects with a plane.

    Parameters
    ----------
    line : [point, point] | :class:`compas.geometry.Line`
        A line.
    plane : [point, vector] | :class:`compas.geometry.Plane`
        A plane.
    tol : float, optional
        A tolerance for intersection verification.

    Returns
    -------
    bool
        True if the line intersects with the plane.
        False otherwise.

    """
    pt1 = line[0]
    pt2 = line[1]
    p_norm = plane[1]

    v1 = subtract_vectors(pt2, pt1)
    dot = dot_vectors(p_norm, v1)

    if fabs(dot) > tol:
        return True
    return False
Пример #22
0
def distance_point_point(a, b):
    """Compute the distance bewteen a and b.

    Parameters
    ----------
    a : [float, float, float] | :class:`compas.geometry.Point`
        XYZ coordinates of point a.
    b : [float, float, float] | :class:`compas.geometry.Point`
        XYZ coordinates of point b.

    Returns
    -------
    float
        Distance bewteen a and b.

    Examples
    --------
    >>> distance_point_point([0.0, 0.0, 0.0], [2.0, 0.0, 0.0])
    2.0

    See Also
    --------
    distance_point_point_xy

    """
    ab = subtract_vectors(b, a)
    return length_vector(ab)
Пример #23
0
def distance_line_line(l1, l2, tol=0.0):
    r"""Compute the shortest distance between two lines.

    Parameters
    ----------
    l1 : tuple
        Two points defining a line.
    l2 : tuple
        Two points defining a line.

    Returns
    -------
    float
        The distance between the two lines.

    Notes
    -----
    The distance is the absolute value of the dot product of a unit vector that
    is perpendicular to the two lines, and the vector between two points on the lines ([1]_, [2]_).

    If each of the lines is defined by two points (:math:`l_1 = (\mathbf{x_1}, \mathbf{x_2})`,
    :math:`l_2 = (\mathbf{x_3}, \mathbf{x_4})`), then the unit vector that is
    perpendicular to both lines is...

    References
    ----------
    .. [1] Weisstein, E.W. *Line-line Distance*.
           Available at: http://mathworld.wolfram.com/Line-LineDistance.html.
    .. [2] Wikipedia. *Skew lines Distance*.
           Available at: https://en.wikipedia.org/wiki/Skew_lines#Distance.

    Examples
    --------
    >>>

    """
    a, b = l1
    c, d = l2
    ab = subtract_vectors(b, a)
    cd = subtract_vectors(d, c)
    ac = subtract_vectors(c, a)
    n = cross_vectors(ab, cd)
    length = length_vector(n)
    if length <= tol:
        return distance_point_point(closest_point_on_line(l1[0], l2), l1[0])
    n = scale_vector(n, 1.0 / length)
    return fabs(dot_vectors(n, ac))
Пример #24
0
def intersection_line_line(l1, l2, tol=1e-6):
    """Computes the intersection of two lines.

    Parameters
    ----------
    l1 : tuple, list
        XYZ coordinates of two points defining the first line.
    l2 : tuple, list
        XYZ coordinates of two points defining the second line.
    tol : float, optional
        A tolerance for membership verification.
        Default is ``1e-6``.

    Returns
    -------
    list
        XYZ coordinates of the two points marking the shortest distance between the lines.
        If the lines intersect, these two points are identical.
        If the lines are skewed and thus only have an apparent intersection, the two
        points are different.
        If the lines are parallel, the return value is [None, None].

    Examples
    --------
    >>>

    """
    a, b = l1
    c, d = l2

    ab = subtract_vectors(b, a)
    cd = subtract_vectors(d, c)

    n = cross_vectors(ab, cd)
    n1 = normalize_vector(cross_vectors(ab, n))
    n2 = normalize_vector(cross_vectors(cd, n))

    plane_1 = (a, n1)
    plane_2 = (c, n2)

    i1 = intersection_line_plane(l1, plane_2, tol=tol)
    i2 = intersection_line_plane(l2, plane_1, tol=tol)

    return i1, i2
Пример #25
0
def intersection_segment_plane(segment, plane, tol=1e-6):
    """Computes the intersection point of a line segment and a plane

    Parameters
    ----------
    segment : tuple
        Two points defining the line segment.
    plane : tuple
        The base point and normal defining the plane.
    tol : float, optional
        A tolerance for membership verification.
        Default is ``1e-6``.

    Returns
    -------
    point : tuple
        if the line segment intersects with the plane, None otherwise.

    """
    a, b = segment
    o, n = plane

    ab = subtract_vectors(b, a)
    cosa = dot_vectors(n, ab)

    if fabs(cosa) <= tol:
        # if the dot product (cosine of the angle between segment and plane)
        # is close to zero the line and the normal are almost perpendicular
        # hence there is no intersection
        return None

    # based on the ratio = -dot_vectors(n, ab) / dot_vectors(n, oa)
    # there are three scenarios
    # 1) 0.0 < ratio < 1.0: the intersection is between a and b
    # 2) ratio < 0.0: the intersection is on the other side of a
    # 3) ratio > 1.0: the intersection is on the other side of b
    oa = subtract_vectors(a, o)
    ratio = - dot_vectors(n, oa) / cosa

    if 0.0 <= ratio and ratio <= 1.0:
        ab = scale_vector(ab, ratio)
        return add_vectors(a, ab)

    return None
Пример #26
0
def is_polygon_convex(polygon):
    """Determine if a polygon is convex.

    Parameters
    ----------
    polygon : sequence of sequence of floats
        The XYZ coordinates of the corners of the polygon.

    Notes
    -----
    Use this function for *spatial* polygons.
    If the polygon is in a horizontal plane, use :func:`is_polygon_convex_xy` instead.

    Returns
    -------
    bool
        ``True`` if the polygon is convex.
        ``False`` otherwise.

    See Also
    --------
    is_polygon_convex_xy

    Examples
    --------
    >>> polygon = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.4, 0.4, 0.0], [0.0, 1.0, 0.0]]
    >>> is_polygon_convex(polygon)
    False
    """
    a = polygon[0]
    o = polygon[1]
    b = polygon[2]
    oa = subtract_vectors(a, o)
    ob = subtract_vectors(b, o)
    n0 = cross_vectors(oa, ob)
    for a, o, b in window(polygon + polygon[:2], 3):
        oa = subtract_vectors(a, o)
        ob = subtract_vectors(b, o)
        n = cross_vectors(oa, ob)
        if dot_vectors(n, n0) >= 0:
            continue
        else:
            return False
    return True
Пример #27
0
def distance_point_plane_signed(point, plane):
    r"""Compute the signed distance from a point to a plane defined by origin point and normal.

    Parameters
    ----------
    point : list
        Point coordinates.
    plane : tuple
        A point and a vector defining a plane.

    Returns
    -------
    float
        Distance between point and plane.

    Notes
    -----
    The distance from a point to a plane can be computed from the coefficients
    of the equation of the plane and the coordinates of the point [1]_.

    The equation of a plane is

    .. math::

        Ax + By + Cz + D = 0

    where

    .. math::
        :nowrap:

        \begin{align}
            D &= - Ax_0 - Bx_0 - Cz_0 \\
            Q &= (x_0, y_0, z_0) \\
            N &= (A, B, C)
        \end{align}

    with :math:`Q` a point on the plane, and :math:`N` the normal vector at
    that point. The distance of any point :math:`P` to a plane is the
    value of the dot product of the vector from :math:`Q` to :math:`P`
    and the normal at :math:`Q`.

    References
    ----------
    .. [1] Nykamp, D. *Distance from point to plane*.
           Available at: http://mathinsight.org/distance_point_plane.

    Examples
    --------
    >>>

    """
    base, normal = plane
    vector = subtract_vectors(point, base)
    return dot_vectors(vector, normal)
Пример #28
0
def is_polygon_convex(polygon):
    """Determine if a polygon is convex.

    Parameters
    ----------
    polygon : sequence[point] | :class:`compas.geometry.Polygon`
        A polygon.

    Returns
    -------
    bool
        True if the polygon is convex.
        False otherwise.

    Notes
    -----
    Use this function for *spatial* polygons.
    If the polygon is in a horizontal plane, use :func:`is_polygon_convex_xy` instead.

    Examples
    --------
    >>> polygon = [[0.0, 0.0, 0.0], [1.0, 0.0, 0.0], [0.4, 0.4, 0.0], [0.0, 1.0, 0.0]]
    >>> is_polygon_convex(polygon)
    False

    """
    a = polygon[0]
    o = polygon[1]
    b = polygon[2]
    oa = subtract_vectors(a, o)
    ob = subtract_vectors(b, o)
    n0 = cross_vectors(oa, ob)
    for a, o, b in window(polygon + polygon[:2], 3):
        oa = subtract_vectors(a, o)
        ob = subtract_vectors(b, o)
        n = cross_vectors(oa, ob)
        if dot_vectors(n, n0) >= 0:
            continue
        else:
            return False
    return True
Пример #29
0
def angles_points(a, b, c, deg=False):
    r"""Compute the two angles between two vectors defined by three points.

    Parameters
    ----------
    a : [float, float, float] | :class:`compas.geometry.Point`
        XYZ coordinates.
    b : [float, float, float] | :class:`compas.geometry.Point`
        XYZ coordinates.
    c : [float, float, float] | :class:`compas.geometry.Point`
        XYZ coordinates.
    deg : bool, optional
        If True, returns the angle in degrees.

    Returns
    -------
    float
        The smallest angle in radians, or in degrees if ``deg == True``.
    float
        The other angle.

    Notes
    -----
    The vectors are defined in the following way

    .. math::

        \mathbf{u} = \mathbf{b} - \mathbf{a} \\
        \mathbf{v} = \mathbf{c} - \mathbf{a}

    Examples
    --------
    >>>

    """
    u = subtract_vectors(b, a)
    v = subtract_vectors(c, a)
    return angles_vectors(u, v, deg)
Пример #30
0
def distance_point_line(point, line):
    """Compute the distance between a point and a line.

    Parameters
    ----------
    point : list, tuple
        Point location.
    line : list, tuple
        Line defined by two points.

    Returns
    -------
    float
        The distance between the point and the line.

    Notes
    -----
    This implementation computes the *right angle distance* from a point P to a
    line defined by points A and B as twice the area of the triangle ABP divided
    by the length of AB [1]_.

    References
    ----------
    .. [1] Wikipedia. *Distance from a point to a line*.
           Available at: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line

    Examples
    --------
    >>>

    """
    a, b = line
    ab = subtract_vectors(b, a)
    pa = subtract_vectors(a, point)
    pb = subtract_vectors(b, point)
    length = length_vector(cross_vectors(pa, pb))
    length_ab = length_vector(ab)
    return length / length_ab