Exemplo n.º 1
0
def fill(ranges, exp, rotation, iters, shape_maker):
    riem = sum(i ** (-exp) for i in range(1, 1000000))
    total_area = (ranges[0][1] - ranges[0][0]) * (ranges[1][1] - ranges[1][0])
    initial_area = total_area / riem
    initial_size = math.sqrt(initial_area / shape_maker(gr.Point(0, 0), 1).area)

    progress = u.make_progressbar(iters, timeit=True)

    rad_rotation = rotation * math.pi / 180

    shapes = []
    for i in range(1, iters+1):
        size = initial_size * (i ** (-exp / 2))
        while True:
            center = gr.Point(random.uniform(*ranges[0]),
                              random.uniform(*ranges[1]))
            shape = shape_maker(center, size)
            if rotation > 0:
                units = random.randint(0, (360-1)//rotation)
                if units:
                    shape = shape.rotate(rad_rotation*units)
            if all(not shape.intersects(sh) for sh in shapes):
                shapes.append(shape)
                progress()
                break

    return shapes
Exemplo n.º 2
0
    def process(self):
        print("Will create triangulation for", len(self.points), "points")

        initial_tri = gr.Triangle(*self.container_points())
        self.triangles = [initial_tri]
        self.edge_map = {edge: [initial_tri] for edge in initial_tri.edges()}

        print("Inserting points")
        progressbar = utils.make_progressbar(len(self.points), timeit=True)
        for point in self.points:
            self.insert_point(point)
            progressbar()

        print("Testing triangles")
        self.test_triangles()
Exemplo n.º 3
0
def circle_fill(ranges, circle_count, minrad, maxrad, decay, postfix):
    width = ranges[0][1] - 2*ranges[0][0] + 1
    height = ranges[1][1] - 2*ranges[1][0] + 1
    used = [[False for y in range(height)] for x in range(width)]
    used_count = 0
    total_count = width * height

    maxrad = original_maxrad = maxrad

    fi = maxrad/total_count

    def maxrad_no_decay():
        pass

    def maxrad_uniform_decay():
        nonlocal maxrad, fi
        maxrad = max(5, int(fi*(total_count - used_count)))

    def maxrad_log_decay():
        nonlocal maxrad, fi
        fi =  math.log((1 + (total_count - used_count) / total_count), 2)
        maxrad = min(max(5, int(fi*(total_count - used_count))), original_maxrad)

    maxrad_decay = {
        "none": maxrad_no_decay,
        "uniform": maxrad_uniform_decay,
        "log": maxrad_log_decay
    }[decay]

    maxrad_decay()

    def check_circle(center, radius):
        for x, y in ras.rasterize_circle(center, radius):
            if used[x][y]:
                new_radius = math.ceil(math.sqrt((x-center[0])**2 + (y-center[1])**2))
                if new_radius < radius:
                    return new_radius
                else:
                    return radius - 1
        return None

    circles = []

    print("Will generate", circle_count, "random circles")
    progress = u.make_progressbar(circle_count, timeit=True)

    while len(circles) < circle_count:
        x, y = random.randint(0, width), random.randint(0, height)

        cropdrad = -1
        maxrad_cropped = min(x, y, width-x, height-y, maxrad)

        for radius in range(0, maxrad_cropped):
            if used[x-radius][y] or used[x+radius][y] or used[x][y-radius] or used[x][y+radius]:
                break
            cropdrad = radius

        if cropdrad < minrad:
            continue

        radius = cropdrad
        while radius >= minrad:
            new_radius = check_circle((x,y), radius)
            if new_radius is None:
                for cx, cy in ras.rasterize_circle((x,y), radius):
                    used[cx][cy] = True
                    used_count += 1
                circles.append(gr.Circle(gr.Point(x + ranges[0][0], y + ranges[1][0]), radius))
                maxrad_decay()
                progress()
                break
            else:
                radius = new_radius

    print("Area coverage {:.2f}%".format((used_count / total_count) * 100))

    if postfix:
        print("Postfixing")
        progress = u.make_progressbar(len(circles), timeit=True)

        for i in range(0, len(circles)):
            progress()
            for j in range(0, len(circles)):
                if i==j:
                    break
                abx = circles[j].center.x - circles[i].center.x
                aby = circles[j].center.y - circles[i].center.y
                r = circles[j].radius + circles[i].radius
                d2 = abd2 = abx**2 + aby**2
                if d2 < r**2 - 0.01:
                    fact = 0.5*(r - math.sqrt(d2)) / math.sqrt(abd2)
                    abx *= fact
                    aby *= fact
                    circles[j].center.x += abx
                    circles[j].center.y += aby
                    circles[i].center.x -= abx
                    circles[i].center.y -= aby

    return circles
Exemplo n.º 4
0
def circle_pack(distributions, iterations, min_sep, postfix, ranges):
    pcenter = ((ranges[0][1] - ranges[0][0])/2,
               (ranges[1][1] - ranges[1][0])/2)
    circles = []

    for count, min_radius, max_radius in distributions:
        for _ in range(count):
            circles.append((pcenter[0] + 50*random.random(),
                            pcenter[1] + 50*random.random(),
                            random.uniform(min_radius, max_radius)))

    progress = u.make_progressbar(iterations, timeit=True)

    for it_count in range(1, iterations+1):
        progress()

        #circles.sort(key=lambda cc: -((cc[0] - pcenter[0])**2 + (cc[1] - pcenter[1])**2))
        random.shuffle(circles)

        d_min_sep2 = min_sep**2

        for i in range(0, len(circles)-1):
            for j in range(i+1, len(circles)):
                abx = circles[j][0] - circles[i][0]
                aby = circles[j][1] - circles[i][1]
                r = circles[j][2] + circles[i][2]
                abd2 = abx**2 + aby**2
                if abd2 > d_min_sep2:
                    d2 = abd2-d_min_sep2
                else:
                    d2 = 0
                if d2 < r**2 - 0.01:
                    fact = 0.5*(r - math.sqrt(d2)) / math.sqrt(abd2)
                    abx *= fact
                    aby *= fact
                    circles[j] = (circles[j][0] + abx, circles[j][1] + aby, circles[j][2])
                    circles[i] = (circles[i][0] - abx, circles[i][1] - aby, circles[i][2])

        damping = 0.1 / it_count
        for i in range(0, len(circles)):
            cx = circles[i][0] - (circles[i][0] - pcenter[0])*damping
            cy = circles[i][1] - (circles[i][1] - pcenter[1])*damping
            circles[i] = (cx, cy, circles[i][2])

    print("Post-fixing circles")

    if postfix:
        for i in range(0, len(circles)):
            for j in range(0, len(circles)):
                if i==j:
                    break
                abx = circles[j][0] - circles[i][0]
                aby = circles[j][1] - circles[i][1]
                r = circles[j][2] + circles[i][2]
                abd2 = abx**2 + aby**2
                if abd2 > d_min_sep2:
                    d2 = abd2-d_min_sep2
                else:
                    d2 = 0
                if d2 < r**2 - 0.01:
                    dr = 0.5*(r - math.sqrt(d2))
                    circles[j] = (circles[j][0], circles[j][1], circles[j][2]-dr)
                    circles[i] = (circles[i][0], circles[i][1], circles[i][2]-dr)

    def circle_inside(cx, cy, r):
        return ranges[0][0] <= (cx - r) <= ranges[0][1] and \
            ranges[0][0] <= (cx + r) <= ranges[0][1] and \
            ranges[1][0] <= (cy - r) <= ranges[1][1] and \
            ranges[1][0] <= (cy + r) <= ranges[1][1]

    return [gr.Circle(gr.Point(cx, cy), r) for cx, cy, r in circles if circle_inside(cx, cy, r)]