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
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)
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
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
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
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)
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)
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))
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)
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)
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
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)