From 56228bc8b12b3bdd9d297cbfe7dda7d007f05be7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?b=CA=B0edoh=E2=82=82=20sw=C3=A9?= Date: Fri, 5 Apr 2024 17:40:54 +0500 Subject: [PATCH] Make some optimizations. --- draw.py | 27 +++++++++++++++++++++------ gyro.py | 42 ++++++++++++++++++++++++------------------ levels.py | 10 ++++++++++ lines.py | 8 ++++---- main.py | 17 ++++++++--------- 5 files changed, 67 insertions(+), 37 deletions(-) diff --git a/draw.py b/draw.py index 399c788..8406355 100644 --- a/draw.py +++ b/draw.py @@ -1,15 +1,30 @@ from cmath import exp -from constants import * -from gyro import * -from lines import * +from constants import I, BLACK +from gyro import MobiusInt, MobiusAdd, MobiusDist, cDot +from lines import cBetween + +from numba import jit, byte, double, prange, optional +from numba.types import UniTuple +from numba.typed import List as nlist +from numba.experimental import jitclass + +from numpy import full + +drawnsegmentsig = [ + ('dist', double), + ('color', UniTuple(byte, 3)) +] +@jitclass(drawnsegmentsig) class DrawnSegment: def __init__(self,dist,color): self.dist = dist self.color = color +@jit#(cache=True,parallel=True) def draw(level,gPlayer,fov,res): - drawn = list() + EMPTYDRAWN = DrawnSegment(0, BLACK) + drawn = [EMPTYDRAWN] * res irot = exp(fov/res*I) iprot = gPlayer.cRot for i in range(res): @@ -18,7 +33,7 @@ def draw(level,gPlayer,fov,res): for j in level: try: # Function "LineIntersection" faults from time to time cInt = MobiusInt(j.pointA,j.pointB,gPlayer.cPos,rot) - except ZeroDivisionError: + except: continue if cDot(rot,MobiusAdd(cInt,-gPlayer.cPos)) > 0: continue @@ -30,6 +45,6 @@ def draw(level,gPlayer,fov,res): continue if m.dist > rDist: m = DrawnSegment(rDist,j.color) - drawn.append(m if m is not None else DrawnSegment(0, BLACK)) + drawn[i] = (m if m is not None else EMPTYDRAWN) return drawn diff --git a/gyro.py b/gyro.py index 25d48cb..7396cb2 100644 --- a/gyro.py +++ b/gyro.py @@ -1,4 +1,5 @@ -from numba import jit +from numba import jit, c16 +from numba.experimental import jitclass from cmath import sqrt from math import tanh, atanh, pi from lines import cLineIntersection @@ -6,64 +7,64 @@ from lines import cLineIntersection def deg2rad(rA): return rA/180*pi def rad2degd(rA): return rA*180/pi -@jit +@jit(cache=True) def cap(rN): if rN < 0: return 0 return rN -@jit +@jit(cache=True) def ZeroCheck(cN): if cN == complex(0,0): return complex(1,0) else: return cN -@jit +@jit(cache=True) def c_tr(cN): return cN.real, cN.imag -@jit +@jit(cache=True) def cNorm(cN): return ZeroCheck(cN)/abs(ZeroCheck(cN)) -@jit +@jit(cache=True) def cDot(cA, cB): return (cA * cB.conjugate()).real -@jit +@jit(cache=True) def cDist(cA, cB): return abs(cA-cB) -@jit +@jit(cache=True) def MobiusInt(cA,cB,cC,cD): # Bruh return Klein2Poincare(cLineIntersection(Poincare2Klein(cA),Poincare2Klein(cB),Poincare2Klein(cC),Poincare2Klein(cD))) -@jit +@jit(cache=True) def MobiusAdd(cA, cB): return (cA + cB) / (1 + cA.conjugate() * cB) -@jit +@jit(cache=True) def MobiusGyr(cA, cB): return (1 + cA * cB.conjugate()) / (1 + cA.conjugate() * cB) -@jit +@jit(cache=True) def MobiusAddGyr(cA, cB): return MobiusAdd(cA, cB), MobiusGyr(cA, cB) -@jit +@jit(cache=True) def MobiusScalar(cA, rT): m = abs(cA) return tanh(rT * atanh(m)) * cA / m -@jit +@jit(cache=True) def MobiusCoadd(cA,cB): return MobiusAdd(cA, (MobiusGyr(cA,-cB) * cB)) -@jit +@jit(cache=True) def MobiusCosub(cA,cB): return MobiusAdd(cA, -(MobiusGyr(cA,cB) * cB)) -@jit +@jit(cache=True) def MobiusLine(cA,cB,rT): return MobiusAdd( cA, @@ -71,18 +72,23 @@ def MobiusLine(cA,cB,rT): MobiusAdd(-cA,cB), rT)) -@jit +@jit(cache=True) def MobiusDist(cA,cB): return abs(MobiusAdd(-cB,cA)) -@jit +@jit(cache=True) def Poincare2Klein(cN): return 2*cN / (1 + cDot(cN,cN)) -@jit +@jit(cache=True) def Klein2Poincare(cN): return (1-sqrt(1-cDot(cN,cN)))*cN/cDot(cN,cN) +gyrosig = [ + ('cPos', c16), + ('cRot', c16) +] +@jitclass(gyrosig) class GyroVector: def __init__(self, cPos, cRot): self.cPos = complex(cPos) diff --git a/levels.py b/levels.py index a576f8e..24cdbb1 100644 --- a/levels.py +++ b/levels.py @@ -1,6 +1,16 @@ from os import makedirs from time import time +from numba import jit, c16, b1, byte +from numba.experimental import jitclass +from numba.types import UniTuple +segmentsig = [ + ('isFinite', b1), + ('pointA', c16), + ('pointB', c16), + ('color', UniTuple(byte, 3)) +] +@jitclass(segmentsig) class Segment: def __init__(self,bA,cA,cB,trColor): self.isFinite = bA diff --git a/lines.py b/lines.py index 71ffb0d..2249f4e 100644 --- a/lines.py +++ b/lines.py @@ -1,20 +1,20 @@ from numba import jit -@jit +@jit(cache=True) def LineIntersection(rX1,rY1,rX2,rY2,rX3,rY3,rX4,rY4): rX = ( (rX1*rY2-rY1*rX2)*(rX3-rX4)-(rX1-rX2)*(rX3*rY4-rY3*rX4) ) / ( (rX1-rX2)*(rY3-rY4)-(rY1-rY2)*(rX3-rX4) ) rY = ( (rX1*rY2-rY1*rX2)*(rY3-rY4)-(rY1-rY2)*(rX3*rY4-rY3*rX4) ) / ( (rX1-rX2)*(rY3-rY4)-(rY1-rY2)*(rX3-rX4) ) return (rX, rY) -@jit +@jit(cache=True) def cLineIntersection(cA0, cA1, cB0, cB1): rX, rY = LineIntersection(cA0.real, cA0.imag, cA1.real, cA1.imag, cB0.real, cB0.imag, cB1.real, cB1.imag) return complex(rX, rY) -@jit +@jit(cache=True) def Between(rA,rB,rN): return (rA <= rN and rN <= rB) or (rB <= rN and rN <= rA) -@jit +@jit(cache=True) def cBetween(cA,cB,cN): return Between(cA.real,cB.real,cN.real) and Between(cA.imag,cB.imag,cN.imag) diff --git a/main.py b/main.py index 4a2c26a..9a93bab 100755 --- a/main.py +++ b/main.py @@ -9,14 +9,12 @@ import pygame import pygame.freetype from levels import Segment, open_level, parse_level_from_string -from gyro import * -from levels import * -from constants import * +from gyro import GyroVector, Poincare2Klein +from levels import open_level, save_level, parse_level_from_string, make_wall +from constants import I, WHITE, BLACK, IROT, ROT, OFFSET from draw import draw from alert import Alert -bCap = True - gOrigin = GyroVector(0,1) SKY = (127,127,255) @@ -38,6 +36,8 @@ def nonzerocap(n): return n def mainLoop(): + bCap = True + bCont = True gPlayer = GyroVector(0,1) display = pygame.display.set_mode((1280,720)) clock = pygame.time.Clock() @@ -45,7 +45,7 @@ def mainLoop(): debugInfo = True wall_buffer = [] alerts = [] - + def alert_append(alert, delay): if len(alerts) >= 1: alerts.pop() @@ -59,17 +59,16 @@ def mainLoop(): leveltoparse = open_level("maps/squareroom.p3hel") level = parse_level_from_string(leveltoparse) - while True: + while bCont: for event in pygame.event.get(): if event.type == pygame.QUIT: - return True + bCont = False if event.type == pygame.KEYDOWN: if event.key == pygame.K_r: gPlayer.cRot *= -1 if event.key == pygame.K_F3: debugInfo = not debugInfo if event.key == pygame.K_F1: - global bCap bCap = not bCap if event.key == pygame.K_F2: if (len(wall_buffer) == 1):