def project_point_line_xy(point, line): """Project a point onto a line in the XY plane. Parameters ---------- point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the point. line : [point, point] | :class:`compas.geometry.Line` Two points defining the projection line. Returns ------- [float, float, float] XYZ coordinates of the projected point, with Z=0. Notes ----- For more info, see [1]_. References ---------- .. [1] Wiki Books. *Linear Algebra/Orthogonal Projection Onto a Line*. Available at: https://en.wikibooks.org/wiki/Linear_Algebra/Orthogonal_Projection_Onto_a_Line. """ a, b = line ab = subtract_vectors_xy(b, a) ap = subtract_vectors_xy(point, a) c = vector_component_xy(ap, ab) return add_vectors_xy(a, c)
def mirror_point_point_xy(point, mirror): """Mirror a point about a point. Parameters ---------- point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the point to mirror. mirror : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the mirror point. Returns ------- [float, float, float] The mirrored point, with Z=0. """ return add_vectors_xy(mirror, subtract_vectors_xy(mirror, point))
def mirror_point_point_xy(point, mirror): """Mirror a point about a point. Parameters ---------- point : list of float XY(Z) coordinates of the point to mirror. mirror : list of float XY(Z) coordinates of the mirror point. Returns ------- list of float The mirrored point, with Z=0. """ return add_vectors_xy(mirror, subtract_vectors_xy(mirror, point))
def mirror_point_line_xy(point, line): """Mirror a point about a line. Parameters ---------- point : [float, float, float] | :class:`compas.geometry.Point` XY(Z) coordinates of the point to mirror. line : [point, point] | :class:`compas.geometry.Line` Two points defining the line. XY(Z) coordinates of the two points defining the mirror line. Returns ------- [float, float, float] The mirrored point, with Z=0. """ closest = closest_point_on_line_xy(point, line) return add_vectors_xy(closest, subtract_vectors_xy(closest, point))
def mirror_point_line_xy(point, line): """Mirror a point about a line. Parameters ---------- point : list of float XY(Z) coordinates of the point to mirror. line : tuple Two points defining the line. XY(Z) coordinates of the two points defining the mirror line. Returns ------- list of float The mirrored point, with Z=0. """ closest = closest_point_on_line_xy(point, line) return add_vectors_xy(closest, subtract_vectors_xy(closest, point))
def translate_points_xy(points, vector): """Translate points and in the XY plane. Parameters ---------- points : sequence[[float, float, float] | :class:`compas.geometry.Point`] A list of points. vector : [float, float, float] | :class:`compas.geometry.Vector` A translation vector. Returns ------- list[[float, float, float]] The translated points in the XY plane (Z=0). Examples -------- >>> """ return [add_vectors_xy(point, vector) for point in points]
def translate_points_xy(points, vector): """Translate points and in the XY plane. Parameters ---------- points : list of point A list of points. vector : vector A translation vector. Returns ------- list of point The translated points in the XY plane (Z=0). Examples -------- >>> """ return [add_vectors_xy(point, vector) for point in points]
def add_feet(self, segments, feet=2): """""" def rotate(point, angle): x = cos(angle) * point[0] - sin(angle) * point[1] y = sin(angle) * point[0] + cos(angle) * point[1] return x, y, 0 def cross_z(ab, ac): return ab[0] * ac[1] - ab[1] * ac[0] scale = self.attributes['feet.scale'] alpha = self.attributes['feet.alpha'] * pi / 180 tol = self.attributes['feet.tol'] key_foot = {} key_xyz = { key: self.vertex_coordinates(key, 'xyz') for key in self.vertices() } for i, vertices in enumerate(segments): key = vertices[0] after = vertices[1] before = segments[i - 1][-2] b = key_xyz[before] o = key_xyz[key] a = key_xyz[after] ob = normalize_vector_xy(subtract_vectors_xy(b, o)) oa = normalize_vector_xy(subtract_vectors_xy(a, o)) z = cross_z(ob, oa) if z > +tol: r = normalize_vector_xy(add_vectors_xy(oa, ob)) r = [-scale * axis for axis in r] elif z < -tol: r = normalize_vector_xy(add_vectors_xy(oa, ob)) r = [+scale * axis for axis in r] else: ba = normalize_vector_xy(subtract_vectors_xy(a, b)) r = cross_vectors([0, 0, 1], ba) r = [+scale * axis for axis in r] if feet == 1: x, y, z = add_vectors_xy(o, r) m = self.add_vertex(x=x, y=y, z=o[2], is_fixed=True, is_external=True) key_foot[key] = m elif feet == 2: lx, ly, lz = add_vectors_xy(o, rotate(r, +alpha)) rx, ry, rz = add_vectors_xy(o, rotate(r, -alpha)) l = self.add_vertex(x=lx, y=ly, z=o[2], is_fixed=True, is_external=True) r = self.add_vertex(x=rx, y=ry, z=o[2], is_fixed=True, is_external=True) key_foot[key] = l, r else: pass for vertices in segments: l = vertices[0] r = vertices[-1] if feet == 1: lm = key_foot[l] rm = key_foot[r] self.add_face([lm] + vertices + [rm], is_loaded=False) self.set_edge_attribute((l, lm), 'is_external', True) self.set_edge_attribute((rm, lm), 'is_edge', False) elif feet == 2: lb = key_foot[l][0] la = key_foot[l][1] rb = key_foot[r][0] self.add_face([lb, l, la], is_loaded=False) self.add_face([la] + vertices + [rb], is_loaded=False) self.set_edge_attribute((l, lb), 'is_external', True) self.set_edge_attribute((l, la), 'is_external', True) self.set_edge_attribute((lb, la), 'is_edge', False) self.set_edge_attribute((la, rb), 'is_edge', False) else: pass