User Tools

Site Tools


3d_box_v1

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
3d_box_v1 [2024/09/20 00:53] – created appledog3d_box_v1 [2024/09/21 01:13] (current) appledog
Line 4: Line 4:
 The code will be presented as a monolithic file but it is intended that it be split into many files such as putting Object3d into it's own file, and then moving functions like rotate_x into there (maybe using staticmethod) or into their own library class. Object data could also stand to be moved out, maybe into an objects.py sort of class, or into files like cube.obj (i.e. cube.txt) which could be read in at runtime. The code will be presented as a monolithic file but it is intended that it be split into many files such as putting Object3d into it's own file, and then moving functions like rotate_x into there (maybe using staticmethod) or into their own library class. Object data could also stand to be moved out, maybe into an objects.py sort of class, or into files like cube.obj (i.e. cube.txt) which could be read in at runtime.
  
-== The Code+== The Code (Wireframe) 
 +<Code:Python> 
 +import pygame 
 +import sys 
 +import math 
 + 
 +# Initialize Pygame 
 +pygame.init() 
 + 
 +# Constants 
 +WIDTH, HEIGHT = 800, 600 
 +FOV = 256  # Field of view 
 +CAMERA_Z = 4  # Camera distance from the object 
 +SQUARE_SIZE = 1  # Half the size of the square for vertex calculations 
 +rotation_angles = [0, 0, 0]  # Rotation angles for x, y, z 
 + 
 +# Set up the display 
 +screen = pygame.display.set_mode((WIDTH, HEIGHT)) 
 +pygame.display.set_caption("Box"
 + 
 +# Square 
 +square_obj = [ 
 +    [  # Back face 
 +        [-SQUARE_SIZE, -SQUARE_SIZE, 0],  # Bottom left 
 +        [SQUARE_SIZE, -SQUARE_SIZE, 0],  # Bottom right 
 +        [SQUARE_SIZE, SQUARE_SIZE, 0],  # Top right 
 +        [-SQUARE_SIZE, SQUARE_SIZE, 0]  # Top left 
 +    ] 
 +
 + 
 +# Define the vertices of a 3D cube 
 +cube_obj = [ 
 +    [  # Back face 
 +        (-SQUARE_SIZE, -SQUARE_SIZE, -SQUARE_SIZE),  # Bottom left 
 +        (SQUARE_SIZE, -SQUARE_SIZE, -SQUARE_SIZE),  # Bottom right 
 +        (SQUARE_SIZE, SQUARE_SIZE, -SQUARE_SIZE),  # Top right 
 +        (-SQUARE_SIZE, SQUARE_SIZE, -SQUARE_SIZE)  # Top left 
 +    ], 
 +    [  # Front face 
 +        (-SQUARE_SIZE, -SQUARE_SIZE, SQUARE_SIZE),  # Bottom left 
 +        (SQUARE_SIZE, -SQUARE_SIZE, SQUARE_SIZE),  # Bottom right 
 +        (SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE),  # Top right 
 +        (-SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)  # Top left 
 +    ], 
 +    [  # Left face 
 +        (-SQUARE_SIZE, -SQUARE_SIZE, -SQUARE_SIZE),  # Bottom left 
 +        (-SQUARE_SIZE, -SQUARE_SIZE, SQUARE_SIZE),  # Bottom right 
 +        (-SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE),  # Top right 
 +        (-SQUARE_SIZE, SQUARE_SIZE, -SQUARE_SIZE)  # Top left 
 +    ], 
 +    [  # Right face 
 +        (SQUARE_SIZE, -SQUARE_SIZE, -SQUARE_SIZE),  # Bottom left 
 +        (SQUARE_SIZE, -SQUARE_SIZE, SQUARE_SIZE),  # Bottom right 
 +        (SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE),  # Top right 
 +        (SQUARE_SIZE, SQUARE_SIZE, -SQUARE_SIZE)  # Top left 
 +    ], 
 +    [  # Top face 
 +        (-SQUARE_SIZE, SQUARE_SIZE, -SQUARE_SIZE),  # Bottom left 
 +        (SQUARE_SIZE, SQUARE_SIZE, -SQUARE_SIZE),  # Bottom right 
 +        (SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE),  # Top right 
 +        (-SQUARE_SIZE, SQUARE_SIZE, SQUARE_SIZE)  # Top left 
 +    ], 
 +    [  # Bottom face 
 +        (-SQUARE_SIZE, -SQUARE_SIZE, -SQUARE_SIZE),  # Bottom left 
 +        (SQUARE_SIZE, -SQUARE_SIZE, -SQUARE_SIZE),  # Bottom right 
 +        (SQUARE_SIZE, -SQUARE_SIZE, SQUARE_SIZE),  # Top right 
 +        (-SQUARE_SIZE, -SQUARE_SIZE, SQUARE_SIZE)  # Top left 
 +    ] 
 +
 + 
 + 
 +# Function to project 3D points to 2D 
 +def project(point): 
 +    x, y, z = point 
 +    scale = FOV / (CAMERA_Z + z) 
 +    x_proj = int(x * scale + WIDTH // 2) 
 +    y_proj = int(-y * scale + HEIGHT // 2) 
 +    return (x_proj, y_proj) 
 + 
 + 
 +# Functions for rotating points 
 +def rotate_x(point, angle): 
 +    rad = math.radians(angle) 
 +    cos_angle = math.cos(rad) 
 +    sin_angle = math.sin(rad) 
 +    x, y, z = point 
 +    y_rotated = y * cos_angle - z * sin_angle 
 +    z_rotated = y * sin_angle + z * cos_angle 
 +    return (x, y_rotated, z_rotated) 
 + 
 + 
 +def rotate_y(point, angle): 
 +    rad = math.radians(angle) 
 +    cos_angle = math.cos(rad) 
 +    sin_angle = math.sin(rad) 
 +    x, y, z = point 
 +    x_rotated = z * sin_angle + x * cos_angle 
 +    z_rotated = z * cos_angle - x * sin_angle 
 +    return (x_rotated, y, z_rotated) 
 + 
 + 
 +def rotate_z(point, angle): 
 +    rad = math.radians(angle) 
 +    cos_angle = math.cos(rad) 
 +    sin_angle = math.sin(rad) 
 +    x, y, z = point 
 +    x_rotated = x * cos_angle - y * sin_angle 
 +    y_rotated = x * sin_angle + y * cos_angle 
 +    return (x_rotated, y_rotated, z) 
 + 
 + 
 +# Function to draw the cube using faces 
 +def draw_obj(position, faces): 
 +    face_data = [] 
 + 
 +    for index, face in enumerate(faces): 
 +        transformed_vertices = [] 
 + 
 +        # Transform each vertex 
 +        for vertex in face: 
 +            # Rotate the vertex around the Z-axis 
 +            vertex = rotate_z(vertex, rotation_angles[2]) 
 +            # Rotate the result around the Y-axis 
 +            vertex = rotate_y(vertex, rotation_angles[1]) 
 +            # Rotate the result around the X-axis 
 +            vertex = rotate_x(vertex, rotation_angles[0]) 
 +            # Append the transformed vertex 
 +            transformed_vertices.append(vertex) 
 + 
 +        projected_vertices = [] 
 + 
 +        # Project each transformed vertex to 2D 
 +        for vertex in transformed_vertices: 
 +            projected_vertex = project((vertex[0] + position[0], vertex[1] + position[1], vertex[2] + position[2])) 
 +            projected_vertices.append(projected_vertex) 
 + 
 +        pygame.draw.polygon(screen, color, projected_vertices)  # Fill the polygon with color 
 + 
 + 
 +def draw_obj(position, faces): 
 +    for face in faces: 
 +        transformed_vertices = [ 
 +            rotate_x(rotate_y(rotate_z(vertex, rotation_angles[2]), rotation_angles[1]), rotation_angles[0]) 
 +            for vertex in face 
 +        ] 
 +        projected_vertices = [project((x + position[0], y + position[1], z + position[2])) for (x, y, z) in 
 +                              transformed_vertices] 
 + 
 +        # Draw the polygon face 
 +        pygame.draw.polygon(screen, "white", projected_vertices, True) 
 + 
 + 
 +# Main loop 
 +def main(): 
 +    clock = pygame.time.Clock() 
 +    position = [0, 0, 0]  # Initial position of the cube 
 + 
 +    while True: 
 +        for event in pygame.event.get(): 
 +            if event.type == pygame.QUIT: 
 +                pygame.quit() 
 +                sys.exit() 
 + 
 +        keys = pygame.key.get_pressed() 
 + 
 +        # Movement controls 
 +        if keys[pygame.K_UP]:  # Move forward along Z 
 +            position[2] += 0.1 
 +        if keys[pygame.K_DOWN]:  # Move backward along Z 
 +            position[2] -= 0.1 
 +        if keys[pygame.K_a]:  # Move left along X 
 +            position[0] -= 0.1 
 +        if keys[pygame.K_d]:  # Move right along X 
 +            position[0] += 0.1 
 +        if keys[pygame.K_w]:  # Move up along Y 
 +            position[1] += 0.1 
 +        if keys[pygame.K_s]:  # Move down along Y 
 +            position[1] -= 0.1 
 + 
 +        # Rotation controls 
 +        if keys[pygame.K_1]:  # Rotate around X-axis 
 +            rotation_angles[0] += 1 
 +        if keys[pygame.K_2]:  # Rotate around X-axis 
 +            rotation_angles[0] -= 1 
 +        if keys[pygame.K_3]:  # Rotate around Y-axis 
 +            rotation_angles[1] += 1 
 +        if keys[pygame.K_4]:  # Rotate around Y-axis 
 +            rotation_angles[1] -= 1 
 +        if keys[pygame.K_5]:  # Rotate around Z-axis 
 +            rotation_angles[2] += 1 
 +        if keys[pygame.K_6]:  # Rotate around Z-axis 
 +            rotation_angles[2] -= 1 
 + 
 +        # Fill the screen with black 
 +        screen.fill((0, 0, 0)) 
 + 
 +        # Draw the cube using polygons 
 +        draw_obj(position, cube_obj) 
 + 
 +        # Draw the bounding box (optional) 
 +        pygame.draw.rect(screen, "red", (0, 0, WIDTH, HEIGHT), 1) 
 + 
 +        # Update the display 
 +        pygame.display.flip() 
 +        clock.tick(60) 
 + 
 + 
 +if __name__ == "__main__": 
 +    main() 
 + 
 +</Code> 
 + 
 +== The Code (with Simple Z-avg and fill)
 <Code:Python> <Code:Python>
 import pygame import pygame
Line 224: Line 436:
 if __name__ == "__main__": if __name__ == "__main__":
     main()     main()
 +</Code>
 +
 +=== Adding Scaling
 +<Code:Python>
 +class Object3D:
 +    def __init__(self, vertices, position=(0, 0, 0)):
 +        self.vertices = vertices
 +        self.position = list(position)
 +        self.rotation = [0, 0, 0]  # Rotation angles for x, y, z
 +        self.scale_factors = [1, 1, 1]  # Scaling factors for x, y, z
 +
 +    def rotate(self, angle_x, angle_y, angle_z):
 +        self.rotation[0] += angle_x
 +        self.rotation[1] += angle_y
 +        self.rotation[2] += angle_z
 +
 +    def move(self, dx, dy, dz):
 +        self.position[0] += dx
 +        self.position[1] += dy
 +        self.position[2] += dz
 +
 +    def scale(self, scale_x, scale_y, scale_z):
 +        """Set the scaling factors for the object."""
 +        self.scale_factors = [scale_x, scale_y, scale_z]
 +
 +    def get_transformed_vertices(self):
 +        transformed_faces = []
 +        for face in self.vertices:
 +            transformed_face = [
 +                rotate_x(
 +                    rotate_y(
 +                        rotate_z(
 +                            (x * self.scale_factors[0], y * self.scale_factors[1], z * self.scale_factors[2]),
 +                            self.rotation[2]),
 +                        self.rotation[1]),
 +                    self.rotation[0])
 +                for (x, y, z) in face
 +            ]
 +            transformed_faces.append(transformed_face)
 +        return transformed_faces
 </Code> </Code>
3d_box_v1.1726793588.txt.gz · Last modified: 2024/09/20 00:53 by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki