How do you create a polygon that fills the area between 2 circles?
Question:
I’m trying to create a function that can create a specific polygon with Pygame.
My snippet of code:
def draw_line_round_corners_polygon(surf, point_1, point_2, color, circle_radius):
point_1_vector = pygame.math.Vector2(point_1)
point_2_vector = pygame.math.Vector2(point_2)
line_vector = (point_2_vector - point_1_vector).normalize()
line_normalised_vector = pygame.math.Vector2(-line_vector.y, line_vector.x) * circle_radius // 2
points = [point_1_vector + line_normalised_vector, point_2_vector + line_normalised_vector, point_2_vector - line_normalised_vector, point_1_vector - line_normalised_vector]
pygame.draw.polygon(surf, color, points)
pygame.draw.circle(surf, color, point_1, round(2 * circle_radius))
pygame.draw.circle(surf, color, point_2, round(circle_radius))
Current output:
Desired output:
Question:
How can I converge from the width of the bigger circle to the smaller circle with PyGame?
Answers:
You have to calculate the common tangent of 2 circles. See
Common Tangents and Tangent Circles.
After that calculate the 4 points on the tangent that intersect the circle:
def create_polygon(center1, radius1, center2, radius2):
cp1 = pygame.math.Vector2(center1)
cp2 = pygame.math.Vector2(center2)
cv = cp1 - cp2
nv = pygame.math.Vector2(-cv.y, cv.x).normalize() * (radius1 - radius2)
tnv1 = pygame.math.Vector2(-(cv.y + nv.y), cv.x + nv.x).normalize()
tnv2 = pygame.math.Vector2(cv.y - nv.y, -(cv.x - nv.x)).normalize()
pts = [cp1 + tnv1 * radius1, cp2 + tnv1 * radius2, cp2 + tnv2 * radius2, cp1 + tnv2 * radius1]
return [(p.x, p.y) for p in pts]
Minimal example
import pygame
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
cpt1 = (100, 200)
cpt2 = (300, 200)
radius = 40
def create_polygon(center1, radius1, center2, radius2):
cp1 = pygame.math.Vector2(center1)
cp2 = pygame.math.Vector2(center2)
cv = cp1 - cp2
nv = pygame.math.Vector2(-cv.y, cv.x).normalize() * (radius1 - radius2)
tnv1 = pygame.math.Vector2(-(cv.y + nv.y), cv.x + nv.x).normalize()
tnv2 = pygame.math.Vector2(cv.y - nv.y, -(cv.x - nv.x)).normalize()
pts = [cp1 + tnv1 * radius1, cp2 + tnv1 * radius2, cp2 + tnv2 * radius2, cp1 + tnv2 * radius1]
return [(p.x, p.y) for p in pts]
def draw_line_round_corners_polygon(surf, point_1, point_2, color, circle_radius):
points = create_polygon(point_1, circle_radius*2, point_2, circle_radius)
pygame.draw.polygon(surf, color, points)
pygame.draw.circle(surf, color, point_1, round(circle_radius*2))
pygame.draw.circle(surf, color, point_2, round(circle_radius))
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill("gray")
draw_line_round_corners_polygon(window, cpt1, cpt2, "red", radius)
pygame.display.flip()
pygame.quit()
exit()
I’m trying to create a function that can create a specific polygon with Pygame.
My snippet of code:
def draw_line_round_corners_polygon(surf, point_1, point_2, color, circle_radius):
point_1_vector = pygame.math.Vector2(point_1)
point_2_vector = pygame.math.Vector2(point_2)
line_vector = (point_2_vector - point_1_vector).normalize()
line_normalised_vector = pygame.math.Vector2(-line_vector.y, line_vector.x) * circle_radius // 2
points = [point_1_vector + line_normalised_vector, point_2_vector + line_normalised_vector, point_2_vector - line_normalised_vector, point_1_vector - line_normalised_vector]
pygame.draw.polygon(surf, color, points)
pygame.draw.circle(surf, color, point_1, round(2 * circle_radius))
pygame.draw.circle(surf, color, point_2, round(circle_radius))
Current output:
Desired output:
Question:
How can I converge from the width of the bigger circle to the smaller circle with PyGame?
You have to calculate the common tangent of 2 circles. See
Common Tangents and Tangent Circles.
After that calculate the 4 points on the tangent that intersect the circle:
def create_polygon(center1, radius1, center2, radius2):
cp1 = pygame.math.Vector2(center1)
cp2 = pygame.math.Vector2(center2)
cv = cp1 - cp2
nv = pygame.math.Vector2(-cv.y, cv.x).normalize() * (radius1 - radius2)
tnv1 = pygame.math.Vector2(-(cv.y + nv.y), cv.x + nv.x).normalize()
tnv2 = pygame.math.Vector2(cv.y - nv.y, -(cv.x - nv.x)).normalize()
pts = [cp1 + tnv1 * radius1, cp2 + tnv1 * radius2, cp2 + tnv2 * radius2, cp1 + tnv2 * radius1]
return [(p.x, p.y) for p in pts]
Minimal example
import pygame
pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()
cpt1 = (100, 200)
cpt2 = (300, 200)
radius = 40
def create_polygon(center1, radius1, center2, radius2):
cp1 = pygame.math.Vector2(center1)
cp2 = pygame.math.Vector2(center2)
cv = cp1 - cp2
nv = pygame.math.Vector2(-cv.y, cv.x).normalize() * (radius1 - radius2)
tnv1 = pygame.math.Vector2(-(cv.y + nv.y), cv.x + nv.x).normalize()
tnv2 = pygame.math.Vector2(cv.y - nv.y, -(cv.x - nv.x)).normalize()
pts = [cp1 + tnv1 * radius1, cp2 + tnv1 * radius2, cp2 + tnv2 * radius2, cp1 + tnv2 * radius1]
return [(p.x, p.y) for p in pts]
def draw_line_round_corners_polygon(surf, point_1, point_2, color, circle_radius):
points = create_polygon(point_1, circle_radius*2, point_2, circle_radius)
pygame.draw.polygon(surf, color, points)
pygame.draw.circle(surf, color, point_1, round(circle_radius*2))
pygame.draw.circle(surf, color, point_2, round(circle_radius))
run = True
while run:
clock.tick(100)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
window.fill("gray")
draw_line_round_corners_polygon(window, cpt1, cpt2, "red", radius)
pygame.display.flip()
pygame.quit()
exit()