Question

i have make the follow 3D cube , i need to make a translate function to move this cube for example with key up to move to axis x, with cube y to move in axis y,and right in axis z, i search to find a translate function but it's for 2D here but my mind stack and i am confuse.

Now i want the follow please, how can i anjust this translate function to my code, or have anyone any idea how to move,transate my cube to vertices3 of the code below?

Please someone help

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)

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("3D Wireframe Cube Simulation (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)
            ]

        self.vertices2 = [
            Point3D(-1,-1,-1),
            Point3D(-1,0,-1),
            Point3D(0,0,-1),
            Point3D(0,-1,-1),
            Point3D(-1,0,0),
            Point3D(0,0,0),
            Point3D(0,-1,0),
            Point3D(-1,-1,0)
            ]


        self.vertices3 = [
            Point3D(0,-1,-1),
            Point3D(0,0,-1),
            Point3D(1,0,-1),
            Point3D(1,-1,-1),
            Point3D(0,0,0),
            Point3D(1,0,0),
            Point3D(1,-1,0),
            Point3D(0,-1,0)
            ]

        # Define the vertices that compose each of the 6 faces. These numbers are
        # indices to the vertices list defined above.
        self.faces = [(0,1,2,3),(0,1,4,7),(4,5,6,7),(7,6,3,0),(5,6,3,2)]
        self.faces2 = [(0,1,2,3),(0,1,4,7),(4,5,6,7),(7,6,3,0),(5,6,3,2)]


        self.angleX, self.angleY, self.angleZ = 0, 0, 0

    def run(self):
        """ Main Loop """
        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))

            # Will hold transformed vertices.
            t = []
            t1 = []  

            for v in self.vertices:
                # Rotate the point around X axis, then around Y axis, and finally around Z axis.
                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)
                # Put the point in the list of transformed vertices
                t.append(p)
                x, y = int(p.x), int(p.y)
                self.screen.fill((255,0,0),(x,y,2,2))


            for v1 in self.vertices2:
                # Rotate the point around X axis, then around Y axis, and finally around Z axis.
                r1 = v1.rotateX(self.angleX).rotateY(self.angleY).rotateZ(self.angleZ)
                # Transform the point from 3D to 2D
                p1 = r1.project(self.screen.get_width(), self.screen.get_height(), 256, 4)
                # Put the point in the list of transformed vertices
                t1.append(p1)
                x, y = int(p1.x), int(p1.y)
                self.screen.fill((255,0,0),(x,y,3,3)) 

            for f in self.faces:
                pygame.draw.line(self.screen, (255,255,255), (t[f[0]].x, t[f[0]].y), (t[f[1]].x, t[f[1]].y))
                pygame.draw.line(self.screen, (255,255,255), (t[f[1]].x, t[f[1]].y), (t[f[2]].x, t[f[2]].y))
                pygame.draw.line(self.screen, (255,255,255), (t[f[2]].x, t[f[2]].y), (t[f[3]].x, t[f[3]].y))
                pygame.draw.line(self.screen, (255,255,255), (t[f[3]].x, t[f[3]].y), (t[f[0]].x, t[f[0]].y))


            for f1 in self.faces2:
                pygame.draw.line(self.screen, (255,255,255), (t1[f1[0]].x, t1[f1[0]].y), (t1[f1[1]].x, t1[f1[1]].y))
                pygame.draw.line(self.screen, (255,255,255), (t1[f1[1]].x, t1[f1[1]].y), (t1[f1[2]].x, t1[f1[2]].y))
                pygame.draw.line(self.screen, (255,255,255), (t1[f1[2]].x, t1[f1[2]].y), (t1[f1[3]].x, t1[f1[3]].y))
                pygame.draw.line(self.screen, (255,255,255), (t1[f1[3]].x, t1[f1[3]].y), (t1[f1[0]].x, t1[f1[0]].y))

            self.angleX += 1
            self.angleY += 1
            self.angleZ += 1

            pygame.display.flip()

if __name__ == "__main__":
    Simulation().run()
Was it helpful?

Solution

