Make some optimizations.

This commit is contained in:
bʰedoh₂ swé 2024-04-05 17:40:54 +05:00
parent 9e69321399
commit 56228bc8b1
5 changed files with 67 additions and 37 deletions

27
draw.py
View File

@ -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

42
gyro.py
View File

@ -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)

View File

@ -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

View File

@ -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)

15
main.py
View File

@ -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()
@ -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):