diff options
| author | Johannes Hofmann <Johannes.Hofmann@gmx.de> | 2026-10-26 20:05:20 +0100 |
|---|---|---|
| committer | Johannes Hofmann <Johannes.Hofmann@gmx.de> | 2026-10-26 20:05:20 +0100 |
| commit | 375d87a9b0ec1cf2fffd705adb870c86144d2400 (patch) | |
| tree | 1e8e05e7cd58686628d0f4622622456613a42e4d /tests/harness/fitdump.cxx | |
| parent | 45425dd047b791fe63f13a46a3251c529cfffc94 (diff) | |
Replace the C++ implementation with the Rust port
The Rust port (formerly gipfel-rs) is now the official successor to the
FLTK/GSL C++ code base. This squashes the port into a single commit and
removes the C++ sources (they remain in the git history below).
Layout:
crates/gipfel-core headless core: hills, panorama geometry, projections
(maxima-generated derivatives), pure-Rust LM fit,
gipfel: JPEG comment + EXIF I/O, profiles, stitching
crates/gipfel-cli command-line tools (export, info, stitch, profiles)
crates/gipfel-app Cosmic DE (libcosmic) GUI, binary name `gipfel`
codegen/ maxima scripts + regen.sh for the projection code
tests/ golden files + C++ reference harnesses (historical)
The original README is kept for now; it will be updated to describe the
Rust build. gipfel.dat, AUTHORS, ChangeLog and NEWS are unchanged.
Diffstat (limited to 'tests/harness/fitdump.cxx')
| -rw-r--r-- | tests/harness/fitdump.cxx | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/tests/harness/fitdump.cxx b/tests/harness/fitdump.cxx new file mode 100644 index 0000000..8ef392c --- /dev/null +++ b/tests/harness/fitdump.cxx @@ -0,0 +1,83 @@ +// Golden dump: full fit through the original C++ Panorama + GSL solver. +// Usage: fitdump <gipfel.dat> <projection 0|1> +#include <stdio.h> +#include <math.h> +#include <stdlib.h> + +#include "Panorama.H" +#include "Hill.H" +#include "ProjectionRectilinear.H" +#include "ProjectionCylindrical.H" + +int main(int argc, char **argv) { + if (argc < 3) { + fprintf(stderr, "usage: fitdump <gipfel.dat> <projection>\n"); + return 1; + } + + Panorama pan; + if (pan.load_data(argv[1])) { + fprintf(stderr, "load failed\n"); + return 1; + } + pan.set_projection((ProjectionLSQ::Projection_t) atoi(argv[2])); + + pan.set_view_lat(47.36); + pan.set_view_long(11.15); + pan.set_view_height(2100.0); + + // ground truth + pan.set_center_angle(20.0); + pan.set_nick_angle(0.0); + pan.set_tilt_angle(1.0); + pan.set_scale(3000.0); + + // observed positions = projection of first 6 visible hills (snapshotted + // as copies so the perturbation below does not overwrite them) + Hills *vis = pan.get_visible_mountains(); + Hills known; + int n = vis->get_num() < 6 ? vis->get_num() : 6; + for (int i = 0; i < n; i++) { + Hill *c = new Hill(*vis->get(i)); + // NOTE: Hill's copy ctor in the original does not copy a_nick + // (uninitialized garbage -> LSQR stagnates). The real app always + // fits hills living in the main list where a_nick is set, so set it + // here to reproduce the real-app behavior. + c->a_nick = vis->get(i)->a_nick; + known.add(c); + } + + // perturb the initial guess + pan.set_center_angle(pan.get_center_angle() + 0.5); + pan.set_nick_angle(0.3); + pan.set_tilt_angle(0.5); + pan.set_scale(2800.0); + + int ret = pan.comp_params(&known); + + ViewParams *p = &pan.parms; + printf("ret %d\n", ret); + printf("a_center %.17g\n", p->a_center); + printf("a_nick %.17g\n", p->a_nick); + printf("a_tilt %.17g\n", p->a_tilt); + printf("scale %.17g\n", p->scale); + printf("k0 %.17g\n", p->k0); + printf("k1 %.17g\n", p->k1); + printf("x0 %.17g\n", p->x0); + + // final image coordinates of the known hills (bypass visibility check) + for (int i = 0; i < known.get_num(); i++) { + Hill *m = known.get(i); + double x = NAN, y = NAN; + if (atoi(argv[2]) == 1) { + ProjectionCylindrical pc; + pc.get_coordinates(m->alph, m->a_nick, &pan.parms, &x, &y); + } else { + ProjectionRectilinear pr; + pr.get_coordinates(m->alph, m->a_nick, &pan.parms, &x, &y); + } + printf("hill %d %.17g %.17g\n", i, x, y); + } + + return 0; +} |
