Reputation: 31
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
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
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