def angle_vectors_xy(u, v, deg=False): """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 -------- >>> """ a = dot_vectors_xy(u, v) / (length_vector_xy(u) * length_vector_xy(v)) a = max(min(a, 1), -1) if deg: return degrees(acos(a)) return acos(a)
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)
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) l = fabs(cross_vectors_xy(pa, pb)[2]) l_ab = length_vector_xy(ab) return l / l_ab
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
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
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
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
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]
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))
def angle_smallest_vectors_xy(u, v): """Compute the smallest angle (radians) between the XY components of two vectors lying in the XY-plane. 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). Returns ------- float The smallest angle between the vectors in radians. The angle is always positive. Examples -------- >>> """ a = dot_vectors_xy(u, v) / (length_vector_xy(u) * length_vector_xy(v)) a = max(min(a, 1), -1) return acos(a)
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