Beispiel #1
0
def fit(p1: tuple, p2: tuple, r: float) -> tuple:
    """ The two circles determined by two points and a radius. """
    # find line which the center lies on
    (x0, y0), (x1, y1) = p1, p2
    c = ((x0 + x1) / 2, (y0 + y1) / 2)
    dx, dy = x0 - x1, y0 - y1
    if dy == 0:  # vertical line
        xc = c[0] + dy / dx * c[1]
        yc1, yc2 = quadratic(
            1, -2 * y0, y0 * y0 + (x0 * x0 - 2 * x0 * xc + xc * xc) - r * r)
        if yc1 is None: return
        c1, c2 = (xc, yc1), (xc, yc2)
    else:
        m, i = -dx / dy, dx / dy * c[0] + c[1]
        # solve quadratic equation
        a = m * m + 1
        b = -2 * (m * (y0 - i) + x0)
        c = x0 * x0 + (y0 - i) * (y0 - i) - r * r
        xc1, xc2 = quadratic(a, b, c)
        if xc1 is None: return
        c1, c2 = (xc1, m * xc1 + i), (xc2, m * xc2 + i)

    c1, c2 = nudge(p1, p2, c1), nudge(p1, p2, c2)
    assert abs(dist(c1, p1) - r * r) < 10**-3 and abs(dist(c2, p2) -
                                                      r * r) < 10**-3
    return (c1, c2)
def best_point():
    w, h, d = x1 - x0, y1 - y0, D
    p, count = ((x0 + x1) / 2, (y0 + y1) / 2), 0
    i = 0
    while True:
        oldp, oldc = p, count
        p, count = update_point(p, w, h, d)
        if dist(oldp, p) < 0.001:
            break
        w, h, d = w / 2, h / 2, d / 2
        i += 1
    return p
Beispiel #3
0
radii = [int(input()) for i in range(M)]
circle_order = sorted(range(M), key=lambda i: -radii[i])

x, y = zip(*points)
x0, x1, y0, y1 = min(x), max(x), min(y), max(y)

freq = {r: [] for r in radii}
for i, r in enumerate(radii):
    freq[r].append(i)

circles = [None] * M
active = set(points)
for r in sorted(freq, reverse=True):
    K = len(freq[r])
    t = kdTree(list(active))
    # centers, sets = gen_grid(t, r, 0.2)
    centers, sets = get_circles(list(active), t, r)
    rcircles, covered = solve(list(active), centers, sets, K)
    for i in range(K):
        circles[freq[r][i]] = rcircles[i]
    active -= covered

for circle in circles:
    print(" ".join(map(str, circle)))

# count covered
count = set()
for i, circle in enumerate(circles):
    count |= {point for point in points if dist(circle, point) <= radii[i]**2}
assert False, len(count)
def covered(circle: tuple, r: float) -> int:
    return sum(dist(circle, point) <= r**2 for point in points)
def f(i):
    return -sum(dist(point, centers[i]) for point in groups[i])