Skip to content

Instantly share code, notes, and snippets.

@kylelk
Created April 4, 2017 02:57
Show Gist options
  • Save kylelk/051328cf3a3a5d2184c3f6fbb2f26c59 to your computer and use it in GitHub Desktop.
Save kylelk/051328cf3a3a5d2184c3f6fbb2f26c59 to your computer and use it in GitHub Desktop.
import sys, math, pygame
class Point3D():
def __init__(self, x=0, y=0, z=0):
self.x, self.y, self.z = float(x), float(y), float(z)
def rotateX(self, angle):
""" Rotates the point around the X axis by the given angle in degrees. """
rad = angle * math.pi / 180
cosa = math.cos(rad)
sina = math.sin(rad)
y = self.y * cosa - self.z * sina
z = self.y * sina + self.z * cosa
return Point3D(self.x, y, z)
def rotateY(self, angle):
""" Rotates the point around the Y axis by the given angle in degrees. """
rad = angle * math.pi / 180
cosa = math.cos(rad)
sina = math.sin(rad)
z = self.z * cosa - self.x * sina
x = self.z * sina + self.x * cosa
return Point3D(x, self.y, z)
def rotateZ(self, angle):
""" Rotates the point around the Z axis by the given angle in degrees. """
rad = angle * math.pi / 180
cosa = math.cos(rad)
sina = math.sin(rad)
x = self.x * cosa - self.y * sina
y = self.x * sina + self.y * cosa
return Point3D(x, y, self.z)
def project(self, win_width, win_height, fov, viewer_distance):
""" Transforms this 3D point to 2D using a perspective projection. """
factor = fov / (viewer_distance + self.z)
x = self.x * factor + win_width / 2
y = -self.y * factor + win_height / 2
return Point3D(x, y, 1)
def get_cube_edges(center: Point3D, width: float, height: float, length: float) -> list:
edges = [
# front left bottom
# front left top
# front right bottom
# front right top
# back left bottom
# back left top
# back right bottom
# back right top
]
return edges
class Simulation():
def __init__(self, win_width=640, win_height=480):
pygame.init()
self.screen = pygame.display.set_mode((win_width, win_height))
pygame.display.set_caption("Simulation of 3D Point Rotation (http://codentronix.com)")
self.clock = pygame.time.Clock()
self.vertices = [
Point3D(-1, 1, -1),
Point3D(1, 1, -1),
Point3D(1, -1, -1),
Point3D(-1, -1, -1),
Point3D(-1, 1, 1),
Point3D(1, 1, 1),
Point3D(1, -1, 1),
Point3D(-1, -1, 1)
]
edges = [
]
self.angleX, self.angleY, self.angleZ = 0, 0, 0
def run(self):
while 1:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
self.clock.tick(50)
self.screen.fill((0, 0, 0))
self.angleX = 0
self.angleY = 5
self.angleZ = 0
for v in self.vertices:
# Rotate the point around X axis, then around Y axis, and finally around Z axis.
#start_vertex = self.vertices[i].rotateX(self.angleX).rotateY(self.angleY).rotateZ(self.angleZ)
#end_vertex = self.vertices[i+1].rotateX(self.angleX).rotateY(self.angleY).rotateZ(self.angleZ)
r = v.rotateX(self.angleX).rotateY(self.angleY).rotateZ(self.angleZ)
# Transform the point from 3D to 2D
p = r.project(self.screen.get_width(), self.screen.get_height(), 256, 4)
self.screen.fill((255, 255, 255), (int(p.x), int(p.y), 2, 2))
#self.angleX += 1
#self.angleY += 1
#self.angleZ += 1
pygame.display.flip()
if __name__ == "__main__":
Simulation().run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment