from logging import raiseExceptions from math import * from operator import truediv import os from multiprocessing import set_forkserver_preload import re from time import sleep from tracemalloc import start from weakref import ref #asciiscale asciicontroll = 13 #asciiscale = "$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/|()1{}[]?-_+~<>i!lI;:,^`'." #asciiscale = [i for i in reversed("$hz-:,`.")] #asciiscale = ".-^z$" asciiscale = ".-^^zzzz$$$$$$" #index 0 - 67 #start filetosavein = "run3" startpos = [-6,1,0] #physics stepa = 100*5 stepsize = 0.05 #rendering doFloor = True doReflections = True doFloorlight = True #doReflight = True doLighting = False lightpos = [0,0,3] fovx = 90 fovy = 60 resx = 90*3*2 resy = 30*3*2 #physicslist itemlist = [] itemlist.append(["circle", [0,5,0], 2]) def distance(point1,point2): d = sqrt(pow(point2[0] - point1[0], 2) + pow(point2[1] - point1[1], 2) + pow(point2[2] - point1[2], 2)* 1.0) return d def check(pos): if doFloor: if pos[1] <= -2: if (pos[0] % 4 <= 2 and pos[2] % 4 <= 2) or ((pos[0]+2) % 4 <= 2 and (pos[2]+2) % 4 <= 2) : if doFloorlight: sim = lighting(pos,vectoradd(pos,[0,-1,0]),lightpos) char = asciiscale[round(sim*asciicontroll)] return [True, "floor" , char] return [True, "floor" , "#"] else:return[True, "floor" , " "] for item in itemlist: if item[0] == "circle": if distance(pos,item[1]) < item[2]: return [True, item] else: return [False] def vectoradd(obj1,obj2): return [obj1[0]+obj2[0],obj1[1]+obj2[1],obj1[2]+obj2[2]] def vectorsub(obj1,obj2): return [obj1[0]-obj2[0],obj1[1]-obj2[1],obj1[2]-obj2[2]] def intersect(startpos,xdif,ydif,zdif): pos = startpos pos = [pos[0] + xdif * stepsize, pos[1] + ydif * stepsize, pos[2] + zdif * stepsize] pos = [pos[0] + xdif * stepsize, pos[1] + ydif * stepsize, pos[2] + zdif * stepsize] for _ in range(stepa): #print(pos) res = check(pos) if res[0]: return [True,pos,res] else: pos = [pos[0] + xdif * stepsize, pos[1] + ydif * stepsize, pos[2] + zdif * stepsize] return [False] def vectortoangle(vector): xrot = 0 yrot = 0 #vector = nornalize(vector) xrot = degrees(atan2(vector[2],vector[0])) xlen = sqrt(vector[2]**2 + vector[0]**2) yrot = degrees(atan2(vector[1],xlen)) return(xrot,yrot) def angletovector(anglex,angley): xcoefficient = cos(radians(angley)) ydif = sin(radians(angley)) xdif = cos(radians(anglex)) * xcoefficient zdif = sin(radians(anglex)) * xcoefficient return [xdif,ydif,zdif] def sray(startpos,anglex,angley): v = angletovector(anglex,angley) return intersect(startpos,v[0],v[1],v[2]) def nornalizetovalue(v,am): a = sqrt(v[1]**2+v[2]**2+v[0]**2) a = a/am return [v[0]/a,v[1]/a,v[2]/a] def nornalize(v): a = sqrt(v[1]**2+v[2]**2+v[0]**2) return [v[0]/a,v[1]/a,v[2]/a] def dotproduct(v1,v2): v1 = nornalize(v1) v2 = nornalize(v2) return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2] def lighting(colisionpos,objpos,lightpos): normal = vectorsub(colisionpos,objpos) directiontowardslight = vectorsub(lightpos,colisionpos) sim = dotproduct(normal,directiontowardslight) return sim def reflect(colisionpos,objpos,raydirectionx,raydirectiony): #print(objpos) raydirectionx = 180+raydirectionx raydirectiony = -raydirectiony normal = vectorsub(colisionpos,objpos) normangle = vectortoangle(normal) diff = normangle[0] - raydirectionx , normangle[1] - raydirectiony newdirection = raydirectionx + diff[0]*2 , raydirectiony + diff[1]*2 res = sray(colisionpos,newdirection[0],newdirection[1]) if res[0]: try: if res[2][2] == " ": return "´" else: return res[2][2] except IndexError: return "4" else: return "´" def render2(anglex,angley): frame = [] fovystep = fovy/resy fovxstep = fovx/resx for y in range(resy): currentline = [] for x in range(resx): #print((-fovx/2)+fovxstep*x) #print(anglex+(-fovx/2)+fovxstep*x,angley+fovy/2-fovystep*y) res = sray(startpos, anglex+(-fovx/2)+fovxstep*x , angley+fovy/2-fovystep*y) if res[0]: doRest = True obj = res[1] if doFloor: floorcheck = res[2][1] if floorcheck == "floor": doRest = False frame.append(res[2][2]) if doRest: doRest = True #obj[1] is the pos of the object we colided with #res[1] is the pos of the colosion #together these are used to calculate the normal of the position on the object we colided with if doReflections == True: #print(anglex+(-fovx/2)+fovxstep*x,angley+fovy/2-fovystep*y) #print(res[1]) frame.append(reflect(res[1],itemlist[0][1],anglex+(-fovx/2)+fovxstep*x,angley+fovy/2-fovystep*y)) doRest = False if doRest: doRest = False if doLighting == True: sim = lighting(res[1],obj[1],lightpos) else: frame.append("#") if doLighting == True: if sim > 0.1: frame.append(asciiscale[round(sim*asciicontroll)]) else: frame.append("`") else: frame.append(" ") frame.append("\n") # sleep(1) #os.system("cls") f = open(filetosavein,"a") print("".join(frame)) f.write("".join(frame)) f.close() def reftest(colisionpos,objpos,raydirectionx,raydirectiony): raydirectionx = 180+raydirectionx raydirectiony = -raydirectiony normal = vectorsub(colisionpos,objpos) normangle = vectortoangle(normal) diff = normangle[0] - raydirectionx , normangle[1] - raydirectiony newdirection = raydirectionx + diff[0]*2 , raydirectiony + diff[1]*2 res = sray(colisionpos,newdirection[0],newdirection[1]) #print(res) a= 0 b= -17 print(sray([-6,0,0.2],a,b)) print(reflect([-1.4097371713774294, -1.4033841826691358, 0.2],[0, 0, 0],a,b)) v = 20 startpos = [-6,5,-2] for i in range(24): startpos[2] = -2 + (4/24) * i v -= 40/24 render2(v,0)