#!/usr/bin/env python3 from time import time_ns, sleep from cmath import exp import pygame import pygame.freetype from gyro import * from lines import * def deg2rad(rA): return rA/180*PI WHITE = (255,255,255) BLACK = (0,0,0) OFFSET = .015625 I = complex(0,1) PI = 3.14159265358979323846264338327 ROT = cNorm(exp(deg2rad(2)*I)) IROT = 1/ROT F = 5 * 10**7 F_ = 10**9 class Segment: def __init__(self,bA,cA,cB,trColor): self.isFinite = bA self.pointA = cA self.pointB = cB self.color = trColor class DrawnSegment: def __init__(self,height,color): self.height = height self.color = color level = [ # Segment(False,cNorm(-1),cNorm(I),(255,255,20)), Segment(False,-.5,I*.5,BLACK) ] def draw(level,gPlayer,fov,res): drawn = list() irot = exp(fov/res*I) iprot = gPlayer.cRot for i in range(res): m = DrawnSegment(0,BLACK) rot = irot**(i-(res/2)) * iprot for j in level: tA = Poincare2Klein(MobiusAdd(j.pointA,-gPlayer.cPos)) tB = Poincare2Klein(MobiusAdd(j.pointB,-gPlayer.cPos)) try: # This function faults from time to time cInt = cLineIntersection(tA,tB,complex(0),rot) except ZeroDivisionError: continue rDist = cDist(0,cInt) if cDot(cInt,rot) > 0: continue if (1 - m.height) > rDist: m = DrawnSegment(1-rDist,j.color) drawn.append(m) return drawn def cap(rN): if rN < 0: return 0 return rN def mainLoop(): gPlayer = GyroVector(0,1) display = pygame.display.set_mode((1280,720)) font = pygame.freetype.Font(None,24) while True: framestart = time_ns() for event in pygame.event.get(): if event.type == pygame.QUIT: return True keys = pygame.key.get_pressed() if keys[pygame.K_d]: gPlayer.rotate(IROT) if keys[pygame.K_a]: gPlayer.rotate(ROT) if keys[pygame.K_w]: gPlayer += GyroVector(OFFSET, 1) if keys[pygame.K_s]: gPlayer -= GyroVector(OFFSET, 1) display.fill(WHITE) #pygame.draw.rect(display,BLACK, c_tr(Poincare2Klein(gPlayer.cPos) * -100) + (100,100),0) drawn = draw(level,gPlayer,PI/2,640) n = 0 for i in drawn: pygame.draw.rect(display,i.color, (n,360 - (cap(i.height) * 500),10,cap(i.height) * 1000)) n += 2 font.render_to(display, (20, 150), str(gPlayer.cPos), (0, 0, 0)) font.render_to(display, (20, 250), str(gPlayer.cRot), (0, 0, 0)) pygame.display.update() frameend = time_ns() sleep((frameend-framestart) / F_) return True def main(): pygame.init() pygame.display.set_caption('P3HE') if not pygame.get_init(): return False retstatus = mainLoop() return retstatus if __name__ == "__main__": if not main(): print("An error occured")