Exemplo n.º 1
0
def angle_points_xy(a, b, c, deg=False):
    r"""Compute the smallest angle between the vectors defined by the XY components of three points.

    Parameters
    ----------
    a : sequence of float
        XY(Z) coordinates of a 2D or 3D point (Z will be ignored).
    b : sequence of float)
        XY(Z) coordinates of a 2D or 3D point (Z will be ignored).
    c : sequence of float)
        XY(Z) coordinates of a 2D or 3D point (Z will be ignored).
    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_xy(b, a)
    v = subtract_vectors_xy(c, a)
    return angle_vectors_xy(u, v, deg)
Exemplo n.º 2
0
def distance_point_line_sqrd_xy(point, line):
    """Compute the squared distance between a point and a line lying in the XY-plane.

    Parameters
    ----------
    point : sequence of float
        XY(Z) coordinates of a 2D or 3D point (Z will be ignored).
    line : list, tuple
        Line defined by two points.

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

    Notes
    -----
    This implementation computes the orthogonal squared 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.

    """
    a, b = line
    ab = subtract_vectors_xy(b, a)
    pa = subtract_vectors_xy(a, point)
    pb = subtract_vectors_xy(b, point)
    l = cross_vectors_xy(pa, pb)[2]**2
    l_ab = length_vector_sqrd_xy(ab)
    return l / l_ab
Exemplo n.º 3
0
def distance_point_line_xy(point, line):
    """Compute the distance between a point and a line, assuming they lie in the XY-plane.

    This implementation computes the orthogonal 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.

    Parameters
    ----------
    point : sequence of float
        XY(Z) coordinates of the point.
    line : list, tuple
        Line defined by two points.

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

    References
    ----------
    https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line

    """
    a, b = line
    ab = subtract_vectors_xy(b, a)
    pa = subtract_vectors_xy(a, point)
    pb = subtract_vectors_xy(b, point)
    l = fabs(cross_vectors_xy(pa, pb)[2])
    l_ab = length_vector_xy(ab)
    return l / l_ab
Exemplo n.º 4
0
def area_polygon_xy(polygon):
    """Compute the area of a polygon lying in the XY-plane.

    Parameters
    ----------
    polygon : sequence
        A sequence of XY(Z) coordinates of 2D or 3D points
        representing the locations of the corners of a polygon.
        The vertices are assumed to be in order. The polygon is assumed to be closed:
        the first and last vertex in the sequence should not be the same.

    Returns
    -------
    float
        The area of the polygon.

    """
    o = centroid_points_xy(polygon)
    u = subtract_vectors_xy(polygon[-1], o)
    v = subtract_vectors_xy(polygon[0], o)
    a = 0.5 * cross_vectors_xy(u, v)[2]
    for i in range(0, len(polygon) - 1):
        u = v
        v = subtract_vectors_xy(polygon[i + 1], o)
        a += 0.5 * cross_vectors_xy(u, v)[2]
    return abs(a)
Exemplo n.º 5
0
def angle_smallest_points_xy(a, b, c):
    r"""Compute the smallest angle defined by the XY components of three points lying in
       the XY-plane where the angle is computed at point A in the triangle ABC

    Parameters
    ----------
    a : sequence of float
        XY(Z) coordinates of a 2D or 3D point (Z will be ignored).
    b : sequence of float)
        XY(Z) coordinates of a 2D or 3D point (Z will be ignored).
    c : sequence of float)
        XY(Z) coordinates of a 2D or 3D point (Z will be ignored).

    Returns
    -------
    float
        The smallest angle between the vectors.
        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_xy(b, a)
    v = subtract_vectors_xy(c, a)
    a = angle_smallest_vectors_xy(u, v)
    return a
Exemplo n.º 6
0
def normal_triangle_xy(triangle, unitized=True):
    """Compute the normal vector of a triangle assumed to lie in the XY plane.

    Parameters
    ----------
    triangle : list of list
        A list of triangle point coordinates.
        Z-coordinates are ignored.

    Returns
    -------
    list
        The normal vector, which is a vector perpendicular to the XY plane.

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

    """
    a, b, c = triangle
    ab = subtract_vectors_xy(b, a)
    ac = subtract_vectors_xy(c, a)
    n = cross_vectors_xy(ab, ac)
    if not unitized:
        return n
    lvec = length_vector_xy(n)
    return n[0] / lvec, n[1] / lvec, n[2] / lvec
