def is_point_on_segment(point, segment, tol=0.0): """Determine if a point lies on a given line segment. Parameters ---------- point : sequence of float XYZ coordinates. segment : tuple Two points defining the line segment. Returns ------- bool ``True`` if the point is on the line segment. ``False`` otherwise. """ a, b = segment if not is_point_on_line(point, segment, tol=tol): return False d_ab = distance_point_point(a, b) if d_ab == 0: return False d_pa = distance_point_point(a, point) d_pb = distance_point_point(b, point) if d_pa + d_pb <= d_ab + tol: return True return False
def check_length_sol_one(solution, pt_mean, pt, b1, b2, b1_key, b2_key, b_struct): vec_sol = solution dpp = dropped_perpendicular_points(pt, add_vectors(pt, vec_sol), b1["axis_endpoints"][0], b1["axis_endpoints"][1]) pt_x1 = dpp[0] pt_1 = dpp[1] dpp = dropped_perpendicular_points(pt, add_vectors(pt, vec_sol), b2["axis_endpoints"][0], b2["axis_endpoints"][1]) pt_x2 = dpp[0] pt_2 = dpp[1] if pt_x1 == None: return None if pt_x2 == None: return None pts_all_b1 = [] b_vert_n = b_struct.vertex_neighbors(b1_key) pts_all_b1.append(b_struct.vertex[b1_key]["axis_endpoints"][0]) pts_all_b1.append(b_struct.vertex[b1_key]["axis_endpoints"][1]) for n in b_vert_n: pts_all_b1.append( dropped_perpendicular_points( b1["axis_endpoints"][0], b1["axis_endpoints"][1], b_struct.vertex[n]["axis_endpoints"][0], b_struct.vertex[n]["axis_endpoints"][1])[0]) pts_all_b1.append(pt_1) pts_b1 = find_points_extreme(pts_all_b1, b1["axis_endpoints"]) pts_all_b2 = [] b_vert_n = b_struct.vertex_neighbors(b2_key) pts_all_b2.append(b_struct.vertex[b2_key]["axis_endpoints"][0]) pts_all_b2.append(b_struct.vertex[b2_key]["axis_endpoints"][1]) for n in b_vert_n: pts_all_b2.append( dropped_perpendicular_points( b2["axis_endpoints"][0], b2["axis_endpoints"][1], b_struct.vertex[n]["axis_endpoints"][0], b_struct.vertex[n]["axis_endpoints"][1])[0]) pts_all_b2.append(pt_2) pts_b2 = find_points_extreme(pts_all_b2, b2["axis_endpoints"]) vec_test_dir_1 = subtract_vectors(pt_mean, pt) if not check_dir(vec_sol, vec_test_dir_1): vec_sol = scale_vector(vec_sol, -1) lx1 = distance_point_point(pt, pt_x1) lx2 = distance_point_point(pt, pt_x2) l_max = lx1 if lx1 > lx2 else lx2 sol = [vec_sol, l_max, pts_b1, pts_b2] return sol
def is_point_on_polyline(point, polyline, tol=0.0): """Determine if a point is on a polyline. Parameters ---------- point : sequence of float XYZ coordinates. polyline : sequence of sequence of float XYZ coordinates of the points of the polyline. tol : float, optional The tolerance. Default is ``0.0``. Returns ------- bool ``True`` if the point is on the polyline. ``False`` otherwise. """ for i in range(len(polyline) - 1): a = polyline[i] b = polyline[i + 1] c = closest_point_on_segment(point, (a, b)) if distance_point_point(point, c) <= tol: return True return False
def tween_points_distance(points1, points2, dist, index=None): """Compute an interpolated set of points between two sets of points, at a given distance. Parameters ---------- points1 : list The first set of points points2 : list The second set of points dist : float The distance from the first set to the second at which to compute the interpolated set. index: int The index of the point in the first set from which to calculate the distance to the second set. If no value is given, the first point will be used. Returns ------- list List of points """ if not index: index = 0 d = distance_point_point(points1[index], points2[index]) scale = float(dist) / d tweens = [] for i in range(len(points1)): tweens.append( add_vectors( points1[i], scale_vector(vector_from_points(points1[i], points2[i]), scale))) return tweens
def is_point_on_segment(point, segment, tol=1e-6): """Determine if a point lies on a given line segment. Parameters ---------- point : sequence of float XYZ coordinates. segment : tuple Two points defining the line segment. tol : float, optional A tolerance for membership verification. Default is ``1e-6``. Returns ------- bool ``True`` if the point is on the line segment. ``False`` otherwise. """ a, b = segment if not is_point_on_line(point, segment, tol=tol): return False d_ab = distance_point_point(a, b) if d_ab == 0: return False d_pa = distance_point_point(a, point) d_pb = distance_point_point(b, point) if d_pa + d_pb <= d_ab + tol: return True return False
def is_point_in_circle(point, circle): """Determine if a point lies in a circle. Parameters: point (sequence of float): XYZ coordinates of a 3D point. circle (tuple): center, radius, normal Returns: (bool): True if the point lies in the circle, False otherwise. """ center, radius, normal = circle if is_point_on_plane(point, (center, normal)): return distance_point_point(point, center) <= radius return False
def distance_to_point(self, point): """Compute the distance to another point. Parameters ---------- point : point The other point. Returns ------- float The distance. """ return distance_point_point(self, point)
def check_colisions(b_struct, pts, radius, bar_nb=None, bar_checking=None): """[summary] Parameters ---------- b_struct : [type] [description] pts : [type] [description] radius : [type] [description] bar_nb : [type], optional [description], by default None bar_checking : [type], optional [description], by default None Returns ------- bool True if no collision found, False otherwise """ tol = 50 # | TOL # print "bar_checking", bar_checking for b in b_struct.vertex: if not bar_nb: bar_nb = 100000000000000 if bar_checking != None and b < 3: continue if b < bar_nb and b != bar_checking: pts_b = b_struct.vertex[b]["axis_endpoints"] dpp = dropped_perpendicular_points(pts[0], pts[1], pts_b[0], pts_b[1]) try: dist = distance_point_point(dpp[0], dpp[1]) except: return False # why 50? if 2*radius - dist > TOL and \ is_point_on_segment(dpp[0], pts, tol=tol) and \ is_point_on_segment(dpp[1], pts_b, tol=tol): print("COLLISION", len(b_struct.vertex)) return False return True
def is_point_in_circle(point, circle): """Determine if a point lies in a circle. Parameters ---------- point : sequence of float XYZ coordinates of a 3D point. circle : tuple center, radius, normal Returns ------- bool ``True`` if the point lies in the circle. ``False`` otherwise. """ center, radius, normal = circle if is_point_on_plane(point, (center, normal)): return distance_point_point(point, center) <= radius return False
def check_distance(self, n_key, nodes_used, nodes_vic, dist, point_base, n_base): # checks distance for vertices while going through the network structure via neighbours (recursively) bool_check = True for n in self.vertex_neighbours(n_key): bool_check_l = True p = self.vertex_coordinates(n) if n not in nodes_used and n != n_base: d = distance_point_point(point_base, p) if d < dist: nodes_vic.append(n) else: bool_check = False bool_check_l = False nodes_used.append(n) if bool_check_l: self.check_distance(n, nodes_used, nodes_vic, dist, point_base, n_base) if not bool_check: return nodes_vic, nodes_used return nodes_vic, nodes_used
def intersection_sphere_sphere(sphere1, sphere2): """Computes the intersection of 2 spheres. There are 4 cases of sphere-sphere intersection : 1) the spheres intersect in a circle, 2) they intersect in a point, 3) they overlap, 4) they do not intersect. Parameters ---------- sphere1 : tuple center, radius of the sphere. sphere2 : tuple center, radius of the sphere. Returns ------- case : str `point`, `circle`, or `sphere` result : tuple - point: xyz coordinates - circle: center, radius, normal - sphere: center, radius Examples -------- >>> sphere1 = (3.0, 7.0, 4.0), 10.0 >>> sphere2 = (7.0, 4.0, 0.0), 5.0 >>> result = intersection_sphere_sphere(sphere1, sphere2) >>> if result: >>> case, res = result >>> if case == "circle": >>> center, radius, normal = res >>> elif case == "point": >>> point = res >>> elif case == "sphere": >>> center, radius = res References -------- https://gamedev.stackexchange.com/questions/75756/sphere-sphere-intersection-and-circle-sphere-intersection """ center1, radius1 = sphere1 center2, radius2 = sphere2 distance = distance_point_point(center1, center2) # Case 4: No intersection if radius1 + radius2 < distance: return None # Case 4: No intersection, sphere is within the other sphere elif distance + min(radius1, radius2) < max(radius1, radius2): return None # Case 3: sphere's overlap elif radius1 == radius2 and distance == 0: return "sphere", sphere1 # Case 2: point intersection elif radius1 + radius2 == distance: ipt = subtract_vectors(center2, center1) ipt = scale_vector(ipt, radius1 / distance) ipt = add_vectors(center1, ipt) return "point", ipt # Case 2: point intersection, smaller sphere is within the bigger elif distance + min(radius1, radius2) == max(radius1, radius2): if radius1 > radius2: ipt = subtract_vectors(center2, center1) ipt = scale_vector(ipt, radius1 / distance) ipt = add_vectors(center1, ipt) else: ipt = subtract_vectors(center1, center2) ipt = scale_vector(ipt, radius2 / distance) ipt = add_vectors(center2, ipt) return "point", ipt # Case 1: circle intersection else: h = 0.5 + (radius1**2 - radius2**2) / (2 * distance**2) ci = subtract_vectors(center2, center1) ci = scale_vector(ci, h) ci = add_vectors(center1, ci) ri = sqrt(radius1**2 - h**2 * distance**2) normal = scale_vector(subtract_vectors(center2, center1), 1 / distance) return "circle", (ci, ri, normal)
def is_point_in_circle(point, circle): center, radius, normal = circle if is_point_on_plane(point, (center, normal)): return distance_point_point(point, center) <= radius return False
from compas.viewers import MeshViewer from compas.topology import mesh_unify_cycles radius = 5 origin = (0., 0., 0.) count = 0 points = [] while count < 10: x = (random.random() - 0.5) * radius * 2 y = (random.random() - 0.5) * radius * 2 z = (random.random() - 0.5) * radius * 2 pt = x, y, z if distance_point_point(origin, pt) <= radius: points.append(pt) count += 1 vertices, faces = convex_hull_numpy(points) i_index = {i: index for index, i in enumerate(vertices)} mesh = Mesh.from_vertices_and_faces( [points[index] for index in vertices], [[i_index[i] for i in face] for face in faces[1:]] ) mesh_unify_cycles(mesh) viewer = MeshViewer(mesh)