Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
927 views
in Technique[技术] by (71.8m points)

random - Python Pygame randomly draw non overlapping circles

Im very new to python and seem to be missing something.
I want to randomly draw circles on a pygame display but only if the circles don't overlap each other.
I believe I must find the distance between all circle centers and only draw it if the distance is bigger than circle radius * 2.

I've tried many different things but all without success, I always get the same result - circles drawn overlapping.

#!/usr/bin/env python

import pygame, random, math

red = (255, 0, 0)
width = 800
height = 600
circle_num = 10
tick = 2
speed = 5

pygame.init()
screen = pygame.display.set_mode((width, height))

class circle():
    def __init__(self):
        self.x = random.randint(0,width)
        self.y = random.randint(0,height)
        self.r = 100

    def new(self):
        pygame.draw.circle(screen, red, (self.x,self.y), self.r, tick)

c = []
for i in range(circle_num):
    c.append('c'+str(i))
    c[i] = circle()
    for j in range(len(c)):
        dist = int(math.hypot(c[i].x - c[j].x, c[i].y - c[j].y))
        if dist > int(c[i].r*2 + c[j].r*2):
            c[j].new()
            pygame.display.update()

        else:
            continue

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            quit()
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The for loop has been changed to a while loop. It will keep trying to generate circles until the target number is reached. A circle is first generated. Then, it checks if it intersects with any existing circle using the formula from this answer.

It iterates through every existing circle (store in the list circles) and performs the check using the formula. any() returns True if the formula evaluates to True for any iteration. If it's True, it means it found an intersection. Thus, it continues to the next iteration to try again with a new circle.

circles = []
while len(circles) < circle_num:
    new = circle()

    if any(pow(c.r - new.r, 2) <=
           pow(c.x - new.x, 2) + pow(c.y - new.y, 2) <=
           pow(c.r + new.r, 2)
       for c in circles):
        continue

    circles.append(new)
    new.new()
    pygame.display.update()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...