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?

Asked By: 3kstc

||

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()
Answered By: Rabbid76
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.