1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| import matplotlib.pyplot as plt import matplotlib.patches as patches
def get_midpoint_circle_pixels_unsimplified(radius: int): """ Implementation of the Midpoint Circle Algorithm using the original mathematical derivation to enhance conceptual understanding. """ x = 0 y = radius
d = (x + 1) ** 2 + (y - 0.5) ** 2 - radius**2
pixels = set()
while x <= y: pts = [(x, y), (y, x), (y, -x), (x, -y), (-x, -y), (-y, -x), (-y, x), (-x, y)] for p in pts: pixels.add(p)
d = (x + 1) ** 2 + (y - 0.5) ** 2 - radius**2
if d < 0: pass else: y = y - 1
x = x + 1
return list(pixels)
def get_midpoint_circle_pixels(radius: int): """ Calculates the integer pixel coordinates for a circle using the Midpoint Circle Algorithm (Bresenham's variation). """ x = 0 y = radius d = 1 - radius
pixels = set()
while x <= y: pts = [(x, y), (y, x), (y, -x), (x, -y), (-x, -y), (-y, -x), (-y, x), (-x, y)] for p in pts: pixels.add(p)
if d < 0: d = d + 2 * x + 3 else: d = d + 2 * (x - y) + 5 y -= 1
x += 1
return list(pixels)
def visualize_pixel_grid(radius: int, setter): """ Visualizes the circle on a rigorous grid where each pixel is a cell. The origin (0,0) is located at the center of the central grid cell. """ pixels = setter(radius)
fig, ax = plt.subplots(figsize=(6, 6))
for px, py in pixels: square = patches.Rectangle( (px - 0.5, py - 0.5), 1, 1, linewidth=0.4, edgecolor="black", facecolor="royalblue", alpha=0.8, ) ax.add_patch(square)
ideal_circle = patches.Circle( (0, 0), radius, color="crimson", fill=False, linewidth=2, linestyle="--", label="Ideal Circle", ) ax.add_patch(ideal_circle)
limit = radius + 2 ax.set_xlim(-limit, limit) ax.set_ylim(-limit, limit)
grid_ticks = [i - 0.5 for i in range(-limit, limit + 2)] ax.set_xticks(grid_ticks, minor=True) ax.set_yticks(grid_ticks, minor=True) ax.grid(which="minor", color="gray", linestyle="-", linewidth=0.5)
ax.set_xticks(range(-limit, limit + 1)) ax.set_yticks(range(-limit, limit + 1))
ax.set_aspect("equal") ax.set_title(f"Midpoint Circle Grid (R={radius})", fontsize=14)
plt.show()
if __name__ == "__main__": visualize_pixel_grid(5, setter=get_midpoint_circle_pixels)
|