Transformações no Espaço e Projeção Cônica: Implementação

De Aulas

Afluentes: Computação Gráfica

space.py

import sys
import math
import pygame


class Point:
    x = None
    y = None
    z = None

    def __init__(self, vet):
        self.x = vet[0]
        self.y = vet[1]
        self.z = vet[2]

    def copy(self, p):
        self.x = p.x
        self.y = p.y
        self.z = p.z

    def get(self):
        return [self.x, self.y, self.z]


class Cube:
    screen = None
    point = []

    def __init__(self, screen):
        self.screen = screen
        self.point += [Point([0, 0, 0])]
        self.point += [Point([-50, -50, -50])]
        self.point += [Point([+50, -50, -50])]
        self.point += [Point([+50, +50, -50])]
        self.point += [Point([-50, +50, -50])]
        self.point += [Point([-50, -50, +50])]
        self.point += [Point([+50, -50, +50])]
        self.point += [Point([+50, +50, +50])]
        self.point += [Point([-50, +50, +50])]
        self.translate(0, 0, 300)

    def translate(self, tx, ty, tz):
        for p in self.point:
            p.x += tx
            p.y += ty
            p.z += tz

    def scale(self, sx, sy, sz):
        pivot = Point(self.point[0].get())
        self.translate(-pivot.x, -pivot.y, -pivot.z)
        for p in self.point:
            p.x *= sx
            p.y *= sy
            p.z *= sz
        self.translate(pivot.x, pivot.y, pivot.z)

    def rotate_x(self, angle):
        angle /= 100
        pivot = Point(self.point[0].get())
        self.translate(-pivot.x, -pivot.y, -pivot.z)
        for p in self.point:
            y = p.y
            z = p.z
            p.y = (y * math.cos(angle)) - (z * math.sin(angle))
            p.z = (z * math.cos(angle)) + (y * math.sin(angle))
        self.translate(pivot.x, pivot.y, pivot.z)

    def rotate_y(self, angle):
        angle /= 100
        pivot = Point(self.point[0].get())
        self.translate(-pivot.x, -pivot.y, -pivot.z)
        for p in self.point:
            x = p.x
            z = p.z
            p.x = (x * math.cos(angle)) - (z * math.sin(angle))
            p.z = (z * math.cos(angle)) + (x * math.sin(angle))
        self.translate(pivot.x, pivot.y, pivot.z)

    def rotate_z(self, angle):
        angle /= 100
        pivot = Point(self.point[0].get())
        self.translate(-pivot.x, -pivot.y, -pivot.z)
        for p in self.point:
            x = p.x
            y = p.y
            p.x = (x * math.cos(angle)) - (y * math.sin(angle))
            p.y = (y * math.cos(angle)) + (x * math.sin(angle))
        self.translate(pivot.x, pivot.y, pivot.z)

    def line(self, p1, p2):
        pygame.draw.line(self.screen, Color_line, (p1.x, p1.y), (p2.x, p2.y))

    def perpective(self, i, point):
        if conical and point.z != 0:
            point.x = (DISTANCE / point.z) * point.x
            point.y = (DISTANCE / point.z) * point.y

    def draw(self):
        p = []
        for i in range(9):
            point = Point(self.point[i].get())
            self.perpective(i, point)
            point.x += 400
            point.y += 300
            p += [point]

        self.screen.fill(Color_screen)
        self.line(p[0], p[0])  # draw point over pivot
        for i in range(3):
            self.line(p[i + 1], p[i + 2])
            self.line(p[i + 5], p[i + 5 + 1])
            self.line(p[i + 1], p[i + 5])
        self.line(p[4], p[1])
        self.line(p[8], p[4])
        self.line(p[5], p[8])
        pygame.display.flip()

    def change(self, move):
        if move == "translate_left":
            self.translate(-SPEED, 0, 0)
        elif move == "translate_right":
            self.translate(SPEED, 0, 0)
        elif move == "translate_up":
            self.translate(0, -SPEED, 0)
        elif move == "translate_down":
            self.translate(0, SPEED, 0)
        elif move == "translate_front":
            self.translate(0, 0, SPEED)
        elif move == "translate_back":
            self.translate(0, 0, -SPEED)
        elif move == "rotate_y_left":
            self.rotate_y(-SPEED)
        elif move == "rotate_y_right":
            self.rotate_y(SPEED)
        elif move == "rotate_x_up":
            self.rotate_x(SPEED)
        elif move == "rotate_x_down":
            self.rotate_x(-SPEED)
        elif move == "rotate_z_right":
            self.rotate_z(SPEED)
        elif move == "rotate_z_left":
            self.rotate_z(-SPEED)


SPEED = 2
width = 800
height = 600
Color_screen = (0, 0, 0)
Color_line = (255, 255, 255)
conical = False
DISTANCE = 300


def main():
    global conical
    screen = pygame.display.set_mode((width, height))
    cube = Cube(screen)
    cube.draw()
    move = ""
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit(0)
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    move = "translate_left"
                elif event.key == pygame.K_RIGHT:
                    move = "translate_right"
                elif event.key == pygame.K_DOWN:
                    move = "translate_down"
                elif event.key == pygame.K_UP:
                    move = "translate_up"
                elif event.key == pygame.K_q:
                    move = "translate_back"
                elif event.key == pygame.K_e:
                    move = "translate_front"
                elif event.key == pygame.K_a:
                    move = "rotate_y_left"
                elif event.key == pygame.K_d:
                    move = "rotate_y_right"
                elif event.key == pygame.K_w:
                    move = "rotate_x_up"
                elif event.key == pygame.K_s:
                    move = "rotate_x_down"
                elif event.key == pygame.K_x:
                    move = "rotate_z_right"
                elif event.key == pygame.K_z:
                    move = "rotate_z_left"
                elif event.key == pygame.K_c:
                    conical = not conical
                elif event.key == pygame.K_ESCAPE:
                    sys.exit(0)
            elif event.type == pygame.KEYUP:
                move = ""
        cube.change(move)
        cube.draw()


main()