259 lines
7.6 KiB
Python
259 lines
7.6 KiB
Python
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)) |