Exemplo n.º 7
0
def project_point_line_xy(point, line):
    """Project a point onto a line in the XY plane.

    Parameters
    ----------
    point : list of float
        XY(Z) coordinates of the point.
    line : tuple
        Two points defining the projection line.

    Returns
    -------
    list
        XYZ coordinates of the projected point, with Z=0.

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

    References
    ----------
    .. [1] Wiki Books. *Linear Algebra/Orthogonal Projection Onto a Line*.
           Available at: https://en.wikibooks.org/wiki/Linear_Algebra/Orthogonal_Projection_Onto_a_Line.

    """
    a, b = line
    ab = subtract_vectors_xy(b, a)
    ap = subtract_vectors_xy(point, a)
    c = vector_component_xy(ap, ab)
    return add_vectors_xy(a, c)
Exemplo n.º 8
0
def normal_triangle_xy(triangle, normalised=True):
    a, b, c = triangle
    ab = subtract_vectors_xy(b, a)
    ac = subtract_vectors_xy(c, a)
    n = cross_vectors_xy(ab, ac)
    if not normalised:
        return n
    lvec = length_vector_xy(n)
    return n[0] / lvec, n[1] / lvec, n[2] / lvec
Exemplo n.º 9
0
def normal_triangle_xy(triangle, unitized=True):
    """Compute the normal vector of a triangle assumed to lie in the XY plane.
    """
    a, b, c = triangle
    ab = subtract_vectors_xy(b, a)
    ac = subtract_vectors_xy(c, a)
    n  = cross_vectors_xy(ab, ac)
    if not unitized:
        return n
    lvec = length_vector_xy(n)
    return n[0] / lvec, n[1] / lvec, n[2] / lvec
Exemplo n.º 10
0
def distance_point_point_sqrd_xy(a, b):
    """Compute the squared distance between points a and b lying in the XY plane.

    Parameters
    ----------
    a : sequence of float
        XY(Z) coordinates of the first point.
    b : sequence of float)
        XY(Z) coordinates of the second point.

    Returns
    -------
    float
        Squared distance between a and b in the XY-plane.

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

    >>> distance([0.0, 0.0, 0.0], [2.0, 0.0, 0.0])
    4.0

    >>> distance([0.0, 0.0, 1.0], [2.0, 0.0, 1.0])
    4.0

    """
    ab = subtract_vectors_xy(b, a)
    return length_vector_sqrd_xy(ab)
Exemplo n.º 11
0
def distance_point_point_xy(a, b):
    """Compute the distance between points a and b, assuming they lie in the XY plane.

    Parameters
    ----------
    a : sequence of float
        XY(Z) coordinates of a 2D or 3D point (Z will be ignored).
    b : sequence of float
        XY(Z) coordinates of a 2D or 3D point (Z will be ignored).

    Returns
    -------
    float
        Distance between a and b in the XY-plane.

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

    >>> distance_point_point_xy([0.0, 0.0, 0.0], [2.0, 0.0, 0.0])
    2.0

    >>> distance_point_point_xy([0.0, 0.0, 1.0], [2.0, 0.0, 1.0])
    2.0

    """
    ab = subtract_vectors_xy(b, a)
    return length_vector_xy(ab)
Exemplo n.º 12
0
def intersection_circle_circle_xy(circle1, circle2):
    """Calculates the intersection points of two circles in 2d lying in the XY plane.

    Parameters:
        circle1 (tuple): center, radius of the first circle in the xy plane.
        circle2 (tuple): center, radius of the second circle in the xy plane.

    Returns:
        points (list of tuples): the intersection points if there are any
        None: if there are no intersection points

    """
    p1, r1 = circle1[0], circle1[1]
    p2, r2 = circle2[0], circle2[1]

    d = length_vector_xy(subtract_vectors_xy(p2, p1))

    if d > r1 + r2:
        return None

    if d < abs(r1 - r2):
        return None

    if (d == 0) and (r1 == r2):
        return None

    a = (r1 * r1 - r2 * r2 + d * d) / (2 * d)
    h = (r1 * r1 - a * a)**0.5
    cx2 = p1[0] + a * (p2[0] - p1[0]) / d
    cy2 = p1[1] + a * (p2[1] - p1[1]) / d
    i1 = ((cx2 + h * (p2[1] - p1[1]) / d), (cy2 - h * (p2[0] - p1[0]) / d), 0)
    i2 = ((cx2 - h * (p2[1] - p1[1]) / d), (cy2 + h * (p2[0] - p1[0]) / d), 0)

    return i1, i2
