Observer: parameterize Schwarzschild camera view

This commit is contained in:
wyj committed 2026-08-27 04:12:17 -04:00
1 parent 457c0728b4
commit 83dc05fd52
5 files changed
+98 -21

No files matched your search

+8 -3
View File
@@ -19,6 +19,7 @@ typedef struct {
int coarse_cell_pixels;
int draw_mesh;
double horizontal_fov_deg, look_ra_deg, look_dec_deg, exposure;
double observer_radius;
double observer_inward_speed;
PointSpreadFunction psf;
const char *catalog_path;
@@ -102,6 +103,7 @@ static int parse_args(int argc, char **argv, Settings *s,
.look_ra_deg = 270.0,
.look_dec_deg = 0.0,
.exposure = 1e-3,
.observer_radius = 30.0,
.psf = {2.7, 4.5},
.catalog_path = "assets/sky_grid_5deg.csv",
.output_path = "output/imgs/minkowski_sky.ppm",
@@ -137,6 +139,8 @@ static int parse_args(int argc, char **argv, Settings *s,
!parse_positive(argv[++i], &s->exposure)) {
} else if (!strcmp(argv[i], "--observer-inward-speed") && i + 1 < argc &&
!parse_speed(argv[++i], &s->observer_inward_speed)) {
} else if (!strcmp(argv[i], "--observer-radius") && i + 1 < argc &&
!parse_positive(argv[++i], &s->observer_radius)) {
} else if (!strcmp(argv[i], "--psf-fwhm-pixels") && i + 1 < argc &&
!parse_positive(argv[++i], &s->psf.fwhm_pixels)) {
} else if (!strcmp(argv[i], "--psf-moffat-beta") && i + 1 < argc &&
@@ -184,8 +188,9 @@ static GeodesicTraceConfig trace_config(void) {
static int default_observer(const Settings *s, ObserverState *observer) {
#ifdef SPACETIME_SCHWARZSCHILD
return observer_inward_schwarzschild_ks(1.0, 30.0,
s->observer_inward_speed, observer);
return observer_inward_schwarzschild_ks_look_at(
1.0, s->observer_radius, s->look_ra_deg, s->look_dec_deg,
s->observer_inward_speed, observer);
#else
*observer = observer_fixed_at_origin_look_at(s->look_ra_deg, s->look_dec_deg);
return 0;
@@ -352,7 +357,7 @@ int main(int argc, char **argv) {
fprintf(stderr,
"Usage: %s [--catalog PATH | --all-sky-catalog DIR] [--output PATH] [--width N] [--height "
"N] [--fov-deg D] [--look-ra-deg D] [--look-dec-deg D] "
"[--exposure E] [--observer-inward-speed V] "
"[--exposure E] [--observer-radius R] [--observer-inward-speed V] "
"[--psf-fwhm-pixels N] [--psf-moffat-beta N] "
"[--coarse-cell-pixels N] [--draw-mesh] [--write-catalog PATH] "
"[--catalog-load-workers N] "
+58 -12
View File
@@ -30,29 +30,69 @@ ObserverState observer_fixed_at_origin_look_at(double ra_deg, double dec_deg) {
{0.0, right[0], right[1], right[2]}}};
}
int observer_static_schwarzschild_ks(double mass, double radius,
ObserverState *out) {
if (out == NULL || mass <= 0.0 || radius <= 2.0 * mass)
static int schwarzschild_look_direction(double ra_deg, double dec_deg,
double direction[3], double up[3],
double right[3]) {
if (!isfinite(ra_deg) || !isfinite(dec_deg) || ra_deg < 0.0 ||
ra_deg >= 360.0 || dec_deg < -90.0 || dec_deg > 90.0)
return -1;
const double ra = ra_deg * pi / 180.0;
const double dec = dec_deg * pi / 180.0;
const double cos_ra = cos(ra), sin_ra = sin(ra);
const double cos_dec = cos(dec), sin_dec = sin(dec);
direction[0] = cos_dec * cos_ra;
direction[1] = sin_dec;
direction[2] = cos_dec * sin_ra;
up[0] = -sin_dec * cos_ra;
up[1] = cos_dec;
up[2] = -sin_dec * sin_ra;
right[0] = -sin_ra;
right[1] = 0.0;
right[2] = cos_ra;
return 0;
}
int observer_static_schwarzschild_ks_look_at(double mass, double radius,
double look_ra_deg,
double look_dec_deg,
ObserverState *out) {
double direction[3], up[3], right[3];
if (out == NULL || mass <= 0.0 || radius <= 2.0 * mass ||
schwarzschild_look_direction(look_ra_deg, look_dec_deg, direction, up,
right))
return -1;
const double f = 2.0 * mass / radius;
const double normalization = sqrt(1.0 - f);
*out = (ObserverState){
.coordinate_time = 0.0,
.coordinate_position = {radius, 0.0, 0.0},
/* e_(0) is the static four-velocity. e_(1) points inward; its time
* component makes the tetrad orthonormal in the KS metric. */
.coordinate_position = {-radius * direction[0], -radius * direction[1],
-radius * direction[2]},
/* e_(0) is the static four-velocity. e_(1) points inward, toward the
* origin; its time component makes the tetrad orthonormal in the KS
* metric. */
.tetrad = {{1.0 / normalization, 0.0, 0.0, 0.0},
{-f / normalization, -normalization, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0},
{0.0, 0.0, 0.0, 1.0}}};
{-f / normalization, normalization * direction[0],
normalization * direction[1], normalization * direction[2]},
{0.0, up[0], up[1], up[2]},
{0.0, right[0], right[1], right[2]}}};
return 0;
}
int observer_inward_schwarzschild_ks(double mass, double radius,
double inward_speed, ObserverState *out) {
int observer_static_schwarzschild_ks(double mass, double radius,
ObserverState *out) {
return observer_static_schwarzschild_ks_look_at(mass, radius, 180.0, 0.0,
out);
}
int observer_inward_schwarzschild_ks_look_at(double mass, double radius,
double look_ra_deg,
double look_dec_deg,
double inward_speed,
ObserverState *out) {
ObserverState static_observer;
if (inward_speed < 0.0 || inward_speed >= 1.0 ||
observer_static_schwarzschild_ks(mass, radius, &static_observer))
observer_static_schwarzschild_ks_look_at(
mass, radius, look_ra_deg, look_dec_deg, &static_observer))
return -1;
const double gamma = 1.0 / sqrt(1.0 - inward_speed * inward_speed);
@@ -65,3 +105,9 @@ int observer_inward_schwarzschild_ks(double mass, double radius,
}
return 0;
}
int observer_inward_schwarzschild_ks(double mass, double radius,
double inward_speed, ObserverState *out) {
return observer_inward_schwarzschild_ks_look_at(mass, radius, 180.0, 0.0,
inward_speed, out);
}
+15 -4
View File
@@ -12,12 +12,23 @@ ObserverState observer_fixed_at_origin(void);
/* Point the fixed inertial observer at an ICRS-style RA/Dec direction.
* The local spatial axes remain (forward, celestial north, increasing RA). */
ObserverState observer_fixed_at_origin_look_at(double ra_deg, double dec_deg);
/* Static camera at (radius, 0, 0) in Cartesian Kerr--Schild coordinates,
* directed toward the Schwarzschild black hole at the origin. */
/* Static camera at Cartesian Kerr--Schild position -radius * look_direction,
* directed toward the Schwarzschild black hole at the origin. look_direction
* uses the same ICRS-style RA/Dec convention as the flat-space camera. */
int observer_static_schwarzschild_ks_look_at(double mass, double radius,
double look_ra_deg,
double look_dec_deg,
ObserverState *out);
/* Compatibility shortcut for the +X camera directed toward the origin. */
int observer_static_schwarzschild_ks(double mass, double radius,
ObserverState *out);
/* Camera at (radius, 0, 0), moving inward at local speed inward_speed with
* respect to the static Schwarzschild observer. */
/* As above, with a local radial inward boost relative to the static observer. */
int observer_inward_schwarzschild_ks_look_at(double mass, double radius,
double look_ra_deg,
double look_dec_deg,
double inward_speed,
ObserverState *out);
/* Compatibility shortcut for the +X camera directed toward the origin. */
int observer_inward_schwarzschild_ks(double mass, double radius,
double inward_speed, ObserverState *out);