Sarah Unan
Sarah Unan

Reputation: 31

How to plot circles every 20 pixels between two randomly generated points in Pygame?

The homework question I'm working on is the following:

"Draw two randomly placed radius 10 circles on the screen then draw radius 2 circles every twenty pixels from the center of one to the center of the other."

I'm having no trouble randomly generating the two radius 10 circles, but I have no idea how to plot the radius 2 circles between them.

I've tried briefly to plot a line between them, and if there's a way to plot my points along that line, I could definitely do that. I've looked up similar issues and a lot of them mention Bresenham's line algorithm but I doubt that is the answer as it seems very advanced.

Here is the code I have so far for the problem:

import pygame
from random import randint

linecolour = 0,0,0
bgcolour = 255, 255, 255
width = 600
height = 600

screen = pygame.display.set_mode((width, height))
running = 1

x = []
y = []

for i in range (2):
    x.append(randint(0,600))
    y.append(randint(0,600))


done = False
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT: # or other types of events
            done = True

    screen.fill(bgcolour)

    for i,j in zip(x,y):
        pygame.draw.circle(screen,linecolour,(i,j),10)

        pygame.draw.circle(screen,linecolour,(i,j),2)

    pygame.display.flip()

Upvotes: 3

Views: 187

Answers (2)

Mad Physicist
Mad Physicist

Reputation: 114230

This is a very simple problem if you look at it the right way. I would recommend looking at it in terms of polar coordinates. If you have two circles centered at (x[0], y[0]) and (x[1], y[1]), the slope of the line between them is (y[1] - y[0]) / (x[1] - x[0]), but you can also look at the angle of the line:

phi = math.atan2(y[0] - y[1], x[0] - x[1])

The distance from one center to the other is given by

r = math.hypot(y[0] - y[1], x[0] - x[1])

Now you can easily step along the line from (x[0], y[0]) at an angle of phi in steps of 20 until your distance exceeds r. The x-coorindate of the i-th step will be

i * 20 * math.cos(phi)

Similarly the y-coordinate will be

i * 20 * math.sin(phi)

You can calculate the total number of steps as r // 20. Also, math.sin(math.atan2(y, x)) simplifies to y / math.hypot(y, x) and the similar cosine simplifies to x / math.hypot(y, x). So all in all, you get

sep = 20
dx = x[1] - x[0]
dy = y[1] - y[0]
r = math.hypot(dy, dx)
n = int(r // sep)
x_step = sep * dx / r
y_step = sep * dy / r
coords = [(x[0] + i * x_step, y[0] + i * y_step) for i in range(n)]

If you need integer coordinates:

coords = [(x[0] + int(i * x_step), y[0] + int(i * y_step)) for i in range(n)]

To plot:

for coord in [(x[0] + int(i * x_step), y[0] + int(i * y_step)) for i in range(n)]:
    pygame.draw.circle(screen, linecolour, coord, 2)

Upvotes: 2

Rabbid76
Rabbid76

Reputation: 210889

Calculate the direction vector from 1 point to the other:

dir = x[1]-x[0], y[1]-y[0]

Calculate the Euclidean distance between the points. Note you've to import math:

dist = math.sqrt(dir[0]*dir[0] + dir[1]*dir[1])

or as pointed out in the answer of @MadPhysicist

dist = math.hypot(*dir)

the number of points to be drawn is int(dist) // 20. Calculate the points on the line in a loop:

for i in range(int(dist) // 20):
    px = int(x[0] + dir[0] * i*20/dist)
    py = int(y[0] + dir[1] * i*20/dist)

The code to draw the small points may look like this:

done = False
while not done:

    # [...]

    dir = x[1]-x[0], y[1]-y[0]
    dist = math.hypot(*dir)
    for i in range(1, int(dist) // 20 + 1):
        pt = int(x[0] + dir[0] * i*20/dist), int(y[0] + dir[1] *i*20/dist)
        pygame.draw.circle(screen, linecolour, pt, 2)

Upvotes: 2

Related Questions