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 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: class DrawnSegment:
def __init__(self,dist,color): def __init__(self,dist,color):
self.dist = dist self.dist = dist
self.color = color self.color = color
@jit#(cache=True,parallel=True)
def draw(level,gPlayer,fov,res): def draw(level,gPlayer,fov,res):
drawn = list() EMPTYDRAWN = DrawnSegment(0, BLACK)
drawn = [EMPTYDRAWN] * res
irot = exp(fov/res*I) irot = exp(fov/res*I)
iprot = gPlayer.cRot iprot = gPlayer.cRot
for i in range(res): for i in range(res):
@ -18,7 +33,7 @@ def draw(level,gPlayer,fov,res):
for j in level: for j in level:
try: # Function "LineIntersection" faults from time to time try: # Function "LineIntersection" faults from time to time
cInt = MobiusInt(j.pointA,j.pointB,gPlayer.cPos,rot) cInt = MobiusInt(j.pointA,j.pointB,gPlayer.cPos,rot)
except ZeroDivisionError: except:
continue continue
if cDot(rot,MobiusAdd(cInt,-gPlayer.cPos)) > 0: if cDot(rot,MobiusAdd(cInt,-gPlayer.cPos)) > 0:
continue continue
@ -30,6 +45,6 @@ def draw(level,gPlayer,fov,res):
continue continue
if m.dist > rDist: if m.dist > rDist:
m = DrawnSegment(rDist,j.color) 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 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 cmath import sqrt
from math import tanh, atanh, pi from math import tanh, atanh, pi
from lines import cLineIntersection from lines import cLineIntersection
@ -6,64 +7,64 @@ from lines import cLineIntersection
def deg2rad(rA): return rA/180*pi def deg2rad(rA): return rA/180*pi
def rad2degd(rA): return rA*180/pi def rad2degd(rA): return rA*180/pi
@jit @jit(cache=True)
def cap(rN): def cap(rN):
if rN < 0: if rN < 0:
return 0 return 0
return rN return rN
@jit @jit(cache=True)
def ZeroCheck(cN): def ZeroCheck(cN):
if cN == complex(0,0): if cN == complex(0,0):
return complex(1,0) return complex(1,0)
else: else:
return cN return cN
@jit @jit(cache=True)
def c_tr(cN): def c_tr(cN):
return cN.real, cN.imag return cN.real, cN.imag
@jit @jit(cache=True)
def cNorm(cN): def cNorm(cN):
return ZeroCheck(cN)/abs(ZeroCheck(cN)) return ZeroCheck(cN)/abs(ZeroCheck(cN))
@jit @jit(cache=True)
def cDot(cA, cB): def cDot(cA, cB):
return (cA * cB.conjugate()).real return (cA * cB.conjugate()).real
@jit @jit(cache=True)
def cDist(cA, cB): def cDist(cA, cB):
return abs(cA-cB) return abs(cA-cB)
@jit @jit(cache=True)
def MobiusInt(cA,cB,cC,cD): # Bruh def MobiusInt(cA,cB,cC,cD): # Bruh
return Klein2Poincare(cLineIntersection(Poincare2Klein(cA),Poincare2Klein(cB),Poincare2Klein(cC),Poincare2Klein(cD))) return Klein2Poincare(cLineIntersection(Poincare2Klein(cA),Poincare2Klein(cB),Poincare2Klein(cC),Poincare2Klein(cD)))
@jit @jit(cache=True)
def MobiusAdd(cA, cB): def MobiusAdd(cA, cB):
return (cA + cB) / (1 + cA.conjugate() * cB) return (cA + cB) / (1 + cA.conjugate() * cB)
@jit @jit(cache=True)
def MobiusGyr(cA, cB): def MobiusGyr(cA, cB):
return (1 + cA * cB.conjugate()) / (1 + cA.conjugate() * cB) return (1 + cA * cB.conjugate()) / (1 + cA.conjugate() * cB)
@jit @jit(cache=True)
def MobiusAddGyr(cA, cB): def MobiusAddGyr(cA, cB):
return MobiusAdd(cA, cB), MobiusGyr(cA, cB) return MobiusAdd(cA, cB), MobiusGyr(cA, cB)
@jit @jit(cache=True)
def MobiusScalar(cA, rT): def MobiusScalar(cA, rT):
m = abs(cA) m = abs(cA)
return tanh(rT * atanh(m)) * cA / m return tanh(rT * atanh(m)) * cA / m
@jit @jit(cache=True)
def MobiusCoadd(cA,cB): def MobiusCoadd(cA,cB):
return MobiusAdd(cA, (MobiusGyr(cA,-cB) * cB)) return MobiusAdd(cA, (MobiusGyr(cA,-cB) * cB))
@jit @jit(cache=True)
def MobiusCosub(cA,cB): def MobiusCosub(cA,cB):
return MobiusAdd(cA, -(MobiusGyr(cA,cB) * cB)) return MobiusAdd(cA, -(MobiusGyr(cA,cB) * cB))
@jit @jit(cache=True)
def MobiusLine(cA,cB,rT): def MobiusLine(cA,cB,rT):
return MobiusAdd( return MobiusAdd(
cA, cA,
@ -71,18 +72,23 @@ def MobiusLine(cA,cB,rT):
MobiusAdd(-cA,cB), MobiusAdd(-cA,cB),
rT)) rT))
@jit @jit(cache=True)
def MobiusDist(cA,cB): def MobiusDist(cA,cB):
return abs(MobiusAdd(-cB,cA)) return abs(MobiusAdd(-cB,cA))
@jit @jit(cache=True)
def Poincare2Klein(cN): def Poincare2Klein(cN):
return 2*cN / (1 + cDot(cN,cN)) return 2*cN / (1 + cDot(cN,cN))
@jit @jit(cache=True)
def Klein2Poincare(cN): def Klein2Poincare(cN):
return (1-sqrt(1-cDot(cN,cN)))*cN/cDot(cN,cN) return (1-sqrt(1-cDot(cN,cN)))*cN/cDot(cN,cN)
gyrosig = [
('cPos', c16),
('cRot', c16)
]
@jitclass(gyrosig)
class GyroVector: class GyroVector:
def __init__(self, cPos, cRot): def __init__(self, cPos, cRot):
self.cPos = complex(cPos) self.cPos = complex(cPos)

