Dateien nach "/" hochladen
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
from scipy.integrate import solve_ivp
|
||||
import math
|
||||
import numpy as np
|
||||
from scipy.constants import pi
|
||||
from scipy.interpolate import interp1d
|
||||
from functools import cache
|
||||
import copy
|
||||
from PIL import Image
|
||||
|
||||
|
||||
class Ray():
|
||||
interpolation = None
|
||||
|
||||
def __init__(self, x, y, D, Rs, fov, res, accuracy):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.D = D
|
||||
self.Rs = Rs
|
||||
self.fovX = fov[0]
|
||||
self.fovY = fov[1]
|
||||
self.res = res
|
||||
self.accuracy = accuracy
|
||||
|
||||
if Ray.interpolation is None:
|
||||
self.interpolate()
|
||||
|
||||
self.interpolation = Ray.interpolation
|
||||
|
||||
def interpolate(self):
|
||||
maxA = self.fovX
|
||||
minA = self.apperentSize(0, 180)
|
||||
|
||||
linspace = np.linspace(0, 1, self.accuracy)
|
||||
angles = minA + (maxA - minA) * linspace**6
|
||||
|
||||
array = []
|
||||
for i in range(self.accuracy):
|
||||
sol = self.solver(angles[i])
|
||||
deviatedAngle = sol[1][len(sol[1]) - 1]
|
||||
array.append([angles[i], np.degrees(deviatedAngle)])
|
||||
|
||||
#interpolierung der punkte
|
||||
points = np.array(array)
|
||||
Ray.interpolation = interp1d(points[:, 0], points[:, 1], kind='cubic')
|
||||
|
||||
def solver(self, alpha):
|
||||
if alpha == 0: # skip divided by 0 error
|
||||
return [0], [0] # r and phi=0
|
||||
|
||||
if alpha == 180:
|
||||
return [self.D], [0] # if angle= pi then, tan(pi)=0 so 1/tan=1/0
|
||||
|
||||
# initial value for position and angular speed
|
||||
y0 = [1/self.D, 1/(self.D*math.tan(math.radians(alpha)))]
|
||||
sol = solve_ivp(fun=self._diff_eq, t_span=[0, 10*pi], y0=y0, method='DOP853', events=[self._eventRs]) #, self._eventR])#,t_eval=np.linspace(0, t_max, 10000)) #dense_output=False
|
||||
|
||||
if sol.t[-1] == 10*pi:
|
||||
raise StopIteration("solver error, alpha reached computation limit (loop number)")
|
||||
|
||||
phi = np.array(sol.t)
|
||||
r = np.abs(1/sol.y[0, :]) # must use this because solver can't be stop before infinity because negative
|
||||
|
||||
return r, phi
|
||||
|
||||
def _diff_eq(self, phi, u):
|
||||
"""Represent the differential equation : d²u(ɸ)/dɸ²=3/2*Rs*u²(ɸ)-u(ɸ)
|
||||
"""
|
||||
v0 = u[1] #correspond to u'
|
||||
v1 = 3/2*self.Rs*u[0]**2 - u[0] #correspond to u"
|
||||
return v0, v1
|
||||
|
||||
def _eventRs(self, phi, u):
|
||||
"""stop solver if radius < black hole radius"""
|
||||
with np.errstate(all='ignore'):
|
||||
return 1/u[0] - self.Rs
|
||||
_eventRs.terminal = True
|
||||
|
||||
def apperentSize(self, a1, a2):
|
||||
|
||||
if a2-a1 <= .01: #!!!!!!!!!!!!MaxDeviation später einfügen maybe
|
||||
return a2
|
||||
|
||||
points = np.linspace(a1, a2, 3)
|
||||
point = self.solver(points[1])
|
||||
|
||||
test = point[0][len(point[0]) - 1 ]
|
||||
|
||||
if test > self.Rs:
|
||||
return self.apperentSize(a1, points[1])
|
||||
|
||||
|
||||
elif test <= self.Rs:
|
||||
return self.apperentSize(points[1], a2)
|
||||
else:
|
||||
print("Fehler")
|
||||
|
||||
def angle(self):
|
||||
x = self.x
|
||||
y = self.y
|
||||
|
||||
n = None
|
||||
m = None
|
||||
|
||||
angle = math.degrees(math.atan2(math.sqrt(n**2 + m**2)))
|
||||
return self.interpolation(angle)
|
||||
+259
@@ -0,0 +1,259 @@
|
||||
from scipy.integrate import solve_ivp
|
||||
import math
|
||||
import numpy as np
|
||||
from scipy.constants import pi
|
||||
from scipy.interpolate import interp1d
|
||||
import copy
|
||||
from PIL import Image
|
||||
|
||||
Rs = 8 # in au
|
||||
D = 50 # -"-
|
||||
accuracy = 100 # amount of iterations of solver
|
||||
res = 500 #as pixel on X-Axis
|
||||
fovX = 180 #in ° ####vorläufig über 180
|
||||
fovY = 180 # -"-
|
||||
maxDeviation = .01 # bei zu kleinem wert, knick in interpolation. ?photonensphäre? später lösen!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
bg = Image.open("old/images/background.jpg")
|
||||
#test = []
|
||||
|
||||
def solver(alpha):
|
||||
if alpha == 0: # skip divided by 0 error
|
||||
return [0], [0] # r and phi=0
|
||||
|
||||
if alpha == 180:
|
||||
return [D], [0] # if angle= pi then, tan(pi)=0 so 1/tan=1/0
|
||||
|
||||
# initial value for position and angular speed
|
||||
y0 = [1/D, 1/(D*math.tan(math.radians(alpha)))]
|
||||
sol = solve_ivp(fun=_diff_eq, t_span=[0, 10*pi], y0=y0, method='DOP853', events=[_eventRs]) #, self._eventR])#,t_eval=np.linspace(0, t_max, 10000)) #dense_output=False
|
||||
|
||||
if sol.t[-1] == 10*pi:
|
||||
raise StopIteration("solver error, alpha reached computation limit (loop number)")
|
||||
|
||||
phi = np.array(sol.t)
|
||||
r = np.abs(1/sol.y[0, :]) # must use this because solver can't be stop before infinity because negative
|
||||
|
||||
#print("alpha:", alpha)
|
||||
#print(phi, r)
|
||||
|
||||
print("I AM DOING SOMETHING!!", alpha)
|
||||
|
||||
return r, phi
|
||||
|
||||
def _diff_eq(phi, u):
|
||||
"""Represent the differential equation : d²u(ɸ)/dɸ²=3/2*Rs*u²(ɸ)-u(ɸ)
|
||||
"""
|
||||
v0 = u[1] #correspond to u'
|
||||
v1 = 3/2*Rs*u[0]**2 - u[0] #correspond to u"
|
||||
return v0, v1
|
||||
|
||||
|
||||
def _eventRs(phi, u):
|
||||
"""stop solver if radius < black hole radius"""
|
||||
with np.errstate(all='ignore'):
|
||||
return 1/u[0] - Rs
|
||||
_eventRs.terminal = True
|
||||
|
||||
|
||||
|
||||
def apperentSize(a1, a2):
|
||||
|
||||
if a2-a1 <= maxDeviation:
|
||||
print(a2)
|
||||
return a2
|
||||
|
||||
|
||||
points = np.linspace(a1, a2, 3)
|
||||
point = solver(points[1])
|
||||
|
||||
test = point[0][len(point[0]) - 1 ]
|
||||
|
||||
if test > Rs:
|
||||
print("1")
|
||||
return apperentSize(a1, points[1])
|
||||
|
||||
|
||||
elif test <= Rs:
|
||||
print("2")
|
||||
return apperentSize(points[1], a2)
|
||||
else:
|
||||
print("Fehler")
|
||||
|
||||
def getAllAngles():
|
||||
maxA = 0# 180 - math.degrees( math.acos(math.cos(math.radians(fovX)) * math.cos(math.radians(fovY)))) #math.sqrt(((fovX/2)**2) + ((fovY/2)**2))
|
||||
print("MAX_____________________", maxA)
|
||||
maxA = fovX
|
||||
#maxA = 90
|
||||
|
||||
minA = apperentSize(0, 180)
|
||||
print(minA)
|
||||
# minA = 24.2086
|
||||
|
||||
linspace = np.linspace(0, 1, accuracy)
|
||||
|
||||
angles = minA + (maxA - minA) * linspace**6 #beser als **6 finden !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
#angles = np.geomspace(minA, maxA, accuracy)
|
||||
array = []
|
||||
for i in range(accuracy):
|
||||
sol = solver(angles[i])
|
||||
deviatedAngle = sol[1][len(sol[1]) - 1]
|
||||
array.append([angles[i], np.degrees(deviatedAngle)])
|
||||
|
||||
#print(array)
|
||||
|
||||
#interpolierung der punkte
|
||||
|
||||
points = np.array(array)
|
||||
|
||||
f = interp1d(points[:, 0], points[:, 1], kind='cubic')
|
||||
|
||||
#x_new = np.linspace(points[:, 0].min(), points[:, 0].max(), 5000)
|
||||
#y_new = f(x_new)
|
||||
#
|
||||
#plt.figure()
|
||||
#plt.scatter(points[:, 0], points[:, 1])
|
||||
#plt.plot(x_new, y_new, '-', label='Kubische Interpolation', color= 'orange')
|
||||
#plt.xlabel("Seen angle")
|
||||
#plt.ylabel("deviated angle")
|
||||
#plt.title("Punkte aus array")
|
||||
#plt.grid(True)
|
||||
#plt.show()
|
||||
|
||||
#berechnung der einzelnen Pixel
|
||||
|
||||
resX = res
|
||||
resY = int(res * fovY / fovX)
|
||||
|
||||
deviationOfPixels = []
|
||||
|
||||
conversion = maxA / math.degrees( math.acos(math.cos(math.radians(resX) / 2) * math.cos(math.radians(resY) / 2))) #####################################################################
|
||||
|
||||
for x in range(int(resX / 2)):
|
||||
deviationOfPixels.append([])
|
||||
for y in range(int(resY / 2)):
|
||||
deviationOfPixels[x].append([])
|
||||
|
||||
d = math.degrees( math.acos(math.cos(math.radians(x/int(resX / 2) * fovX / 2)) * math.cos(math.radians(y/int(resY / 2) * fovY / 2))))#% maxA #* conversion
|
||||
|
||||
if d >= minA:
|
||||
|
||||
beta = math.atan2(y, x)
|
||||
|
||||
deviation = f(d) % 360 #unnötige umdrehungen durch subtrahieren von auf 360 gerundeten Wert ignorieren
|
||||
|
||||
alpha = x/int(resX / 2) * fovX / 2
|
||||
beta = y/int(resY / 2) * fovY / 2
|
||||
|
||||
phi = math.degrees(math.atan2(math.sin(math.radians(deviation)) * (math.cos(math.radians(beta)) * math.sin(math.radians(alpha))) / math.sqrt((math.cos(math.radians(beta)) * math.sin(math.radians(alpha)))**2 + math.sin(math.radians(beta))**2), math.cos(math.radians(deviation))))
|
||||
|
||||
theta = 2 * math.degrees(math.asin(math.sin(math.radians(deviation)) * math.sin(math.radians(beta)) / math.sqrt((math.cos(math.radians(beta)) * math.sin(math.radians(alpha)))**2 + math.sin(math.radians(beta))**2)))
|
||||
|
||||
deviationX = theta
|
||||
deviationY = phi
|
||||
|
||||
deviationOfPixels[x][y] = ([deviationX, deviationY])
|
||||
|
||||
else:
|
||||
deviationOfPixels[x][y] = None
|
||||
|
||||
print("ARRAY")
|
||||
|
||||
doc = open("del3.txt", "w")
|
||||
for i in range(len(deviationOfPixels)):
|
||||
doc.write(str(deviationOfPixels[i]))
|
||||
doc.write('\n')
|
||||
doc.close()
|
||||
|
||||
return deviationOfPixels
|
||||
|
||||
def fullArray(array):
|
||||
arr = array
|
||||
arr.reverse()
|
||||
arr2 = copy.deepcopy(arr)
|
||||
result =[]
|
||||
result2 = []
|
||||
for i in range(len(arr2)):
|
||||
arr2[i].reverse()
|
||||
for j in range(len(arr2[i])):
|
||||
if arr2[i][j] != None:
|
||||
|
||||
zahl1, zahl2 = arr2[i][j]
|
||||
|
||||
arr2[i][j] = [-zahl1, zahl2]
|
||||
result.append((arr2[i]) + arr[i])
|
||||
|
||||
res = copy.deepcopy(result)
|
||||
|
||||
for i in range(len(res)):
|
||||
for j in range(len(res[i])):
|
||||
if res[i][j] != None:
|
||||
zahl1, zahl2 = res[i][j]
|
||||
|
||||
res[i][j] = [zahl1, -zahl2]
|
||||
|
||||
res.reverse()
|
||||
|
||||
result2.append(result + res)
|
||||
#result2.append(result)
|
||||
|
||||
return result2[0]
|
||||
|
||||
def allPixel(deviations):
|
||||
Img = []
|
||||
|
||||
|
||||
bgY, bgX = bg.size
|
||||
|
||||
conversionX = bgX / 360
|
||||
print("len", len(deviations))
|
||||
print("con", conversionX)
|
||||
conversionY = bgY / 360
|
||||
print("len", len(deviations[0]))
|
||||
print("con", conversionY)
|
||||
|
||||
test = .5
|
||||
|
||||
print(" max X:", )
|
||||
|
||||
for x in range(len(deviations)):
|
||||
Img.append([])
|
||||
for y in range(len(deviations[x])):
|
||||
Img[x].append([])
|
||||
|
||||
if deviations[x][y] == None:
|
||||
pixel = (0, 0, 0)
|
||||
|
||||
else:
|
||||
px = int(deviations[x][y][0] % 360 * conversionX - (bgX / 2)) - 1
|
||||
py = int(deviations[x][y][1] % 360 * conversionY) - 1
|
||||
|
||||
pixel = bg.getpixel((py ,px))
|
||||
|
||||
Img[x][y] = pixel
|
||||
#print(Img)
|
||||
return Img
|
||||
|
||||
def showImage(arrayx):
|
||||
# Beispiel: array ist dein Pixel-Array
|
||||
# Achtung: Pillow erwartet (height, width), also [y][x]
|
||||
height = len(arrayx[0])
|
||||
width = len(arrayx)
|
||||
|
||||
# In ein flaches Array umwandeln
|
||||
pixels = []
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
pixels.append(arrayx[x][y])
|
||||
|
||||
# Bild erzeugen
|
||||
img = Image.new("RGB", (width, height))
|
||||
img.putdata(pixels)
|
||||
img.show()
|
||||
|
||||
|
||||
deviationOfPixels = getAllAngles()
|
||||
|
||||
array = fullArray(deviationOfPixels)
|
||||
|
||||
showImage(allPixel(array))
|
||||
@@ -1,282 +1,5 @@
|
||||
import pygame
|
||||
import random
|
||||
import time
|
||||
from kart import Kart, Item
|
||||
from Ray import Ray
|
||||
|
||||
ray = Ray(199, 231, 50, 8, [90, 90], [200, 200], 20)
|
||||
|
||||
# -------------------------
|
||||
# Einstellungen
|
||||
# -------------------------
|
||||
|
||||
WIDTH = 1000
|
||||
HEIGHT = 700
|
||||
FPS = 60
|
||||
|
||||
BACKGROUND = (40, 40, 40)
|
||||
|
||||
|
||||
# -------------------------
|
||||
# Hilfsfunktion zum Zeichnen
|
||||
# -------------------------
|
||||
|
||||
def draw_kart(screen, kart):
|
||||
# Kart als Rechteck
|
||||
width = 40
|
||||
height = 25
|
||||
|
||||
surface = pygame.Surface((width, height), pygame.SRCALPHA)
|
||||
pygame.draw.rect(surface, kart.color, (0, 0, width, height))
|
||||
|
||||
# Richtung des Karts
|
||||
rotated = pygame.transform.rotate(surface, -kart.rotation)
|
||||
|
||||
rect = rotated.get_rect(
|
||||
center=(int(kart.position[0]), int(kart.position[1]))
|
||||
)
|
||||
|
||||
screen.blit(rotated, rect)
|
||||
|
||||
|
||||
# -------------------------
|
||||
# Pool zeichnen
|
||||
# -------------------------
|
||||
|
||||
def draw_pool(screen, pool):
|
||||
pygame.draw.ellipse(
|
||||
screen,
|
||||
pool.color,
|
||||
(
|
||||
int(pool.position[0] - pool.size),
|
||||
int(pool.position[1] - pool.size / 2),
|
||||
int(pool.size * 2),
|
||||
int(pool.size)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# -------------------------
|
||||
# Main
|
||||
# -------------------------
|
||||
|
||||
def main():
|
||||
pygame.init()
|
||||
|
||||
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
||||
pygame.display.set_caption("Kart Game")
|
||||
|
||||
clock = pygame.time.Clock()
|
||||
|
||||
# -------------------------
|
||||
# Karts erzeugen
|
||||
# -------------------------
|
||||
|
||||
kart1 = Kart(
|
||||
"Player 1",
|
||||
(255, 50, 50),
|
||||
acceleration=0.2,
|
||||
vMax=5,
|
||||
handling=4
|
||||
)
|
||||
|
||||
kart2 = Kart(
|
||||
"Player 2",
|
||||
(50, 100, 255),
|
||||
acceleration=0.2,
|
||||
vMax=5,
|
||||
handling=4
|
||||
)
|
||||
|
||||
# Startpositionen
|
||||
kart1.position = [250, 350]
|
||||
kart1.rotation = 0
|
||||
|
||||
kart2.position = [750, 350]
|
||||
kart2.rotation = 180
|
||||
|
||||
# -------------------------
|
||||
# Pool
|
||||
# -------------------------
|
||||
|
||||
pool = None
|
||||
|
||||
# Zeitpunkt, wann der nächste Pool erscheint
|
||||
nextPoolTime = time.time() + random.uniform(3, 8)
|
||||
|
||||
running = True
|
||||
|
||||
while running:
|
||||
|
||||
# -------------------------
|
||||
# Events
|
||||
# -------------------------
|
||||
|
||||
for event in pygame.event.get():
|
||||
if event.type == pygame.QUIT:
|
||||
running = False
|
||||
|
||||
# -------------------------
|
||||
# Pool erzeugen / entfernen
|
||||
# -------------------------
|
||||
|
||||
currentTime = time.time()
|
||||
|
||||
# Wenn momentan kein Pool existiert
|
||||
# und die Wartezeit vorbei ist
|
||||
if pool is None and currentTime >= nextPoolTime:
|
||||
|
||||
pool = Item("pool")
|
||||
pool.typ()
|
||||
|
||||
# Zufällige Position
|
||||
pool.position = [
|
||||
random.randint(80, WIDTH - 80),
|
||||
random.randint(80, HEIGHT - 80)
|
||||
]
|
||||
|
||||
# Zufällige Größe
|
||||
pool.size = random.randint(40, 80)
|
||||
|
||||
# Pool bleibt unterschiedlich lange sichtbar
|
||||
poolEndTime = currentTime + random.uniform(3, 7)
|
||||
|
||||
# Pool verschwinden lassen
|
||||
if pool is not None and currentTime >= poolEndTime:
|
||||
|
||||
pool = None
|
||||
|
||||
# Unregelmäßige Zeit bis zum nächsten Pool
|
||||
nextPoolTime = currentTime + random.uniform(3, 10)
|
||||
|
||||
keys = pygame.key.get_pressed()
|
||||
|
||||
# -------------------------
|
||||
# Kart 1
|
||||
# WASD + E
|
||||
# -------------------------
|
||||
|
||||
# W = Gas
|
||||
if keys[pygame.K_w]:
|
||||
kart1.acc(False)
|
||||
|
||||
# S = Rückwärts / Bremsen
|
||||
elif keys[pygame.K_s]:
|
||||
kart1.acc(True)
|
||||
|
||||
# Wenn kein Gas/Bremse -> langsam abbremsen
|
||||
else:
|
||||
kart1.speed *= 0.98
|
||||
|
||||
# A = links
|
||||
if keys[pygame.K_a]:
|
||||
kart1.turn(-1)
|
||||
|
||||
# D = rechts
|
||||
if keys[pygame.K_d]:
|
||||
kart1.turn(1)
|
||||
|
||||
# E = Rammen
|
||||
if keys[pygame.K_e]:
|
||||
kart1.ram(kart2)
|
||||
|
||||
# -------------------------
|
||||
# Kart 2
|
||||
# IJKL + O
|
||||
# -------------------------
|
||||
|
||||
# I = Gas
|
||||
if keys[pygame.K_i]:
|
||||
kart2.acc(False)
|
||||
|
||||
# K = Rückwärts / Bremsen
|
||||
elif keys[pygame.K_k]:
|
||||
kart2.acc(True)
|
||||
|
||||
else:
|
||||
kart2.speed *= 0.98
|
||||
|
||||
# J = links
|
||||
if keys[pygame.K_j]:
|
||||
kart2.turn(-1)
|
||||
|
||||
# L = rechts
|
||||
if keys[pygame.K_l]:
|
||||
kart2.turn(1)
|
||||
|
||||
# O = Rammen
|
||||
if keys[pygame.K_o]:
|
||||
kart2.ram(kart1)
|
||||
|
||||
# -------------------------
|
||||
# Position aktualisieren
|
||||
# -------------------------
|
||||
|
||||
kart1.pos()
|
||||
kart2.pos()
|
||||
|
||||
# -------------------------
|
||||
# Bildschirm verlassen?
|
||||
# -> auf andere Seite wechseln
|
||||
# -------------------------
|
||||
|
||||
# Abstand zum Bildschirmrand
|
||||
border = 20
|
||||
|
||||
for kart in [kart1, kart2]:
|
||||
|
||||
# Linker Rand
|
||||
if kart.position[0] < border:
|
||||
kart.position[0] = border
|
||||
|
||||
# Rechter Rand
|
||||
if kart.position[0] > WIDTH - border:
|
||||
kart.position[0] = WIDTH - border
|
||||
|
||||
# Oberer Rand
|
||||
if kart.position[1] < border:
|
||||
kart.position[1] = border
|
||||
|
||||
# Unterer Rand
|
||||
if kart.position[1] > HEIGHT - border:
|
||||
kart.position[1] = HEIGHT - border
|
||||
|
||||
# -------------------------
|
||||
# Zeichnen
|
||||
# -------------------------
|
||||
|
||||
screen.fill(BACKGROUND)
|
||||
|
||||
# Pool zeichnen
|
||||
if pool is not None:
|
||||
draw_pool(screen, pool)
|
||||
|
||||
draw_kart(screen, kart1)
|
||||
draw_kart(screen, kart2)
|
||||
|
||||
# Namen anzeigen
|
||||
font = pygame.font.Font(None, 28)
|
||||
|
||||
text1 = font.render(
|
||||
f"{kart1.name}: {kart1.speed:.1f}",
|
||||
True,
|
||||
kart1.color
|
||||
)
|
||||
|
||||
text2 = font.render(
|
||||
f"{kart2.name}: {kart2.speed:.1f}",
|
||||
True,
|
||||
kart2.color
|
||||
)
|
||||
|
||||
screen.blit(text1, (20, 20))
|
||||
screen.blit(text2, (20, 50))
|
||||
|
||||
pygame.display.flip()
|
||||
|
||||
# FPS
|
||||
clock.tick(FPS)
|
||||
|
||||
pygame.quit()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
print(ray.angle(90))
|
||||
Reference in New Issue
Block a user