This commit is contained in:
2025-05-13 03:12:25 +03:00
parent 9dc1ba897d
commit bd529a5210
31 changed files with 2662 additions and 0 deletions
+330
View File
@@ -0,0 +1,330 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Security.Cryptography;
using JetBrains.Annotations;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
public class BlackHoleRenderer : MonoBehaviour {
void Start() {
}
struct Ray
{
public SphericalDir Dir;
public SphericalCoord P; //Canonical momenta
public double b;
public double q;
public Double3 DirectionOfMotionInCameraCortesianSpace(Double3 N, double beta) { //F
double betaSquare = beta * beta;
double nfy = (-N.Y + beta) / (1.0 - (beta * N.Y));
double nfx = (-Math.Sqrt(1.0 - betaSquare) * N.X) / (1.0 - beta * N.Y);
double nfz = (-Math.Sqrt(1.0 - betaSquare) * N.Z) / (1.0 - beta * N.Y);
return new Double3 { X = nfx, Y = nfy, Z = nfz };
}
public SphericalCoord FSpherical(SphericalCoord B, Double3 nF) {
double kappa = Math.Sqrt(B.R * B.R + B.Dir.Phi * B.Dir.Phi);
double nFr = ((B.Dir.Phi / kappa) * nF.X) + (B.R * nF.Y) + ((B.R * B.Dir.Theta) / kappa) * nF.Z;
double nFTheta = B.Dir.Theta * nF.Y - kappa * nF.Z;
double nFPhi = (-B.R / kappa) * nF.X + B.Dir.Phi * nF.Y + ((B.Dir.Phi * B.Dir.Theta) / kappa) * nF.Z;
SphericalCoord result;
result.R = nFr;
result.Dir.Theta = nFTheta;
result.Dir.Phi = nFPhi;
return result;
}
public void CanonicalMomenta(FidoCamera camera, KerrMetric metric) { //p
var N = Dir.ToCartesian();
var Fdir = DirectionOfMotionInCameraCortesianSpace(N, camera.Beta);
var F = FSpherical(camera.Speed, Fdir);
double Ef = 1.0 / (metric.Alpha + metric.Omega * metric.OmegaUpLine * F.Dir.Phi);
double pr = Ef * (metric.Rho / Math.Sqrt(metric.Delta)) * F.R;
double pTheta = Ef * metric.Rho * F.Dir.Theta;
double pPhi = Ef * metric.OmegaUpLine * F.Dir.Phi;
SphericalCoord result;
result.R = pr;
result.Dir.Phi = pPhi;
result.Dir.Theta = pTheta;
P = result;
}
public void Update(FidoCamera camera, KerrMetric metric)
{
CanonicalMomenta(camera, metric);
b = P.Dir.Phi;
double cosTheta = Math.Cos(Dir.Theta);
double sinTheta = Math.Sin(Dir.Theta);
q = P.Dir.Theta * P.Dir.Theta +
cosTheta * cosTheta * (((b * b) / (sinTheta * sinTheta)) - metric.A * metric.A);
}
}
double betaZero(double r_zero, BlackHole hole)
{
double r_zero_square = r_zero * r_zero;
double r_zero_cube = r_zero_square * r_zero;
double a_square = hole.A * hole.A;
return -((r_zero_cube - 3 * r_zero_square + a_square * r_zero + a_square) / (hole.A * (r_zero - 1.0)));
}
double qZero(double r, BlackHole hole) {
double rSquare = r * r;
double rCube = rSquare * r;
double aSquare = hole.A * hole.A;
double rm1 = r - 1;
double rmSquare = rm1 * rm1;
return -(rCube * (rCube - 6 * rSquare + 9 * r - 4 * aSquare)) / (aSquare * rmSquare);
}
double rZero_0(double b, double a) { //my
var aSquare = a * a;
var subExpr0 = 3 * aSquare + 3 * a * b - 9;
var subExpr2 = (54 - 54 * aSquare);
var cubeRootOf2 = Math.Pow(2.0, 1.0 / 3.0);
var subExpr1 = Math.Pow(Math.Sqrt(Math.Abs(4 * subExpr0 * subExpr0 * subExpr0 + subExpr2 * subExpr2)) + subExpr2, 1.0 / 3.0);
return -(cubeRootOf2 * subExpr0) / (3.0 * subExpr1) + (subExpr1 / (3.0 * cubeRootOf2)) + 1;
}
double rZero_1(double b, double a) { //my
var aSquare = a * a;
var subExpr0 = 3 * aSquare + 3 * a * b - 9;
var subExpr2 = (54 - 54 * aSquare);
var cubeRootOf2 = Math.Pow(2.0, 1.0 / 3.0);
var subExpr1 = Math.Pow(Math.Sqrt(Math.Abs(4 * subExpr0 * subExpr0 * subExpr0 + subExpr2 * subExpr2)) + subExpr2, 1.0 / 3.0);
return ((1 + Math.Sqrt(3.0)) * subExpr0) / (3.0 * Math.Pow(2.0, 2.0/3.0) * subExpr1) - (( (1 - Math.Sqrt(3)) * subExpr1) / (6.0 * cubeRootOf2)) + 1;
}
double rZero_2(double b, double a) { //my
var aSquare = a * a;
var subExpr0 = 3 * aSquare + 3 * a * b - 9;
var subExpr2 = (54 - 54 * aSquare);
var cubeRootOf2 = Math.Pow(2.0, 1.0 / 3.0);
var subExpr1 = Math.Pow(Math.Sqrt(Math.Abs(4 * subExpr0 * subExpr0 * subExpr0 + subExpr2 * subExpr2)) + subExpr2, 1.0 / 3.0);
return ((1 - Math.Sqrt(3.0)) * subExpr0) / (3.0 * Math.Pow(2.0, 2.0 / 3.0) * subExpr1) - (((1 + Math.Sqrt(3)) * subExpr1) / (6.0 * cubeRootOf2)) + 1;
}
[Serializable]
public class FidoCamera
{
public SphericalCoord Position;
public SphericalCoord Speed;
public double Beta;
public void UpdateMetricAndSelf(KerrMetric metric, BlackHole hole)
{
metric.Update(hole.A, Position.R, Position.Dir.Theta);
double bigOmega = 1.0 / (metric.A + Math.Pow(Position.R, 3.0 / 2.0));
Beta = (metric.OmegaUpLine / metric.Alpha) * (bigOmega - metric.Omega);
}
}
[Serializable]
public class BlackHole
{
public double A;
public double r1() {
return 2 * (1 + Math.Cos((2.0 / 3.0) * Math.Acos(-A)));
}
public double r2() {
return 2 * (1 + Math.Cos((2.0 / 3.0) * Math.Acos(A)));
}
}
[Serializable]
public class KerrMetric {
public double Delta;
public double Rho;
public double OmegaUpLine;
public double Omega;
public double Sigma;
public double Alpha;
public double A;
public void Update(double a, double r, double theta) {
double cosTheta = Math.Cos(theta);
double sinTheta = Math.Sin(theta);
double cosThetaSquare = cosTheta * cosTheta;
double sinThetaSquare = sinTheta * sinTheta;
double aSquare = a * a;
double rSquare = r * r;
Rho = Math.Sqrt(rSquare + (aSquare * cosThetaSquare));
Delta = rSquare - (2 * r) + aSquare;
Sigma = Math.Sqrt((rSquare + aSquare) * (rSquare + aSquare) - aSquare * Delta * sinThetaSquare);
Alpha = (Rho * Math.Sqrt(Delta)) / Sigma;
Omega = (2 * a * r) / (Sigma * Sigma);
OmegaUpLine = (Sigma * sinTheta) / Rho;
A = a;
}
}
public FidoCamera Camera = new FidoCamera();
public KerrMetric Metric = new KerrMetric();
public BlackHole Hole = new BlackHole();
public void RecalcState()
{
Camera.UpdateMetricAndSelf(Metric, Hole);
}
double drdt(double delta, double rho, double Pr)
{
return delta / (rho * rho) * Pr;
}
SphericalDir[] rays = new SphericalDir[256];
class BlackHoleRayIntegrator : Integrator
{
}
void DrawCameraGizmo() {
var pos = Camera.Position.ToCartesian().ToVector3();
UpdateRays();
foreach (var rayDir in rays)
{
Ray ray = new Ray();
ray.Dir = rayDir;
ray.Update(Camera, Metric);
var v0 = rZero_0(0.666, 0.9);
var v1 = rZero_1(0.666, 0.9);
var v2 = rZero_2(0.666, 0.9);
// var b1 = betaZero(Hole.r2());
// var b2 = betaZero(Hole.r1());
//-0.1184053483681316836 + 0.×10^-19 i
//0.7514421233051754296 + 0.×10^-19 i
//2.3669632250629562540 + 0.×10^-20 i
var N = ray.Dir.ToCartesian();
var Fdir = ray.DirectionOfMotionInCameraCortesianSpace(N, Camera.Beta);
var F = ray.FSpherical(Camera.Speed, Fdir);
Gizmos.DrawLine(pos, pos + ray.P.ToCartesian().ToVector3());
/*
var r0 = rZero2(b);
var r0_ = rZero(b);
//r0 = 2.1899962982234369;
var q0 = qZero2(r0, b);
Color rayColor = Color.white;
if (((b1 < b) && (b < b2)) && (q < q0))
{
//there are no radial turning points for that {b, q}
if (rayCanonicalMomenta_.R > 0)
{
//horizon
rayColor = Color.black;
horizon++;
}
else
{
celestial++;
}
}
else
{
var a = a_spinAngularMomentumPerMass;
double P = Math.Sqrt(Metric.Delta * ((b - a) * (b - a) + q));
double rUp0 = P + a * b - a * a;
double rUp1 = -P + a * b - a * a;
double rUp = rUp0 > rUp1 ? rUp0 : rUp1;
if (cameraPosition.R > rUp)
{
celestial++;
}
else
{
horizon++;
//horizon
rayColor = Color.black;
}
}*/
}
}
public void OnDrawGizmos() {
// double accretionDiskInnerRadius = 9.26 * M_blackHoleMass;
// double accretionDiskOuterRadius = 18.7 * M_blackHoleMass;
Gizmos.DrawLine(Vector3.zero, Camera.Position.ToCartesian().ToVector3());
Gizmos.DrawWireSphere(Vector3.zero, 1);
DrawCameraGizmo();
// double OmegaBig = CameraGeodesicAngularVelocity(Rc);
//DrawCameraGizmo(cameraCoord, cameraDirectionOfMotion);
}
void UpdateRays()
{
int imageHeight = 16;
int imageWidth = 16;
int totalRays = imageHeight * imageWidth;
if (rays == null || rays.Length != totalRays)
{
rays = new SphericalDir[totalRays];
}
double verticalFov = Math.PI / 2;
double horizontalFov = ((double)imageWidth / imageHeight) * verticalFov;
for (int y = 0; y < imageHeight; y++)
{
double rayTheta = (Math.PI / 2) - verticalFov / 2 + (verticalFov / (imageHeight - 1) * y);
for (int x = 0; x < imageWidth; x++)
{
double rayPhi = Math.PI + horizontalFov / 2 - (horizontalFov / (imageWidth - 1) * x);
rays[y * imageWidth + x].Phi = rayPhi;
rays[y * imageWidth + x].Theta = rayTheta;
}
}
}
public void Trace()
{
RecalcState();
}
}