View File

@ -1,6 +1,16 @@
from os import makedirs from os import makedirs
from time import time 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: class Segment:
def __init__(self,bA,cA,cB,trColor): def __init__(self,bA,cA,cB,trColor):
self.isFinite = bA self.isFinite = bA

View File

@ -1,20 +1,20 @@
from numba import jit from numba import jit
@jit @jit(cache=True)
def LineIntersection(rX1,rY1,rX2,rY2,rX3,rY3,rX4,rY4): 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) ) 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) ) rY = ( (rX1*rY2-rY1*rX2)*(rY3-rY4)-(rY1-rY2)*(rX3*rY4-rY3*rX4) ) / ( (rX1-rX2)*(rY3-rY4)-(rY1-rY2)*(rX3-rX4) )
return (rX, rY) return (rX, rY)
@jit @jit(cache=True)
def cLineIntersection(cA0, cA1, cB0, cB1): 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) rX, rY = LineIntersection(cA0.real, cA0.imag, cA1.real, cA1.imag, cB0.real, cB0.imag, cB1.real, cB1.imag)
return complex(rX, rY) return complex(rX, rY)
@jit @jit(cache=True)
def Between(rA,rB,rN): def Between(rA,rB,rN):
return (rA <= rN and rN <= rB) or (rB <= rN and rN <= rA) return (rA <= rN and rN <= rB) or (rB <= rN and rN <= rA)
@jit @jit(cache=True)
def cBetween(cA,cB,cN): def cBetween(cA,cB,cN):
return Between(cA.real,cB.real,cN.real) and Between(cA.imag,cB.imag,cN.imag) return Between(cA.real,cB.real,cN.real) and Between(cA.imag,cB.imag,cN.imag)

17
main.py
View File

@ -9,14 +9,12 @@ import pygame
import pygame.freetype import pygame.freetype
from levels import Segment, open_level, parse_level_from_string from levels import Segment, open_level, parse_level_from_string
from gyro import * from gyro import GyroVector, Poincare2Klein
from levels import * from levels import open_level, save_level, parse_level_from_string, make_wall
from constants import * from constants import I, WHITE, BLACK, IROT, ROT, OFFSET
from draw import draw from draw import draw
from alert import Alert from alert import Alert
bCap = True
gOrigin = GyroVector(0,1) gOrigin = GyroVector(0,1)
SKY = (127,127,255) SKY = (127,127,255)
@ -38,6 +36,8 @@ def nonzerocap(n):
return n return n
def mainLoop(): def mainLoop():
bCap = True
bCont = True
gPlayer = GyroVector(0,1) gPlayer = GyroVector(0,1)
display = pygame.display.set_mode((1280,720)) display = pygame.display.set_mode((1280,720))
clock = pygame.time.Clock() clock = pygame.time.Clock()
@ -45,7 +45,7 @@ def mainLoop():
debugInfo = True debugInfo = True
wall_buffer = [] wall_buffer = []
alerts = [] alerts = []
def alert_append(alert, delay): def alert_append(alert, delay):
if len(alerts) >= 1: if len(alerts) >= 1:
alerts.pop() alerts.pop()
@ -59,17 +59,16 @@ def mainLoop():
leveltoparse = open_level("maps/squareroom.p3hel") leveltoparse = open_level("maps/squareroom.p3hel")
level = parse_level_from_string(leveltoparse) level = parse_level_from_string(leveltoparse)
while True: while bCont:
for event in pygame.event.get(): for event in pygame.event.get():
if event.type == pygame.QUIT: if event.type == pygame.QUIT:
return True bCont = False
if event.type == pygame.KEYDOWN: if event.type == pygame.KEYDOWN:
if event.key == pygame.K_r: if event.key == pygame.K_r:
gPlayer.cRot *= -1 gPlayer.cRot *= -1
if event.key == pygame.K_F3: if event.key == pygame.K_F3:
debugInfo = not debugInfo debugInfo = not debugInfo
if event.key == pygame.K_F1: if event.key == pygame.K_F1:
global bCap
bCap = not bCap bCap = not bCap
if event.key == pygame.K_F2: if event.key == pygame.K_F2:
if (len(wall_buffer) == 1): if (len(wall_buffer) == 1):