p3he/draw.py
2024-04-07 17:48:14 +05:00

51 lines
1.5 KiB
Python

from cmath import exp
from constants import I, BLACK
from gyro import MobiusInt, MobiusAdd, MobiusDist, cDot, Poincare2Klein
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,dscale):
EMPTYDRAWN = DrawnSegment(0, BLACK)
drawn = [EMPTYDRAWN] * res
irot = exp(fov/res*I)
iprot = gPlayer.cRot
for i in range(res):
m = None
rot = irot**(i-(res/2)) * iprot
for j in level:
try: # Function "LineIntersection" faults from time to time
cInt = MobiusInt(j.pointA,j.pointB,gPlayer.cPos,rot)
except:
continue
if cDot(rot,MobiusAdd(cInt,-gPlayer.cPos)) > 0:
continue
rDist = MobiusDist(cInt,gPlayer.cPos) * dscale
if j.isFinite and not cBetween(Poincare2Klein(j.pointA),Poincare2Klein(j.pointB),Poincare2Klein(cInt)):
continue
if m is None:
m = DrawnSegment(rDist,j.color)
continue
if m.dist > rDist:
m = DrawnSegment(rDist,j.color)
drawn[i] = (m if m is not None else EMPTYDRAWN)
return drawn