Exemplo n.º 13
0
def mirror_point_point_xy(point, mirror):
    """Mirror a point about a point.

    Parameters:
        point (sequence of float): XY coordinates of the point to mirror.
        mirror (sequence of float): XY coordinates of the mirror point.

    """
    return add_vectors_xy(mirror, subtract_vectors_xy(mirror, point))
Exemplo n.º 14
0
def project_point_line_xy(point, line):
    """Project a point onto a line.

    Parameters:
        point (sequence of float): XY coordinates.
        line (tuple): Two points defining a line.

    Returns:
        list: XY coordinates of the projected point.

    References:
        https://en.wikibooks.org/wiki/Linear_Algebra/Orthogonal_Projection_Onto_a_Line

    """
    a, b = line
    ab = subtract_vectors_xy(b, a)
    ap = subtract_vectors_xy(point, a)
    c = vector_component_xy(ap, ab)
    return add_vectors_xy(a, c)
Exemplo n.º 15
0
def closest_point_on_line_xy(point, line):
    """Compute closest point on line (continuous) to a given point lying in the XY-plane.

    Parameters
    ----------
    point : sequence of float
        XY(Z) coordinates of a point.
    line : tuple
        Two XY(Z) points defining a line.

    Returns
    -------
    list
        XYZ coordinates of closest point (Z = 0.0).

    """
    a, b = line
    ab = subtract_vectors_xy(b, a)
    ap = subtract_vectors_xy(point, a)
    c = vector_component_xy(ap, ab)
    return add_vectors_xy(a, c)
Exemplo n.º 16
0
def angles_points_xy(a, b, c, deg=False):
    r"""Compute the two angles between the two vectors defined by the XY components of three points.

    Parameters
    ----------
    a : sequence of float)
        XY(Z) coordinates.
    b : sequence of float)
        XY(Z) coordinates.
    c : sequence of float)
        XY(Z) coordinates.
    deg : boolean
        returns angles in degrees if True

    Returns
    -------
    tuple
        The smallest angle between the vectors in radians (in degrees if deg == True).
        The smallest angle is returned first.

    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.

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

    """
    u = subtract_vectors_xy(b, a)
    v = subtract_vectors_xy(c, a)
    return angles_vectors_xy(u, v, deg)
Exemplo n.º 17
0
def centroid_polygon_edges_xy(polygon):
    """"""
    L = 0
    cx = 0
    cy = 0
    p = len(polygon)
    for i in range(-1, p - 1):
        p1 = polygon[i]
        p2 = polygon[i + 1]
        d = length_vector_xy(subtract_vectors_xy(p2, p1))
        cx += 0.5 * d * (p1[0] + p2[0])
        cy += 0.5 * d * (p1[1] + p2[1])
        L += d
    return [cx / L, cy / L, 0.0]
Exemplo n.º 18
0
def mirror_point_point_xy(point, mirror):
    """Mirror a point about a point.

    Parameters
    ----------
    point : list of float
        XY(Z) coordinates of the point to mirror.
    mirror : list of float
        XY(Z) coordinates of the mirror point.

    Returns
    -------
    list of float
        The mirrored point, with Z=0.

    """
    return add_vectors_xy(mirror, subtract_vectors_xy(mirror, point))
Exemplo n.º 19
0
def mirror_point_line_xy(point, line):
    """Mirror a point about a line.

    Parameters
    ----------
    point : list of float
        XY(Z) coordinates of the point to mirror.
    line : tuple
        Two points defining the line.
        XY(Z) coordinates of the two points defining the mirror line.

    Returns
    -------
    list of float
        The mirrored point, with Z=0.

    """
    closest = closest_point_on_line_xy(point, line)
    return add_vectors_xy(closest, subtract_vectors_xy(closest, point))