I find the answer for my question, and more, with the follow i can move,rotate and scale a cube you can find the code

here and here

Save the page as .py in the same folder, run the displaywireframe3 and that´s it .If you want to know the control keys check the code in displayWireframe3 guys.

OTHER TIPS

import pygame
import math
import numpy as np
import sys

'''
Not really sure but I think pygame needs to run under Python 3.6

Here is what I used:
Pycharm - Community Version
Python Ver:3.6
Pygame Ver:2.0.1
Numpy Ver: 1.19.3

Good Luck!
'''
print()
print("Python Ver: " + str(sys.version_info.major) + '.' + str(sys.version_info.minor))
print("Pygame Ver: " + pygame.__version__)
print("Numpy Ver:  " + np.__version__)

BLACK = (  0,   0,   0)
WHITE = (255, 255, 255)
GREEN = (  0, 255,   0)
RED   = (  0,   0, 255)

WDT = 640
HGT = 480

pygame.init()                                     # Set up pygame parameters
pygame.display.set_caption("Rotating 3D Cube Projection in PYGame")
screen = pygame.display.set_mode((WDT, HGT))

points = [n for n in range(8)]                   # Define 3D cube

points[0] = [[-1], [-1],  [1]]
points[1] = [[1],  [-1],  [1]]
points[2] = [[1],   [1],  [1]]
points[3] = [[-1],  [1],  [1]]
points[4] = [[-1], [-1], [-1]]
points[5] = [[1],  [-1], [-1]]
points[6] = [[1],   [1], [-1]]
points[7] = [[-1],  [1], [-1]]


def draw_line(i, j, k):                   # Draw lines between edges of cube
    a = k[i]
    b = k[j]
    pygame.draw.line(screen, GREEN, (a[0], a[1]), (b[0], b[1]), 2)


angle_x = 0                    # starting x position
angle_y = 0                    # starting y position
angle_z = 0                    # starting z position

cube_size = 600                # 300 = small   900 = large
distance_from_cube = 5         # view point distance - MUST BE GREATER THAN 1

while True:
    screen.fill(BLACK)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:    pygame.quit()
        if event.type == pygame.KEYDOWN: pygame.quit()

    projected_points = [j for j in range(len(points))]

    rotation_x = [[1,                 0,                  0],
                  [0, math.cos(angle_x), -math.sin(angle_x)],
                  [0, math.sin(angle_x),  math.cos(angle_x)]]

    rotation_y = [[math.cos(angle_y), 0, -math.sin(angle_y)],
                  [0,                 1,                  0],
                  [math.sin(angle_y), 0, math.cos(angle_y)]]

    rotation_z = [[math.cos(angle_z), -math.sin(angle_z), 0],
                  [math.sin(angle_z),  math.cos(angle_z), 0],
                  [0,              0,                     1]]

    index = 0
    for point in points:
        rotated_y = np.matmul(rotation_y, point)        # Cube rotation in y axis
        rotated_x = np.matmul(rotation_x, rotated_y)    # Cube rotation in yx axis
        rotated_xyz = np.matmul(rotation_z, rotated_x)  # Cube rotation in yxz axis

        z = 1 / (distance_from_cube - rotated_xyz[2][0])
        projection_matrix = [[z, 0, 0], [0, z, 0]]
        projected_2d = np.matmul(projection_matrix, rotated_xyz)

        x = int(projected_2d[0][0] * cube_size) + WDT // 2   # x,y 2D projection
        y = int(projected_2d[1][0] * cube_size) + HGT // 2

        projected_points[index] = [x, y]
        index += 1
        pygame.draw.circle(screen, RED, (x, y), 4)

    for m in range(4):                                 # Draw lines to connect dots/circles
        draw_line(m,       (m+1)%4, projected_points)
        draw_line(m+4, (m+1)%4 + 4, projected_points)
        draw_line(m,           m+4, projected_points)

    angle_x += 0.00030       # Rotation speed about x axis
    angle_y += 0.00020       # Rotation speed about y axis
    angle_z += 0.00010       # Rotation speed about z axis

    pygame.display.update()

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top