number_of_courses = 7 # brick dimensions width = 0.240 height = 0.052 depth = 0.116 # horizontal joints gap = 0.02 # brick geometry box = Box.from_width_height_depth(width, height, depth) brick = Block.from_vertices_and_faces(box.vertices, box.faces) # halfbrick geometry box = Box.from_width_height_depth(0.5 * (width - gap), height, depth) halfbrick = Block.from_vertices_and_faces(box.vertices, box.faces) # empty assembly assembly = Assembly() # add bricks in a staggered pattern for i in range(number_of_courses): dy = i * height
def arch_from_rise_and_span(height, span, depth, thickness, n): """Create a semicircular arch from rise and span. Parameters ---------- height : float ... span : float Dimension of the span in meter measured at the impost level (intrados-intrados). depth : float Depth in meter of the arch perpendicular to the front view plane. thickness : float Thickness in meter of the arch. n: int number of voussoirs. Returns ------- Assembly Data structure of the semicircular arch. """ assembly = Assembly() if height > span / 2: raise Exception("Not a semicircular arch.") radius = height / 2 + (span**2 / (8 * height)) base = [0.0, 0.0, 0.0] top = [0.0, 0.0, height] left = [-span / 2, 0.0, 0.0] center = [0.0, 0.0, height - radius] vector = subtract_vectors(left, center) springing = angle_vectors(vector, [-1.0, 0.0, 0.0]) sector = radians(180) - 2 * springing angle = sector / n a = top b = add_vectors(top, [0, depth, 0]) c = add_vectors(top, [0, depth, thickness]) d = add_vectors(top, [0, 0, thickness]) R = Rotation.from_axis_and_angle([0, 1.0, 0], 0.5 * sector, center) bottom = transform_points([a, b, c, d], R) blocks = [] for i in range(n): R = Rotation.from_axis_and_angle([0, 1.0, 0], -angle, center) top = transform_points(bottom, R) vertices = bottom + top faces = [[0, 1, 2, 3], [7, 6, 5, 4], [3, 7, 4, 0], [6, 2, 1, 5], [7, 3, 2, 6], [5, 1, 0, 4]] block = Block.from_vertices_and_faces(vertices, faces) assembly.add_block(block) bottom = top assembly.node_attribute(0, 'is_support', True) assembly.node_attribute(n - 1, 'is_support', True) return assembly
# list the coordinates of all vertices of all blocks points = [] for key in assembly.vertices(): block = assembly.blocks[key] xyz = block.get_vertices_attributes('xyz') points.extend(xyz) # compute the XY bounding box of all listed vertices bbox = bounding_box_xy(points) # make a support block of the same size as the bounding box support = Block.from_vertices_and_faces(bbox, [[0, 1, 2, 3]]) # scale the support lx = length_vector(subtract_vectors(bbox[1], bbox[0])) ly = length_vector(subtract_vectors(bbox[2], bbox[1])) sx = (0.0 + lx) / lx sy = (0.0 + ly) / ly S = Scale([sx, sy, 1.0]) mesh_transform(support, S) # align the centroid of the support with the centroid of the bounding box b = centroid_points(bbox) a = support.centroid()