I want to project a 3d point onto a 2d plane (screen).
Here is my code as well as the class that converts 3d coordinate to 2d coordinate.
The class to convert 3d coordinate to 2d coordinate:
class dtod(pygame.sprite.Sprite):
def __init__(self, point, scale):
super().__init__()
self.point = numpy.array(point)
width, height = pygame.display.get_surface().get_size()
self.angle = 0
self.point[0] = (self.point[0] * 1) / self.point[2]
self.point[1] = (self.point[1] * 1) / self.point[2]
self.projection = numpy.array(
[[math.cos(self.angle), math.sin(self.angle), 0.], [math.sin(self.angle), math.cos(self.angle), 0.]])
self.point = numpy.dot(self.projection, self.point)
self.point = ((self.point[0] * scale) + width / 2, height / 2 - (self.point[1] * scale))
The main code where I draw the things:
import pygame
import numpy as np
from coord import dtod
import math
pygame.init()
screen = pygame.display.set_mode((0, 0))
run = True
width, height = screen.get_size()
colors = {"white": (255, 255, 255), "red": (255, 0, 0), "green": (150, 253, 55), "blue": (0,
227, 227), "orange": (255, 127, 39), "grey": (64, 64, 64), "yellow": (255, 240, 0)}
tx, ty, tz = 0., 0., 0.
fps = pygame.time.Clock()
def cos(x):
return math.cos(x)
def sin(x):
return math.sin(x)
rx = np.array([[1., 0., 0.], [0., cos(tx), -sin(tx)], [0., sin(tx), cos(tx)]])
ry = np.array([[cos(ty), 0., sin(ty)], [0., 1., 0.], [-sin(ty), 0., cos(ty)]])
rz = np.array([[cos(tz), -sin(ty), 0.], [sin(ty), cos(ty), 0.], [0., 0., 1.]])
scale = 200
p1 = np.array([0.5, 0.5, 1.])
p2 = np.array([-0.5, 0.5, 1.])
p3 = np.array([-0.5, -0.5, 1.])
p4 = np.array([0.5, -0.5, 1.])
p5 = np.array([0.5, 0.5, -2.])
p6 = np.array([-0.5, 0.5, -2.])
p7 = np.array([-0.5, -0.5, -2.])
p8 = np.array([0.5, -0.5, -2.])
def transform(tx, ty, tz):
global rx, ry, rz, p1, p2, p3, p4, p5, p6, p7, p8
rx = np.array([[1., 0., 0.], [0., cos(tx), -sin(tx)], [0., sin(tx), cos(tx)]])
ry = np.array([[cos(ty), 0., sin(ty)], [0., 1., 0.], [-sin(ty), 0., cos(ty)]])
rz = np.array([[cos(tz), -sin(ty), 0.], [sin(ty), cos(ty), 0.], [0., 0., 1.]])
p1 = np.dot(rx, p1)
p1 = np.dot(ry, p1)
p1 = np.dot(rz, p1)
p2 = np.dot(rx, p2)
p2 = np.dot(ry, p2)
p2 = np.dot(rz, p2)
p3 = np.dot(rx, p3)
p3 = np.dot(ry, p3)
p3 = np.dot(rz, p3)
p4 = np.dot(rx, p4)
p4 = np.dot(ry, p4)
p4 = np.dot(rz, p4)
p5 = np.dot(rx, p5)
p5 = np.dot(ry, p5)
p5 = np.dot(rz, p5)
p6 = np.dot(rx, p6)
p6 = np.dot(ry, p6)
p6 = np.dot(rz, p6)
p7 = np.dot(rx, p7)
p7 = np.dot(ry, p7)
p7 = np.dot(rz, p7)
p8 = np.dot(rx, p8)
p8 = np.dot(ry, p8)
p8 = np.dot(rz, p8)
while run:
screen.fill((0, 0, 0))
fps.tick(60)
transform(tx, ty, tz)
pygame.draw.circle(screen, colors["white"], dtod(p1, scale).point, 5)
pygame.draw.circle(screen, colors["white"], dtod(p2, scale).point, 5)
pygame.draw.circle(screen, colors["white"], dtod(p3, scale).point, 5)
pygame.draw.circle(screen, colors["white"], dtod(p4, scale).point, 5)
pygame.draw.circle(screen, colors["white"], dtod(p5, scale).point, 5)
pygame.draw.circle(screen, colors["white"], dtod(p6, scale).point, 5)
pygame.draw.circle(screen, colors["white"], dtod(p7, scale).point, 5)
pygame.draw.circle(screen, colors["white"], dtod(p8, scale).point, 5)
pygame.draw.line(screen, colors["white"], dtod(p1, scale).point, dtod(p2, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p2, scale).point, dtod(p3, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p3, scale).point, dtod(p4, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p4, scale).point, dtod(p1, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p5, scale).point, dtod(p6, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p6, scale).point, dtod(p7, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p7, scale).point, dtod(p8, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p8, scale).point, dtod(p5, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p1, scale).point, dtod(p5, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p6, scale).point, dtod(p2, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p7, scale).point, dtod(p3, scale).point)
pygame.draw.line(screen, colors["white"], dtod(p8, scale).point, dtod(p4, scale).point)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r:
run = False
pygame.display.update()
pygame.quit()
The logic I used:
I m using orthographic projection technique, and to get a feel of perception, I m dividing the x and y coordinates by depth (z-component) before actually converting 3d->2d.
Thank you in advance