Exemplo n.º 20
0
def center_of_mass_polygon_xy(polygon):
    """Compute the center of mass of a polygon defined as a sequence of points lying in the XY-plane.

    The center of mass of a polygon is the centroid of the midpoints of the edges,
    each weighted by the length of the corresponding edge.

    Parameters
    ----------
    polygon : sequence
        A sequence of XY(Z) coordinates of 2D or 3D points (Z will be ignored)
        representing the locations of the corners of a polygon.

    Returns
    -------
    tuple of floats
        The XYZ coordinates of the center of mass (Z = 0.0).

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

    """
    L = 0
    cx = 0
    cy = 0
    p = len(polygon)
    for i in range(-1, p - 1):
        p1 = polygon[i]
        p2 = polygon[i + 1]
        d = length_vector_xy(subtract_vectors_xy(p2, p1))
        cx += 0.5 * d * (p1[0] + p2[0])
        cy += 0.5 * d * (p1[1] + p2[1])
        L += d
    cx = cx / L
    cy = cy / L
    return cx, cy, 0.0
Exemplo n.º 21
0
def centroid_polygon_xy(polygon):
    r"""Compute the centroid of the surface of a polygon projected to the XY plane.

    Parameters
    ----------
    polygon : list of point
        A sequence of polygon point XY(Z) coordinates.
        The Z coordinates are ignored.

    Returns
    -------
    list
        The XYZ coordinates of the centroid.
        The Z coodinate is zero.

    Examples
    --------
    .. code-block:: python

        from compas.geometry import centroid_polygon_xy

        polygon = [
            [0.0, 0.0, 0.0],
            [1.0, 0.0, 0.0],
            [1.0, 1.0, 0.0],
            [0.0, 1.0, 0.0]
        ]

        c = centroid_polygon_xy(polygon)

        print(c)  # [0.5, 0.5, 0.0]

    .. code-block:: python

        from compas.geometry import centroid_polygon_xy
        from compas.geometry import centroid_points_xy

        polygon = [
            [0.0, 0.0, 0.0],
            [1.0, 0.0, 0.0],
            [1.0, 1.0, 0.0],
            [0.5, 1.0, 0.0],
            [0.0, 1.0, 0.0]
        ]

        c = centroid_polygon(polygon)
        print(c)  # [0.5, 0.5, 0.0]

        c = centroid_points(polygon)
        print(c)  # [0.5, 0.6, 0.0]

    Notes
    -----
    The centroid is the centre of gravity of the polygon surface if mass would be
    uniformly distributed over it.

    It is calculated by triangulating the polygon surface with respect to the centroid
    of the polygon vertices, and then computing the centroid of the centroids of
    the individual triangles, weighted by the corresponding triangle area in
    proportion to the total surface area.

    .. math::

        c_x = \frac{1}{A} \sum_{i=1}^{N} A_i \cdot c_{x,i}
        c_y = \frac{1}{A} \sum_{i=1}^{N} A_i \cdot c_{y,i}
        c_z = 0

    Warning
    -------
    The polygon need not be convex.

    The polygon may be self-intersecting. However, it is unclear what the meaning
    of the centroid is in that case.

    """
    p = len(polygon)

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

    if p == 3:
        return centroid_points_xy(polygon)

    cx, cy = 0.0, 0.0
    A2 = 0

    o = centroid_points_xy(polygon)
    a = polygon[-1]
    b = polygon[0]
    oa = subtract_vectors_xy(a, o)
    ob = subtract_vectors_xy(b, o)
    n0 = cross_vectors_xy(oa, ob)

    x, y, z = centroid_points_xy([o, a, b])
    a2 = fabs(n0[2])

    A2 += a2
    cx += a2 * x
    cy += a2 * y

    for i in range(1, len(polygon)):
        a = b
        b = polygon[i]

        oa = ob
        ob = subtract_vectors_xy(b, o)

        n = cross_vectors_xy(oa, ob)
        x, y, z = centroid_points_xy([o, a, b])

        if n[2] * n0[2] > 0:
            a2 = fabs(n[2])
        else:
            a2 = -fabs(n[2])

        A2 += a2
        cx += a2 * x
        cy += a2 * y

    return [cx / A2, cy / A2, 0.0]
Exemplo n.º 22
0
def angles_points_xy(a, b, c):
    u = subtract_vectors_xy(b, a)
    v = subtract_vectors_xy(c, a)
    return angles_vectors_xy(u, v)