def draw_layers(points, on='[]', off='  '):
    points = list(points)

    # Shift the geometry so that every point has (x, y, z) all greater than 0
    xmax = max(p.x for p in points)
    xmin = min(p.x for p in points)
    ymax = max(p.y for p in points)
    ymin = min(p.y for p in points)
    zmax = max(p.z for p in points)
    zmin = min(p.z for p in points)

    offset = (-xmin, -ymin, -zmin)
    points = translate(points, offset)

    # Update the max and min values.
    xmax -= xmin
    xmin = 0
    ymax -= ymin
    ymin = 0
    zmax -= zmin
    zmin = 0

    # Split the points into layers.
    diagrams = []
    for layer in split_layers(points):
        # Restrict to 2D points only for drawing.
        layer = [(p.x, p.y) for p in layer]
        # Draw the current layer.
        diagrams.append(
            format_points(
                layer,
                max_x=xmax,
                max_y=ymax,
                on=on,
                off=off,
            )
        )
    return diagrams
    start_angle = interpolate(min_angle, max_angle, mu)
    slice_angle = (slice_width / (outer * 2 * math.pi)) * 360

    end_angle = start_angle + slice_angle


    points = ring(center, outer, inner)
    points = radial_slice(points, center, start_angle, end_angle)
    layers.append(points)

def by_twos(iterable):
    iterable = iter(iterable)
    while True:
        yield next(iterable), next(iterable)

for z, (a, b) in enumerate(by_twos(layers)):
    a_lines = format_points(a, on='_', off='.', max_x=c*2, max_y=c*2, raw=True)
    b_lines = format_points(b, on='#', max_x=c*2, max_y=c*2, raw=True)
    for y, line in enumerate(b_lines):
        for x, character in enumerate(line):
            if character == '#':
                a_lines[y][x] = '#'

    if a_lines[c][c] != '#':
        a_lines[c][c] = 'X'

    print('-'*c*2)
    print('z', z)
    print('\n'.join(''.join(line).rstrip() for line in a_lines))
slice_angle = 90

c = math.floor(sphere_radius)
center = (c + 0.5, c + 0.5)

def slice_radius(sphere_radius, z):
    return math.sqrt(max(sphere_radius**2 - z**2, 0))

for z in range(-half_num_steps, half_num_steps + 1):
    print('z', z)

    mu = z / (max_z - min_z)

    r1 = slice_radius(sphere_radius, z)
    points = circle(center, r1)
    r2 = slice_radius(inner_sphere_radius, z)
    points -= circle(center, r2)

    start_angle = interpolate(min_angle, max_angle, mu)
    end_angle = start_angle + slice_angle
    slice_1 = radial_slice(points, center, start_angle, end_angle)

    start_angle = start_angle + 180
    end_angle = start_angle + slice_angle
    slice_2 = radial_slice(points, center, start_angle, end_angle)

    points = slice_1 | slice_2

    print('-'*c*2)
    print(format_points(points, max_x=c*2, max_y=c*2, off='.'))