Ejemplo n.º 1
0
def angle_vectors_xy(u, v, deg=False, tol=1e-4):
    """Compute the smallest angle between the XY components of two vectors.

    Parameters
    ----------
    u : sequence of float
        The first 2D or 3D vector (Z will be ignored).
    v : sequence of float)
        The second 2D or 3D vector (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.

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

    """
    L = length_vector_xy(u) * length_vector_xy(v)
    if L < tol:
        return 0
    a = dot_vectors_xy(u, v) / L
    a = max(min(a, 1), -1)
    if deg:
        return degrees(acos(a))
    return acos(a)
Ejemplo n.º 2
0
def angle_vectors_xy(u, v, deg=False, tol=1e-4):
    """Compute the smallest angle between the XY components of two vectors.

    Parameters
    ----------
    u : [float, float] or [float, float, float] | :class:`compas.geometry.Vector`
        The first 2D or 3D vector (Z will be ignored).
    v : [float, float] or [float, float, float] | :class:`compas.geometry.Vector`
        The second 2D or 3D vector (Z will be ignored).
    deg : bool, optional
        If True, returns the angle in degrees.
    tol : float, optional
        Tolerance for the length of the vectors.

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

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

    """
    L = length_vector_xy(u) * length_vector_xy(v)
    if L < tol:
        return 0
    a = dot_vectors_xy(u, v) / L
    a = max(min(a, 1), -1)
    if deg:
        return degrees(acos(a))
    return acos(a)
Ejemplo n.º 3
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)
Ejemplo n.º 4
0
def distance_point_line_xy(point, line):
    """Compute the distance between a point and a line, assuming they lie in the XY-plane.

    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.

    Notes
    -----
    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 [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)
    length = fabs(cross_vectors_xy(pa, pb)[2])
    length_ab = length_vector_xy(ab)
    return length / length_ab
Ejemplo n.º 5
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
Ejemplo n.º 6
0
def centroid_polygon_edges_xy(polygon):
    """Compute the centroid of the edges of a polygon prohected to the XY plane.

    Parameters
    ----------
    polygon : sequence[[float, float] or [float, float, float] | :class:`compas.geometry.Point`]
        A sequence of polygon point coordinates.
        The Z coordinates will be ignored.

    Returns
    -------
    [float, float, 0.0]
        The XYZ coordinates of the centroid in the XY plane.

    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
    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]
Ejemplo n.º 7
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]
Ejemplo n.º 8
0
def area_triangle_xy(triangle):
    """Compute the area of a triangle defined by three points lying in the XY-plane.

    Parameters
    ----------
    triangle : list of list
        XY(Z) coordinates of the corners of the triangle.

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

    """
    return 0.5 * length_vector_xy(normal_triangle_xy(triangle, False))
Ejemplo n.º 9
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 < fabs(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