def get_tmatrix(self): c = self.get_center() tmatrix = Matrix44.identity() # tmatrix = Matrix44.z_rotation(math.radians(self.rotation)) tmatrix.translate += Vector3(-c.x, -c.y, 0) tmatrix.translate += Vector3(self.world_pos.x, self.world_pos.y, 0) # z_rotation_matrix = Matrix44.z_rotation(math.radians(self.rotation)) # z_rotation_matrix.invert() # tmatrix *= z_rotation_matrix # Can't get rotation working :( # Working: # tmatrix = Matrix44.translation(self.world_pos.x, self.world_pos.y, 0) return tmatrix
def world_to_screen(self, pos): """Convert world coordinates (Vector2) to screen coordinates (Vector2)""" vec2to3 = Vector3(pos.x, pos.y, 0) transformed = self.get_tmatrix().get_inverse().transform( vec2to3) # World to screen return Vector2(transformed[0] + self.position.x, transformed[1] + self.position.y)
def move(self, forward=None, right=None, up=None): """Changes the translation according to a direction vector. To move in opposite directions (i.e back, left and down), first negate the vector forward -- Vector or tuple to move in the 'forward' direction right -- Vector or tuple to move in the 'right' direction up -- Vector or tuple to move in the 'up' direction """ if forward is not None: self.translate = Vector3(self.translate) + forward if right is not None: self.right = Vector3(self.right) + right if up is not None: self.up = Vector3(self.up) + up
def transform_vec3(self, v): """Transforms a vector and returns the result as a Vector3. v -- Vector to transform """ m = self._m x, y, z = v return Vector3.from_floats( x * m[0] + y * m[4] + z * m[8] + m[12], x * m[1] + y * m[5] + z * m[9] + m[13], x * m[2] + y * m[6] + z * m[10] + m[14] )
def transform_sequence_vec3(self, points): m_0, m_1, m_2, m_3, \ m_4, m_5, m_6, m_7, \ m_8, m_9, m_10, m_11, \ m_12, m_13, m_14, m_15 = self._m return [ Vector3.from_floats ( x * m_0 + y * m_4 + z * m_8 + m_12, x * m_1 + y * m_5 + z * m_9 + m_13, x * m_2 + y * m_6 + z * m_10 + m_14 ) for x,y,z in points ]
def transform_vec3(self, v): """Transforms a vector and returns the result as a Vector3. v -- Vector to transform """ m = self._m x, y, z = v return Vector3.from_floats(x * m[0] + y * m[4] + z * m[8] + m[12], x * m[1] + y * m[5] + z * m[9] + m[13], x * m[2] + y * m[6] + z * m[10] + m[14])
def transform_sequence_vec3(self, points): m_0, m_1, m_2, m_3, \ m_4, m_5, m_6, m_7, \ m_8, m_9, m_10, m_11, \ m_12, m_13, m_14, m_15 = self._m return [Vector3.from_floats (x * m_0 + y * m_4 + z * m_8 + m_12, x * m_1 + y * m_5 + z * m_9 + m_13, x * m_2 + y * m_6 + z * m_10 + m_14) for x, y, z in points]
def rotate_vec3(self, v): """Rotates a Vector3 and returns the result. The translation part of the Matrix44 is ignored. v -- Vector to rotate """ m = self._m x, y, z = v return Vector3.from_floats( x * m[0] + y * m[4] + z * m[8], x * m[1] + y * m[5] + z * m[9], x * m[2] + y * m[6] + z * m[10] )
def get_row_vec3(self, row_no): """Returns a Vector3 for a given row. row_no -- The row index """ try: r = row_no * 4 x, y, z = self._m[r:r + 3] return Vector3.from_floats(x, y, z) except IndexError: raise IndexError("Row and Column should be 0, 1, 2 or 3")
def get_row_vec3(self, row_no): """Returns a Vector3 for a given row. row_no -- The row index """ try: r = row_no*4 x, y, z = self._m[r:r+3] return Vector3.from_floats(x, y, z) except IndexError: raise IndexError( "Row and Column should be 0, 1, 2 or 3" )
def rotate_vec3(self, v): """Rotates a Vector3 and returns the result. The translation part of the Matrix44 is ignored. v -- Vector to rotate """ m = self._m x, y, z = v return Vector3.from_floats(x * m[0] + y * m[4] + z * m[8], x * m[1] + y * m[5] + z * m[9], x * m[2] + y * m[6] + z * m[10])
def iter_transform_vec3(self, points): """Transforms a sequence of points, and yields the result as Vector3s points -- A sequence of vectors """ m_0, m_1, m_2, m_3, \ m_4, m_5, m_6, m_7, \ m_8, m_9, m_10, m_11, \ m_12, m_13, m_14, m_15 = self._m for x, y, z in points: yield Vector3.from_floats(x * m_0 + y * m_4 + z * m_8 + m_12, x * m_1 + y * m_5 + z * m_9 + m_13, x * m_2 + y * m_6 + z * m_10 + m_14)
def test(): m = Matrix44.xyz_rotation(radians(45), radians(20), radians(0)) print(m) print("--Transpose") print(m.get_transpose()) print("--") print(m.get_row(2)) m.transpose() print(m) print #print (10, 20, 30) + Vector3(1,2,3) m.translate = (m.translate) + Vector3(10, 20, 30) print(m) print v = (1., 2., 3.) print(v) vt = m.transform(v) print(vt) vit = m.get_inverse().transform(vt) print(vit) print(m.inverse_transform(vt)) m[1, 2] = 3. print print(m.x_axis) print(m.translate) m.translate = (1, 2, 3) print(m)
def iter_transform_vec3(self, points): """Transforms a sequence of points, and yields the result as Vector3s points -- A sequence of vectors """ m_0, m_1, m_2, m_3, \ m_4, m_5, m_6, m_7, \ m_8, m_9, m_10, m_11, \ m_12, m_13, m_14, m_15 = self._m for x, y, z in points: yield Vector3.from_floats( x * m_0 + y * m_4 + z * m_8 + m_12, x * m_1 + y * m_5 + z * m_9 + m_13, x * m_2 + y * m_6 + z * m_10 + m_14 )
def as_vec3(self): """Shorthand for converting to a vector3.""" return Vector3._from_float_sequence(self)
def test(): m = Matrix44.xyz_rotation(radians(45), radians(20), radians(0)) # m.translate += (1, 2, 3) print(m.right) print(m.right.as_vec3()) n = m.copy() r = Matrix44.z_rotation(radians(32)) m *= r print(m) n.fast_mul(r) print(n) print("--Transpose") print(m.get_transpose()) print("--") print(m.get_row(2)) m.transpose() print(m) print() # print (10, 20, 30) + Vector3(1,2,3) m.translate = (m.translate[:3]) + Vector3(10, 20, 30) print(m) print() v = (1., 2., 3.) print(v) vt = m.transform(v) print(vt) vit = m.get_inverse().transform(vt) print(vit) print(m.inverse_transform(vt)) m[1, 2] = 3. print() print(m.x_axis) print(m.translate) m.translate = (1, 2, 3) print(m) identity = Matrix44() # identity.set_row(0, (1, 2, 3, 4)) print(identity) identity[3, 1] = 456 # identity *= Matrix44.scale(20.32, 764.2323, -23) print(identity) print(eval(repr(identity))) print(m) print(m.translate + Vector3(1, 2, 3)) print(m) m.translate = (0, 0, 0)
def screen_to_world(self, pos): """Convert screen coordinates (Vector2) to world coordinates (Vector2)""" pos = Vector2(pos) pos -= self.position transformed = self.get_tmatrix().transform(Vector3(pos.x, pos.y, 0)) return Vector2(transformed[0], transformed[1])
def run(): pygame.init() screen = pygame.display.set_mode(SCREEN_SIZE, 0) default_font = pygame.font.get_default_font() font = pygame.font.SysFont(default_font, 24) ball = pygame.image.load("ball.png").convert_alpha() # The 3D points points = [] fov = 90. # 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, 20): edge_x = x == 0 or x == CUBE_SIZE for y in range(0, CUBE_SIZE + 1, 20): edge_y = y == 0 or y == CUBE_SIZE for z in range(0, CUBE_SIZE + 1, 20): 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)) # Sort points in z order def point_z(point): return point.z 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, -700.) camera_speed = Vector3(300.0, 300.0, 300.0) clock = pygame.time.Clock() while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() quit() screen.fill((0, 0, 0)) pressed_keys = pygame.key.get_pressed() time_passed = clock.tick() time_passed_seconds = time_passed / 1000. direction = Vector3() if pressed_keys[K_LEFT]: direction.x = -1.0 elif pressed_keys[K_RIGHT]: direction.x = +1.0 if pressed_keys[K_UP]: direction.y = +1.0 elif pressed_keys[K_DOWN]: direction.y = -1.0 if pressed_keys[K_q]: direction.z = +1.0 elif pressed_keys[K_a]: direction.z = -1.0 if pressed_keys[K_w]: fov = min(179., fov + 1.) w = SCREEN_SIZE[0] viewing_distance = calculate_viewing_distance(radians(fov), w) elif pressed_keys[K_s]: fov = max(1., fov - 1.) w = SCREEN_SIZE[0] viewing_distance = calculate_viewing_distance(radians(fov), w) camera_position += direction * camera_speed * time_passed_seconds # Draw the 3D points for point in points: x, y, z = point - camera_position if z > 0: x = x * viewing_distance / z y = -y * viewing_distance / z x += center_x y += center_y screen.blit(ball, (x - ball_center_x, y - ball_center_y)) # Draw the field of view diagram diagram_width = SCREEN_SIZE[0] / 4 col = (50, 255, 50) diagram_points = [] diagram_points.append((diagram_width / 2, 100 + viewing_distance / 4)) diagram_points.append((0, 100)) diagram_points.append((diagram_width, 100)) diagram_points.append((diagram_width / 2, 100 + viewing_distance / 4)) diagram_points.append((diagram_width / 2, 100)) pygame.draw.lines(screen, col, False, diagram_points, 2) # Draw the text white = (255, 255, 255) cam_text = font.render("camera = " + str(camera_position), True, white) screen.blit(cam_text, (5, 5)) fov_text = font.render("field of view = %i" % int(fov), True, white) screen.blit(fov_text, (5, 35)) txt = "viewing distance = %.3f" % viewing_distance d_text = font.render(txt, True, white) screen.blit(d_text, (5, 65)) 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() # 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 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 move(self, forward=None, right=None, up=None): """Changes the translation according to a direction vector. To move in opposite directions (i.e back, left and down), first negate the vector. forward -- Units to move in the 'forward' direction right -- Units to move in the 'right' direction up -- Units to move in the 'up' direction """ if forward is not None: self.translate = Vector3(self.translate) + \ Vector3(self.forward) * forward if right is not None: self.translate = Vector3(self.translate) + \ Vector3(self.right) * right if up is not None: self.translate = Vector3(self.translate) + \ Vector3(self.up) * up # def test(): # m = Matrix44.xyz_rotation(radians(45), radians(20), radians(0)) # # # m.translate += (1, 2, 3) # print(m.right) # print(m.right.as_vec3()) # # n = m.copy() # # r = Matrix44.z_rotation(radians(32)) # m *= r # print(m) # n.fast_mul(r) # # print(n) # # print("--Transpose") # # print(m.get_transpose()) # # print("--") # # print(m.get_row(2)) # # m.transpose() # print(m) # # print() # # # print (10, 20, 30) + Vector3(1,2,3) # # m.translate = (m.translate[:3]) + Vector3(10, 20, 30) # # print(m) # # print() # # v = (1., 2., 3.) # print(v) # vt = m.transform(v) # print(vt) # # vit = m.get_inverse().transform(vt) # # print(vit) # # print(m.inverse_transform(vt)) # m[1, 2] = 3. # # print() # # print(m.x_axis) # print(m.translate) # m.translate = (1, 2, 3) # # print(m) # # identity = Matrix44() # # identity.set_row(0, (1, 2, 3, 4)) # print(identity) # # identity[3, 1] = 456 # # identity *= Matrix44.scale(20.32, 764.2323, -23) # # print(identity) # print(eval(repr(identity))) # # print(m) # # print(m.translate + Vector3(1, 2, 3)) # # print(m) # # m.translate = (0, 0, 0) # # # if __name__ == "__main__": # test()
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 main(): pygame.init() screen = pygame.display.set_mode(screensize,0,32) defaultfont = pygame.font.get_default_font() sysfont = pygame.font.SysFont(defaultfont,24) ballsurf = pygame.image.load('ball.png').convert_alpha() # the 3D points points = [] fov = 90 # Field of view viewdistance = calculateViewingDistance(radians(fov), screenwidth) # create a list of points along the edge of a cube for x in range(0, cubesize+1, 20): isEdgeX = (x==0) or (x==cubesize) for y in range(0,cubesize+1,20): isEdgeY = (y==0) or (y==cubesize) for z in range(0,cubesize+1,20): isEdgeZ = (z==0) or (z==cubesize) if sum( [isEdgeX, isEdgeY, isEdgeZ] ) >= 2: pointX = x - cubesize/2.0 pointY = y - cubesize/2.0 pointZ = z - cubesize/2.0 points.append( Vector3(pointX,pointY,pointZ) ) # sort points in z order def getPointZ(point): return point.z points.sort(key=getPointZ, reverse=True) centerX,centerY = screenwidth/2, screenheight/2 ballwidth,ballheight = ballsurf.get_size() ballcenterX,ballcenterY = ballwidth/2, ballheight/2 cameraposition = Vector3(0.0, 0.0, -700.0) cameraspeed = Vector3(300.0, 300.0, 300.0) clock = pygame.time.Clock() while True: for e in pygame.event.get(): if e.type == QUIT: pygame.quit(); exit() screen.fill(black) pressedkeys = pygame.key.get_pressed() timepassed = clock.tick(fps)/1000.0 direction = Vector3() if pressedkeys[K_LEFT]: direction.x = -1.0 elif pressedkeys[K_RIGHT]: direction.x = +1.0 elif pressedkeys[K_UP]: direction.y = -1.0 elif pressedkeys[K_DOWN]: direction.y = +1.0 elif pressedkeys[K_a]: direction.z = -1.0 elif pressedkeys[K_q]: direction.z = +1.0 if pressedkeys[K_w]: fov = min(179.0, fov+1.0) viewdistance = calculateViewingDistance( radians(fov), screenwidth) elif pressedkeys[K_s]: fov = max(1.0, fov-1.0) viewdistance = calculateViewingDistance( radians(fov), screenwidth) cameraposition += timepassed * cameraspeed * direction # draw the 3D points for point in points: x,y,z = point - cameraposition if z > 0: x = x * viewdistance/z y = -y * viewdistance/z x += centerX y += centerY screen.blit(ballsurf, (x-ballcenterX,y-ballcenterY) ) # draw the field of view diagram diagramwidth = screenwidth/4 color = 50,255,50 diagrampoints = [] diagrampoints.append( (diagramwidth/2, 100+viewdistance/4) ) diagrampoints.append( (0,100)) diagrampoints.append( (diagramwidth,100)) diagrampoints.append( (diagramwidth/2,100+viewdistance/4)) diagrampoints.append( (diagramwidth/2,100) ) pygame.draw.lines(screen,color,False,diagrampoints,2) # draw the text cam_textsurf = sysfont.render('Camera = %s' %str(cameraposition), True,white) fov_textsurf = sysfont.render('field of view = %i' %int(fov), True,white) txt = 'viewing distance = %.3f' % viewdistance dist_textsurf = sysfont.render(txt,True,white) screen.blit(cam_textsurf, (5,5) ) screen.blit(fov_textsurf, (5,35) ) screen.blit(dist_textsurf, (5,65) ) pygame.display.update()