Example #1
0
def distance_point_line_sqrd_2d(point, line):
    """Compute the squared distance between a point and a line lying in the XY-plane.

    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.

    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.

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

    """
    a, b = line
    ab = subtract_vectors_2d(b, a)
    pa = subtract_vectors_2d(a, point)
    pb = subtract_vectors_2d(b, point)
    l = cross_vectors_2d(pa, pb)[2]**2
    l_ab = length_vector_sqrd_2d(ab)
    return l / l_ab
Example #2
0
def area_polygon_2d(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_2d(polygon)
    u = subtract_vectors_2d(polygon[-1], o)
    v = subtract_vectors_2d(polygon[0], o)
    a = 0.5 * cross_vectors_2d(u, v)[2]
    for i in range(0, len(polygon) - 1):
        u = v
        v = subtract_vectors_2d(polygon[i + 1], o)
        a += 0.5 * cross_vectors_2d(u, v)[2]
    return abs(a)
Example #3
0
def angle_smallest_points_2d(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_2d(b, a)
    v = subtract_vectors_2d(c, a)
    a = angle_smallest_vectors_2d(u, v)
    return a
Example #4
0
def normal_triangle_2d(triangle, normalised=True):
    a, b, c = triangle
    ab = subtract_vectors_2d(b, a)
    ac = subtract_vectors_2d(c, a)
    n = cross_vectors_2d(ab, ac)
    if not normalised:
        return n
    lvec = length_vector_2d(n)
    return n[0] / lvec, n[1] / lvec, n[2] / lvec
Example #5
0
def intersection_circle_circle_2d(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_2d(subtract_vectors_2d(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
Example #6
0
def distance_point_point_2d(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_2d([0.0, 0.0], [2.0, 0.0])
    2.0

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

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

    """
    ab = subtract_vectors_2d(b, a)
    return length_vector_2d(ab)
Example #7
0
def distance_point_point_sqrd_2d(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_2d(b, a)
    return length_vector_sqrd_2d(ab)
Example #8
0
def mirror_point_point_2d(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_2d(mirror, subtract_vectors_2d(mirror, point))
Example #9
0
def project_point_line_2d(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_2d(b, a)
    ap = subtract_vectors_2d(point, a)
    c = vector_component_2d(ap, ab)
    return add_vectors_2d(a, c)
Example #10
0
def closest_point_on_line_2d(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_2d(b, a)
    ap = subtract_vectors_2d(point, a)
    c = vector_component_2d(ap, ab)
    return add_vectors_2d(a, c)
Example #11
0
def center_of_mass_polygon_2d(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_2d(subtract_vectors_2d(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
Example #12
0
def angles_points_2d(a, b, c):
    u = subtract_vectors_2d(b, a)
    v = subtract_vectors_2d(c, a)
    return angles_vectors_2d(u, v)