В общих чертах достигается Однородные координаты . Ваш подход близок к этому.
Я рекомендую оперировать Декартовыми координатами , где 3 измерения имеют одинаковый масштаб.
Эмулировать Перспективная проекция , когда выНарисуйте точки.
Это означает, что вы должны вычислить w
компонент Однородных координат в зависимости от глубины (координата z) точки (например, w = p[2] * 30 / 5000
) и выполнить«перспективное деление» компонентов x
, y
и z
на компонент * w
, перед тем как начертить точки. Например:
![](https://i.stack.imgur.com/Nwntm.gif)
#delta mov
ds=10
do=0.01
#Stars
points=[]
for i in range(1000):
n1 = random.randrange(-5000,5000)
n2 = random.randrange(-5000,5000)
n3 = random.randrange(-5000,5000)
points.append([n1,n2,n3])
while run:
pygame.time.delay(20)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run=False
################## keys
keys=pygame.key.get_pressed()
if keys[pygame.K_w]:
for p in points:
p[2]-=ds
if keys[pygame.K_s]:
for p in points:
p[2]+=ds
if keys[pygame.K_a] or keys[pygame.K_d]:
if keys[pygame.K_a]:
for p in points:
p[0], p[2] = np.cos(-do)*p[0]-np.sin(-do)*p[2], np.sin(-do)*p[0]+np.cos(-do)*p[2]
else:
for p in points:
p[0], p[2] = np.cos(do)*p[0]-np.sin(do)*p[2], np.sin(do)*p[0]+np.cos(do)*p[2]
###############################projection###################
screen.fill((0,0,0))
for p in points:
#this is to create new stars
if p[2]<=-5000 or p[2]>=5000:
p[0], p[1], p[2] = random.randrange(-5000,5000), random.randrange(-5000,5000), 5000
else:
#this is to ignore stars which are behind the ship
if p[2]<=0:
pass
else:
w = p[2] * 30 / 5000
pygame.draw.circle(screen,(255,255,0),(int(p[0]/w+center[0]),int(p[1]/w+center[1])),int(10/w))
pygame.display.update()
Более того, вращение не правильное. Когда вы делаете
p[0]=np.cos(-do)*p[0]-np.sin(-do)*p[2]
p[2]=np.sin(-do)*p[0]+np.cos(-do)*p[2]
, p[0]
изменяется в первой строке, но исходное значение должно использоваться во 2-й строке.
Выполните присвоение "tuple" длярешить вопрос:
p[0], p[2] = np.cos(-do)*p[0]-np.sin(-do)*p[2], np.sin(-do)*p[0]+np.cos(-do)*p[2]