def rotate_vector2(vec2, degrees): rotation_matrix = Matrix44.z_rotation(math.radians(degrees)) transformed = rotation_matrix.transform_vec3(Vector3(vec2.x, vec2.y, 0)) return Vector2(transformed.x, transformed.y)
def run(): pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE, 0) font = pygame.font.SysFont("courier new", 16, True) ball = pygame.image.load("map.png").convert_alpha() points = [] fov = 75. # Field of view viewing_distance = calculate_viewing_distance(radians(fov), SCREEN_SIZE[0]) # Create a list of points along the edge of a cube for x in xrange(0, CUBE_SIZE+1, 10): edge_x = x == 0 or x == CUBE_SIZE for y in xrange(0, CUBE_SIZE+1, 10): edge_y = y == 0 or y == CUBE_SIZE for z in xrange(0, CUBE_SIZE+1, 10): edge_z = z == 0 or z == CUBE_SIZE if sum((edge_x, edge_y, edge_z)) >= 2: point_x = float(x) - CUBE_SIZE/2 point_y = float(y) - CUBE_SIZE/2 point_z = float(z) - CUBE_SIZE/2 points.append(Vector3(point_x, point_y, point_z)) def point_z(point): return point[2] center_x, center_y = SCREEN_SIZE center_x /= 2 center_y /= 2 ball_w, ball_h = ball.get_size() ball_center_x = ball_w / 2 ball_center_y = ball_h / 2 camera_position = Vector3(0.0, 0.0, 600.) rotation = Vector3() rotation_speed = Vector3(radians(20), radians(20), radians(20)) clock = pygame.time.Clock() # Some colors for drawing red = (255, 0, 0) green = (0, 255, 0) blue = (0, 0, 255) white = (255, 255, 255) # Labels for the axes x_surface = font.render("X", True, white) y_surface = font.render("Y", True, white) z_surface = font.render("Z", True, white) while True: for event in pygame.event.get(): if event.type == QUIT: return screen.fill((0, 0, 0)) time_passed = clock.tick() time_passed_seconds = time_passed / 1000. rotation_direction = Vector3() #Adjust the rotation direction depending on key presses pressed_keys = pygame.key.get_pressed() if pressed_keys[K_q]: rotation_direction.x = +1.0 elif pressed_keys[K_a]: rotation_direction.x = -1.0 if pressed_keys[K_w]: rotation_direction.y = +1.0 elif pressed_keys[K_s]: rotation_direction.y = -1.0 if pressed_keys[K_e]: rotation_direction.z = +1.0 elif pressed_keys[K_d]: rotation_direction.z = -1.0 # Apply time based movement to rotation rotation += rotation_direction * rotation_speed * time_passed_seconds # Build the rotation matrix rotation_matrix = Matrix.x_rotation(rotation.x) rotation_matrix *= Matrix.y_rotation(rotation.y) rotation_matrix *= Matrix.z_rotation(rotation.z) transformed_points = [] # Transform all the points and adjust for camera position for point in points: p = rotation_matrix.transform_vec3(point) - camera_position transformed_points.append(p) transformed_points.sort(key=point_z) # Perspective project and blit all the points for x, y, z in transformed_points: if z < 0: x = center_x + x * -viewing_distance / z y = center_y + -y * -viewing_distance / z screen.blit(ball, (x-ball_center_x, y-ball_center_y)) # Function to draw a single axes, see below def draw_axis(color, axis, label): axis = rotation_matrix.transform_vec3(axis * 150.) SCREEN_SIZE = (640, 480) center_x = SCREEN_SIZE[0] / 2.0 center_y = SCREEN_SIZE[1] / 2.0 x, y, z = axis - camera_position x = center_x + x * -viewing_distance / z y = center_y + -y * -viewing_distance / z pygame.draw.line(screen, color, (center_x, center_y), (x, y), 2) w, h = label.get_size() screen.blit(label, (x-w/2, y-h/2)) # Draw the x, y and z axes x_axis = Vector3(1, 0, 0) y_axis = Vector3(0, 1, 0) z_axis = Vector3(0, 0, 1) draw_axis(red, x_axis, x_surface) draw_axis(green, y_axis, y_surface) draw_axis(blue, z_axis, z_surface) # Display rotation information on screen degrees_txt = tuple(degrees(r) for r in rotation) rotation_txt = "Rotation: Q/A %.3f, W/S %.3f, E/D %.3f" % degrees_txt txt_surface = font.render(rotation_txt, True, white) screen.blit(txt_surface, (5, 5)) # Displat the rotation matrix on screen matrix_txt = str(rotation_matrix) txt_y = 25 for line in matrix_txt.split('\n'): txt_surface = font.render(line, True, white) screen.blit(txt_surface, (5, txt_y)) txt_y += 20 pygame.display.update()
def run(): pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE, 0) font = pygame.font.SysFont("courier new", 16, True) ball = pygame.image.load("ball.png").convert_alpha() points = [] fov = 75.0 # Field of view viewing_distance = calculate_viewing_distance(radians(fov), SCREEN_SIZE[0]) # Create a list of points along the edge of a cube for x in range(0, CUBE_SIZE + 1, 10): edge_x = x == 0 or x == CUBE_SIZE for y in range(0, CUBE_SIZE + 1, 10): edge_y = y == 0 or y == CUBE_SIZE for z in range(0, CUBE_SIZE + 1, 10): edge_z = z == 0 or z == CUBE_SIZE if sum((edge_x, edge_y, edge_z)) >= 2: point_x = float(x) - CUBE_SIZE / 2 point_y = float(y) - CUBE_SIZE / 2 point_z = float(z) - CUBE_SIZE / 2 points.append(Vector3(point_x, point_y, point_z)) def point_z(point): return point[2] center_x, center_y = SCREEN_SIZE center_x /= 2 center_y /= 2 ball_w, ball_h = ball.get_size() ball_center_x = ball_w / 2 ball_center_y = ball_h / 2 camera_position = Vector3(0.0, 0.0, 600.0) rotation = Vector3() rotation_speed = Vector3(radians(20), radians(20), radians(20)) clock = pygame.time.Clock() # Some colors for drawing red = (255, 0, 0) green = (0, 255, 0) blue = (0, 0, 255) white = (255, 255, 255) # Labels for the axes x_surface = font.render("X", True, white) y_surface = font.render("Y", True, white) z_surface = font.render("Z", True, white) while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() quit() screen.fill((0, 0, 0)) time_passed = clock.tick() time_passed_seconds = time_passed / 1000.0 rotation_direction = Vector3() # Adjust the rotation direction depending on key presses pressed_keys = pygame.key.get_pressed() if pressed_keys[K_q]: rotation_direction.x = +1.0 elif pressed_keys[K_a]: rotation_direction.x = -1.0 if pressed_keys[K_w]: rotation_direction.y = +1.0 elif pressed_keys[K_s]: rotation_direction.y = -1.0 if pressed_keys[K_e]: rotation_direction.z = +1.0 elif pressed_keys[K_d]: rotation_direction.z = -1.0 # Apply time based movement to rotation rotation += rotation_direction * rotation_speed * time_passed_seconds # Build the rotation matrix rotation_matrix = Matrix.x_rotation(rotation.x) rotation_matrix *= Matrix.y_rotation(rotation.y) rotation_matrix *= Matrix.z_rotation(rotation.z) transformed_points = [] # Transform all the points and adjust for camera position for point in points: p = rotation_matrix.transform_vec3(point) - camera_position transformed_points.append(p) transformed_points.sort(key=point_z) # Perspective project and blit all the points for x, y, z in transformed_points: if z < 0: x = center_x + x * -viewing_distance / z y = center_y + -y * -viewing_distance / z screen.blit(ball, (x - ball_center_x, y - ball_center_y)) # Function to draw a single axes, see below def draw_axis(color, axis, label): axis = rotation_matrix.transform_vec3(axis * 150.0) SCREEN_SIZE = (640, 480) center_x = SCREEN_SIZE[0] / 2.0 center_y = SCREEN_SIZE[1] / 2.0 x, y, z = axis - camera_position x = center_x + x * -viewing_distance / z y = center_y + -y * -viewing_distance / z pygame.draw.line(screen, color, (center_x, center_y), (x, y), 2) w, h = label.get_size() screen.blit(label, (x - w / 2, y - h / 2)) # Draw the x, y and z axes x_axis = Vector3(1, 0, 0) y_axis = Vector3(0, 1, 0) z_axis = Vector3(0, 0, 1) draw_axis(red, x_axis, x_surface) draw_axis(green, y_axis, y_surface) draw_axis(blue, z_axis, z_surface) # Display rotation information on screen degrees_txt = tuple(degrees(r) for r in rotation) rotation_txt = "Rotation: Q/A %.3f, W/S %.3f, E/D %.3f" % degrees_txt txt_surface = font.render(rotation_txt, True, white) screen.blit(txt_surface, (5, 5)) # Displat the rotation matrix on screen matrix_txt = str(rotation_matrix) txt_y = 25 for line in matrix_txt.split("\n"): txt_surface = font.render(line, True, white) screen.blit(txt_surface, (5, txt_y)) txt_y += 20 pygame.display.update()
def start(): pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32) ball = pygame.image.load("images/ball.png").convert_alpha() fov = 75.0 # degrees viewing_distance = calculate_view_distance(fov, SCREEN_W) points = create_cube_points() points.sort(key=point_z, reverse=True) center_x, center_y = SCREEN_W/2, SCREEN_H/2 ball_w, ball_h = ball.get_size() ball_center_x, ball_center_y = ball_w/2, ball_h/2 cam_position = Vector3(0.0, 0.0, 600.0) rotation = Vector3() rotation_speed = Vector3(math.radians(20), math.radians(20), math.radians(20)) # Labels for the axes font = pygame.font.SysFont(pygame.font.get_default_font(), 16) x_surface = font.render("X", True, white) y_surface = font.render("Y", True, white) z_surface = font.render("Z", True, white) clock = pygame.time.Clock() while True: for event in pygame.event.get(): if event.type == pygame.QUIT: quit_game() screen.fill(bg_color) time_passed = clock.tick(30) time_passed_seconds = time_passed / 1000.0 rotation_direction = Vector3() # Adjust the rotation direction depending on key presses pressed_keys = pygame.key.get_pressed() if pressed_keys[pygame.K_q]: rotation_direction.x = +1.0 elif pressed_keys[pygame.K_a]: rotation_direction.x = -1.0 if pressed_keys[pygame.K_w]: rotation_direction.y = +1.0 elif pressed_keys[pygame.K_s]: rotation_direction.y = -1.0 if pressed_keys[pygame.K_e]: rotation_direction.z = +1.0 elif pressed_keys[pygame.K_d]: rotation_direction.z = -1.0 rotation += rotation_direction * rotation_speed * time_passed_seconds rotation_matrix = Matrix44.x_rotation(rotation.x) rotation_matrix *= Matrix44.y_rotation(rotation.y) rotation_matrix *= Matrix44.z_rotation(rotation.z) transformed_points = [] # Transform all the points and adjust for camera position for point in points: p = rotation_matrix.transform_vec3(point) - cam_position transformed_points.append(p) transformed_points.sort(key=point_z) # Perspective project and blit all the points for x, y, z in transformed_points: if z < 0: x = center_x + x * (-viewing_distance / z) y = center_y + (-y) * (-viewing_distance / z) screen.blit(ball, (x - ball_center_x, y - ball_center_y)) def draw_axis(label, axis, color): axis = rotation_matrix.transform_vec3(axis * 150.0) x, y, z = axis - cam_position x = SCREEN_W/2.0 + x * (-viewing_distance / z) y = SCREEN_H/2.0 + (-y) * (-viewing_distance / z) pygame.draw.line(screen, color, (center_x, center_y), (x, y), 2) w, h = label.get_size() screen.blit(label, (x - w/2, y - h/2)) # Draw the x, y and z axes x_axis = Vector3(1, 0, 0) y_axis = Vector3(0, 1, 0) z_axis = Vector3(0, 0, 1) draw_axis(x_surface, x_axis, red) draw_axis(y_surface, y_axis, green) draw_axis(z_surface, z_axis, blue) # Display rotation information on screen degrees_txt = tuple(math.degrees(r) for r in rotation) rotation_txt = f"Rotation: Q/A {round(degrees_txt[0], 3)}, W/S {round(degrees_txt[1], 3)}, E/D {round(degrees_txt[2], 3)}" txt_surface = font.render(rotation_txt, True, white) screen.blit(txt_surface, (5, 5)) matrix_txt = str(rotation_matrix) txt_y = 25 for line in matrix_txt.split('\n'): txt_surface = font.render(line, True, white) screen.blit(txt_surface, (5, txt_y)) txt_y += 20 pygame.display.flip()
def run(): pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE, 0) font = pygame.font.SysFont("courier new", 16, True) ball = pygame.image.load("ball.png").convert_alpha() # os pontos 3D points = [] fov = 75. # campo de visao viewing_distance = calculate_viewing_distance(radians(fov), SCREEN_SIZE[0]) # cria uma lista de pontos ao longo da borda de um cubo for x in range(0, CUBE_SIZE + 1, 10): edge_x = x == 0 or x == CUBE_SIZE for y in range(0, CUBE_SIZE + 1, 10): edge_y = y == 0 or y == CUBE_SIZE for z in range(0, CUBE_SIZE + 1, 10): edge_z = z == 0 or z == CUBE_SIZE if sum((edge_x, edge_y, edge_z)) >= 2: point_x = float(x) - CUBE_SIZE / 2 point_y = float(y) - CUBE_SIZE / 2 point_z = float(z) - CUBE_SIZE / 2 points.append(Vector3(point_x, point_y, point_z)) def point_z(point): return point[2] center_x, center_y = SCREEN_SIZE center_x /= 2 center_y /= 2 ball_w, ball_h = ball.get_size() ball_center_x = ball_w / 2 ball_center_y = ball_h / 2 camera_position = Vector3(0.0, 0.0, 600.) rotation = Vector3() rotation_speed = Vector3(radians(20), radians(20), radians(20)) clock = pygame.time.Clock() # Algumas cores para desenhar red = (255, 0, 0) green = (0, 255, 0) blue = (0, 0, 255) white = (255, 255, 255) # Nomes para os eixos x_surface = font.render("X", True, white) y_surface = font.render("Y", True, white) z_surface = font.render("Z", True, white) while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() quit() screen.fill((0, 0, 0)) time_passed = clock.tick() time_passed_seconds = time_passed / 1000. rotation_direction = Vector3() # Ajusta a direcao da rotacao de acordo com as teclas pressionadas pressed_keys = pygame.key.get_pressed() if pressed_keys[K_q]: rotation_direction.x = +1.0 elif pressed_keys[K_a]: rotation_direction.x = -1.0 if pressed_keys[K_w]: rotation_direction.y = +1.0 elif pressed_keys[K_s]: rotation_direction.y = -1.0 if pressed_keys[K_e]: rotation_direction.z = +1.0 elif pressed_keys[K_d]: rotation_direction.z = -1.0 # Aplica um movimento baseado em tempo à rotação rotation += rotation_direction * rotation_speed * time_passed_seconds # Cria a matriz de rotação rotation_matrix = Matrix.x_rotation(rotation.x) rotation_matrix *= Matrix.y_rotation(rotation.y) rotation_matrix *= Matrix.z_rotation(rotation.z) transformed_points = [] # Transforma todos os pontos e ajusta conforme a posição da câmera for point in points: p = rotation_matrix.transform_vec3(point) - camera_position transformed_points.append(p) transformed_points.sort(key=point_z) # Faz a projeção de perspectiva e o blit de todos os pontos for x, y, z in transformed_points: if z < 0: x = center_x + x * -viewing_distance / z y = center_y + -y * -viewing_distance / z screen.blit(ball, (x - ball_center_x, y - ball_center_y)) # funacao para desenhar um unico eixo def draw_axis(color, axis, label): axis = rotation_matrix.transform_vec3(axis * 150.) SCREEN_SIZE = (640, 480) center_x = SCREEN_SIZE[0] / 2.0 center_y = SCREEN_SIZE[1] / 2.0 x, y, z = axis - camera_position x = center_x + x * -viewing_distance / z y = center_y + -y * -viewing_distance / z pygame.draw.line(screen, color, (center_x, center_y), (x, y), 2) w, h = label.get_size() screen.blit(label, (x - w / 2, y - h / 2)) # desenha os eixos x, y, z x_axis = Vector3(1, 0, 0) y_axis = Vector3(0, 1, 0) z_axis = Vector3(0, 0, 1) draw_axis(red, x_axis, x_surface) draw_axis(green, y_axis, y_surface) draw_axis(blue, z_axis, z_surface) # exibe informacoes de rotacao na tela degrees_txt = tuple(degrees(r) for r in rotation) rotation_txt = "Rotacao: Q/A %.3f, W/S %.3f, E/D %.3f" % degrees_txt txt_surface = font.render(rotation_txt, True, white) screen.blit(txt_surface, (5, 5)) # exibe a matriz de rotacao na tela matrix_txt = str(rotation_matrix) txt_y = 25 for line in matrix_txt.split('\n'): txt_surface = font.render(line, True, white) screen.blit(txt_surface, (5, txt_y)) txt_y += 20 pygame.display.update()
def run (): pygame.init() screen = pygame.display.set_mode (SCREEN_SIZE, 0) font = pygame.font.SysFont ('courier new', 16, True) ball = pygame.image.load ('ball.png').convert_alpha() points = [] fov = 75. viewing_distance = calculate_viewing_distance (radians (fov), SCREEN_SIZE[0]) for x in xrange (0, CUBE_SIZE + 1, 10): edge_x = x == 0 or x == CUBE_SIZE for y in xrange (0, CUBE_SIZE + 1, 10): edge_y = y == 0 or y == CUBE_SIZE for z in xrange (0, CUBE_SIZE + 1, 10): edge_z = z == 0 or z == CUBE_SIZE if sum ((edge_x, edge_y, edge_z)) >= 2: point_x = float (x) - CUBE_SIZE / 2 point_y = float (y) - CUBE_SIZE / 2 point_z = float (z) - CUBE_SIZE / 2 points.append (Vector3 (point_x, point_y, point_z)) def point_z (point): return point[2] points.sort (key=point_z, reverse=True) center_x, center_y = SCREEN_SIZE center_x /= 2 center_y /= 2 ball_w, ball_h = ball.get_size() ball_center_x = ball_w / 2 ball_center_y = ball_h / 2 camera_position = Vector3 (0.0, 0.0, 600.) rotation = Vector3() rotation_speed = Vector3 (radians(20), radians(20), radians(20)) clock = pygame.time.Clock() red = (255, 0, 0) green = (0, 255, 0) blue = (0, 0, 255) white = (255, 255, 255) x_surface = font.render ("X", True, white) y_surface = font.render ('Y', True, white) z_surface = font.render ('Z', True, white) while True: for event in pygame.event.get(): if event.type == QUIT: return screen.fill ((0, 0, 0)) time_passed = clock.tick () time_passed_seconds = time_passed / 1000. rotation_direction = Vector3 () pressed_keys = pygame.key.get_pressed () if pressed_keys [K_a]: rotation_direction.y -= 1.0 if pressed_keys [K_d]: rotation_direction.y += 1.0 if pressed_keys [K_w]: rotation_direction.x -= 1.0 if pressed_keys [K_s]: rotation_direction.x += 1.0 if pressed_keys [K_q]: rotation_direction.z += 1.0 if pressed_keys [K_e]: rotation_direction.z -= 1.0 rotation += rotation_direction * rotation_speed * time_passed_seconds rotation_matrix = Matrix.x_rotation (rotation.x) rotation_matrix *= Matrix.y_rotation (rotation.y) rotation_matrix *= Matrix.z_rotation (rotation.z) transformed_points = [] for point in points: p = rotation_matrix.transform_vec3(point) - camera_position transformed_points.append (p) transformed_points.sort (key=point_z) for x, y, z in transformed_points: if z < 0: x = center_x + x * -viewing_distance / z # why -viewing_distance? so the z axis of camera would be negetive y = center_y + -y * -viewing_distance / z screen.blit (ball, (x-ball_center_x, y-ball_center_y)) def draw_axis (color, axis, label): axis = rotation_matrix.transform_vec3 (axis * 150.) # that's where magificant by 150 SCREEN_SIZE = (640, 640) center_x = SCREEN_SIZE[0] / 2.0 center_y = SCREEN_SIZE[1] / 2.0 x,y,z = axis - camera_position x = center_x + x * -viewing_distance / z y = center_y + -y * -viewing_distance / z pygame.draw.line (screen, color, (center_x, center_y), (x, y), 2) w,h = label.get_size () screen.blit (label, (x-w/2, y-h/2)) x_axis = Vector3 (1, 0, 0) y_axis = Vector3 (0, 1, 0) z_axis = Vector3 (0, 0, 1) draw_axis (red, x_axis, x_surface) draw_axis (green, y_axis, y_surface) draw_axis (blue, z_axis, z_surface) degrees_txt = tuple (degrees(r) for r in rotation) rotation_txt = 'Rotation: W/S %.3f, A/D %.3f, Q/E %.3f' % degrees_txt txt_surface = font.render (rotation_txt, True, white) screen.blit (txt_surface, (5, 5)) matrix_txt = str (rotation_matrix) txt_y = 25 for line in matrix_txt.split ('\n'): txt_surface = font.render (line, True, white) screen.blit (txt_surface, (5, txt_y)) txt_y += 20 pygame.display.update()
p2 = identity.transform(p1) print(p2) print(identity.get_column(2)) translation = Matrix44.translation(10, 5, 2) print(translation) scale = Matrix44.scale(2.0) print(scale) s = scale.transform(p1) print(s) z_rotate = Matrix44.z_rotation(math.radians(-45)) print(z_rotate) a = (0, 10, 0) b = z_rotate.transform(a) print(b) translation1 = Matrix44.translation(5, 10, 2) translation2 = Matrix44.translation(-7, 2, 4) print(translation1 * translation2) translation = Matrix44.translation(5, 10, 0) rotate = Matrix44.y_rotation(math.radians(45)) translation_rotate = translation * rotate print(translation_rotate)