I am working on a pygame project and I encountered a problem. I have two circles A and B as shown below. Which are overlapped Now I want to fill only some part of the circle which is common to both circles. Is there any way to achieve that?
I know I can fill circle B with red colour and circle A with white, but there is a certain area and circle A goes outside that area. So I cannot implement that.
The image of circles and filled position is mentioned in this image:
We can see that when the distance measure d is zero, the intersection area is π r 2 \pi r^2 πr2 with r being the smaller radius of both circles. If d is greater than the sum of both radii, the area of intersection is zero.
To draw a circle in your pygame project you can use draw. circle() function. The entire approach is the same as above only the function and parameters are changed accordingly.
A curved line in pygame can be as simple as using the pygame. draw. circle(surface,color,center,radius) and cropping part or most of it away. You can use trig functions to plot a curve, ect.
To draw a circle in your pygame project you can use draw.circle () function. The entire approach is the same as above only the function and parameters are changed accordingly. surface :- Here we can pass the surface on which we want to draw our circle. In the above example, we created a surface object named ‘window’.
Now, Create the surface object of a specific dimension using the display.set_mode () method of pygame. Fill the background of the surface object with white color using the fill () function of pygame. Create a rectangle using the draw.rect () method of pygame. Update the Surface object. Example 1: Drawing outlined rectangle using pygame.
Your task is to complete the function intersectionArea () which takes the coordinates of the centers as well as the radii (X1, Y1, R1, X2, Y2, R2) as input parameters and returns the area of intersection of the two circles.
Alternatively, you can just extract four functions ( slope (), y_intercept (), intersect () & segment_intersect ()) and use them as you see fit. The function intersect ( line1, line2 ) tries to compute the intersection of line1 and line2; it includes a primitive sort of guard against numeric overflow, and returns a point (a tuple (x,y)).
Create 2 pygame.Surface
objects with per pixel alpha (pygame.SRCALPHA
):
surf1 = pygame.Surface((500, 500), pygame.SRCALPHA)
surf2 = pygame.Surface((500, 500), pygame.SRCALPHA)
Define the center point and radius of the 2 circles:
pos1, rad1 = (250, 200), 100
pos2, rad2 = (250, 250), 80
Draw the circles on the 2 surfaces, with the same color:
pygame.draw.circle(surf1, (255, 0, 0, 255), pos1, rad1)
pygame.draw.circle(surf2, (255, 0, 0, 255), pos2, rad2)
Blend one surface on the other, using the blend mode pygame.BLEND_RGBA_MIN
:
surf1.blit(surf2, (0, 0), special_flags = pygame.BLEND_RGBA_MIN)
At this point surf1
contains the intersection area of the 2 circles.
To get the outer section, another step is required. Blend surf1
on surf2
, using the blend mode pygame.BLEND_RGBA_MIN
:
surf2.blit(surf1, (0, 0), special_flags = pygame.BLEND_RGBA_SUB)
Now surf2
contains the the part of circle B which is left if circle A is subtracted:
Minimal example: repl.it/@Rabbid76/PyGame-CircleIntersection
import pygame
pygame.init()
window = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
pos1, rad1 = (250, 200), 100
pos2, rad2 = (250, 250), 80
surf1 = pygame.Surface((500, 500), pygame.SRCALPHA)
surf2 = pygame.Surface((500, 500), pygame.SRCALPHA)
pygame.draw.circle(surf1, (255, 0, 0, 255), pos1, rad1)
pygame.draw.circle(surf2, (255, 0, 0, 255), pos2, rad2)
surf1.blit(surf2, (0, 0), special_flags = pygame.BLEND_RGBA_MIN)
surf2.blit(surf1, (0, 0), special_flags = pygame.BLEND_RGBA_SUB)
run = True
while run:
clock.tick(60)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
print(pygame.key.name(event.key))
window.fill((255, 255, 255))
window.blit(surf2, (0, 0))
pygame.draw.circle(window, (128, 128, 128), pos1, rad1+1, 3)
pygame.draw.circle(window, (128, 128, 128), pos2, rad2+1, 3)
pygame.display.flip()
I couldn't find a way to do it with pygame
functions, so I made a quick demo on how to do it yourself here:
import pygame
import math
import time
# Screen dimensions
WIDTH = 600
HEIGHT = 400
# Circle and screen colours
WHITE = (255, 255, 255)
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
# Circle data
BIGGER_POS = (300, 150)
SMALLER_POS = (300, 220)
BIGGER_RADIUS = 130
SMALLER_RADIUS = 100
BIGGER_COLOUR = GREEN
SMALLER_COLOUR = BLUE
INTERSECTION_COLOUR = RED
def prepare_screen():
"""
Create the initial screen.
"""
pygame.init()
screen = pygame.display.set_mode((WIDTH, HEIGHT))
screen.fill(WHITE)
return screen
def draw_circles(screen):
"""
Draw the circles and wait to visually inspect what they look like.
"""
bigger = pygame.draw.circle(screen, BIGGER_COLOUR, BIGGER_POS, BIGGER_RADIUS)
smaller = pygame.draw.circle(screen, SMALLER_COLOUR, SMALLER_POS, SMALLER_RADIUS)
pygame.display.update()
time.sleep(3)
return bigger, smaller
def calculate_distance(p1: tuple, p2: tuple):
"""
Calculate distance between two points p1 and p2.
"""
return math.sqrt(((p1[0] - p2[0])**2) + ((p1[1] - p2[1])**2))
def draw_intersection(screen, bigger, smaller):
"""
Animation to mark intersecting points with red.
Ideally this should only go through colliding points, but I'm lazy and made it iterate through all pixels
instead.
"""
for x in range(WIDTH):
for y in range(HEIGHT):
print("Checking point", x, y)
# A point is in the intersection if it's within the radius-es of both circles
if calculate_distance(bigger.center, (x, y)) <= BIGGER_RADIUS and \
calculate_distance(smaller.center, (x, y)) <= SMALLER_RADIUS:
screen.set_at((x, y), INTERSECTION_COLOUR)
pygame.display.update()
# Get screen to draw on
screen = prepare_screen()
# Draw some initial circles
bigger, smaller = draw_circles(screen)
# Draw the intersection
draw_intersection(screen, bigger, smaller)
# Finally sleep some to allow visual inspection, and quit
time.sleep(3)
pygame.quit()
Feel free to adjust as needed - note that various places can be optimised, made more readable etc.
Result:
Let me know if anything's unclear.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With