mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2024-12-24 01:00:25 +00:00
added some devmods
This commit is contained in:
parent
dfbdc57b44
commit
3caec11dfa
4
devmods/README.md
Normal file
4
devmods/README.md
Normal file
@ -0,0 +1,4 @@
|
||||
This subdirectory contains various extra modules which are useful in development,
|
||||
but are not a part of standard HyperRogue build nor RogueViz.
|
||||
|
||||
They can be added to a HyperRogue build e.g. with `mymake devmods/edit-shaders`.
|
72
devmods/edit-shaders.cpp
Normal file
72
devmods/edit-shaders.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
// This addon is useful when debugging or tuning shaders.
|
||||
// Press F2, edit the shader files, then press F3 to see them in action.
|
||||
|
||||
// F2: write the currently used shaders to files
|
||||
// F3: replace the currently used shaders with the content of the files
|
||||
|
||||
// Might need some editing.
|
||||
|
||||
#include "../hyper.h"
|
||||
|
||||
namespace hr {
|
||||
|
||||
string load_whole(const char *fname) {
|
||||
char buf[1000000];
|
||||
FILE *f = fopen(fname, "rb");
|
||||
int n = fread(buf, 1, 1000000, f);
|
||||
buf[n] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
void print_shader(const char *fname, string s) {
|
||||
FILE *f = fopen(fname, "wb");
|
||||
int indent = 0;
|
||||
bool linestart = true;
|
||||
for(char c: s) {
|
||||
if(c == ' ' && linestart) continue;
|
||||
if(c == '\n' && linestart) continue;
|
||||
linestart = false;
|
||||
fputc(c, f);
|
||||
if(c == '{') indent += 2;
|
||||
if(c == '}') indent -= 2;
|
||||
if(c == ';' || c == '}' || c == '{') {
|
||||
fputc('\n', f);
|
||||
for(int i=0; i<indent; i++) fputc(' ', f);
|
||||
linestart = true;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
bool trailer_handleKey(int sym, int uni) {
|
||||
|
||||
if(sym == SDLK_F2) {
|
||||
glhr::be_textured();
|
||||
current_display->set_all(0);
|
||||
auto p = glhr::get_shaders();
|
||||
print_shader("addons/current.vsh", p.first);
|
||||
print_shader("addons/current.fsh", p.second);
|
||||
addMessage("shaders saved");
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sym == SDLK_F3) {
|
||||
glhr::be_textured();
|
||||
current_display->set_all(0);
|
||||
string vsh = load_whole("addons/current.vsh");
|
||||
string fsh = load_whole("addons/current.fsh");
|
||||
println(hlog, "loaded vsh:\n", vsh);
|
||||
glhr::install_shaders(vsh, fsh);
|
||||
glhr::be_textured();
|
||||
current_display->set_all(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto hook =
|
||||
addHook(hooks_handleKey, 100, trailer_handleKey)
|
||||
+ 0;
|
||||
|
||||
}
|
241
devmods/manual-animation.cpp
Normal file
241
devmods/manual-animation.cpp
Normal file
@ -0,0 +1,241 @@
|
||||
#include "../hyper.h"
|
||||
|
||||
// A tool to create smooth manually controlled movement animations in 3D geometries.
|
||||
|
||||
// Press 'f' to start controlling
|
||||
|
||||
// 'qweasdzxc' will move the camera and additionally rotate the view a bit (except 's')
|
||||
|
||||
// 'b' goes back 1 frame, 'e' undoes 30 frames
|
||||
|
||||
// 'r' starts recording
|
||||
|
||||
// 1234 change movement speed (see console for details)
|
||||
// 67890 change rotation speed (see console for details)
|
||||
|
||||
namespace hr {
|
||||
|
||||
bool saving_positions;
|
||||
|
||||
int next_pos_tick;
|
||||
|
||||
vector<tuple<transmatrix, transmatrix, int, heptspin> > saved;
|
||||
|
||||
bool trailer_turn(int delta) {
|
||||
if(saving_positions)
|
||||
View = cpush(2, -delta/8000.) * cspin(0, 2, (mousex - current_display->xcenter) * delta / -1000000.) * cspin(1, 2, (mousey - current_display->ycenter) * delta / -1000000.) * View;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool recording;
|
||||
|
||||
void trailer_frame() {
|
||||
// if(saving_positions || !isize(saved))
|
||||
if(!recording) queuechr(current_display->xcenter, current_display->ycenter, 0, 16, '+', 0xFFFFFFFF);
|
||||
|
||||
if(saving_positions && ticks > next_pos_tick) {
|
||||
next_pos_tick += 66;
|
||||
saved.emplace_back(View, nisot::local_perspective, hybrid::current_view_level, viewctr);
|
||||
println(hlog, "frames = ", isize(saved));
|
||||
}
|
||||
}
|
||||
|
||||
bool keys_on = false;
|
||||
|
||||
ld stepdist = 0.02;
|
||||
|
||||
ld stepang = 0.01;
|
||||
|
||||
bool move_camera(transmatrix T) {
|
||||
for(int it=0; it<5; it++) {
|
||||
saved.emplace_back(View, nisot::local_perspective, hybrid::current_view_level, viewctr);
|
||||
println(hlog, "frames = ", isize(saved));
|
||||
shift_view(ztangent(-stepdist));
|
||||
rotate_view(T);
|
||||
}
|
||||
playermoved = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace solv { pair<heptagon*,heptagon*> getcoord(heptagon *h); }
|
||||
|
||||
bignum bdiff(heptagon *h1, heptagon *h2) {
|
||||
if(h1 == h2) return 0;
|
||||
auto p = bdiff(h1->move(3), h2->move(3));
|
||||
int d = h1->c.spin(3) - h2->c.spin(3);
|
||||
println(hlog, "d=", d, " p = ", p.get_str(10000));
|
||||
return p + p + bignum(d);
|
||||
}
|
||||
|
||||
#define BASE 10
|
||||
|
||||
/*
|
||||
void o_addmul(bignum& b0, const bignum& b, int factor) {
|
||||
int K = isize(b.digits);
|
||||
if(K > isize(b0.digits)) b0.digits.resize(K);
|
||||
int carry = 0;
|
||||
for(int i=0; ; i++) {
|
||||
bool cnt = (i<K || (carry > 0 && carry < -1) || (carry == -1 && i < isize(b0.digits)));
|
||||
println(hlog, "cnt = ", cnt, " carry = ", carry
|
||||
if(!cnt) break;
|
||||
println(hlog, "i=", i, " carry start=", carry);
|
||||
if(i >= isize(b0.digits)) b0.digits.push_back(0);
|
||||
long long l = b0.digits[i];
|
||||
l += carry;
|
||||
if(i < K) l += b.digits[i] * factor;
|
||||
carry = 0;
|
||||
if(l >= BASE) carry = l / BASE;
|
||||
if(l < 0) carry = -(BASE-1-l) / BASE;
|
||||
l -= carry * BASE;
|
||||
b0.digits[i] = l;
|
||||
println(hlog, "carry=", carry);
|
||||
}
|
||||
println(hlog, "carry end=", carry);
|
||||
if(carry < 0) b0.digits.back() -= BASE;
|
||||
while(isize(b0.digits) && b0.digits.back() == 0) b0.digits.pop_back();
|
||||
} */
|
||||
|
||||
void get_b4_distance() {
|
||||
heptagon *h1 = currentmap->gamestart()->master;
|
||||
heptagon *h2 = viewctr.at;
|
||||
if(h1->distance != h2->distance)
|
||||
println(hlog, "Z difference: ", h2->distance - h1->distance);
|
||||
else {
|
||||
auto c1 = solv::getcoord(h1);
|
||||
auto c2 = solv::getcoord(h2);
|
||||
println(hlog, "X difference: ", bdiff(c1.first, c2.first).get_str(10000));
|
||||
println(hlog, "Y difference: ", bdiff(c1.second, c2.second).get_str(10000));
|
||||
println(hlog, "X difference> ", bdiff(c2.first, c1.first).get_str(10000));
|
||||
println(hlog, "Y difference> ", bdiff(c2.second, c1.second).get_str(10000));
|
||||
}
|
||||
}
|
||||
|
||||
bool trailer_handleKey(int sym, int uni) {
|
||||
|
||||
if(sym == 'f') {
|
||||
keys_on = !keys_on;
|
||||
println(hlog, "keys_on = ", keys_on);
|
||||
return true;
|
||||
}
|
||||
|
||||
// println(hlog, "cells_drawn = ", cells_drawn, " cells_generated = ", cells_generated);
|
||||
|
||||
if(keys_on) {
|
||||
|
||||
if(sym == 't') {
|
||||
if(!saved.empty()) {
|
||||
println(hlog, "frames = ", isize(saved));
|
||||
saved.pop_back();
|
||||
}
|
||||
if(!saved.empty()) {
|
||||
tie(View, nisot::local_perspective, hybrid::current_view_level, viewctr) = saved.back();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* if(sym == 'e') {
|
||||
dialog::editNumber(stepdist, 0, 1, 0.1, 0.1, "", "");
|
||||
dialog::scaleLog();
|
||||
} */
|
||||
|
||||
if(sym == 's') return move_camera(Id);
|
||||
|
||||
if(sym == 'a') return move_camera(cspin(0, 2, stepang));
|
||||
|
||||
if(sym == 'd') return move_camera(cspin(0, 2, -stepang));
|
||||
|
||||
if(sym == 'q') return move_camera(cspin(0, 2, stepang) * cspin(1, 2, stepang));
|
||||
if(sym == 'w') return move_camera(cspin(1, 2, stepang));
|
||||
if(sym == 'e') return move_camera(cspin(0, 2, -stepang) * cspin(1, 2, stepang));
|
||||
|
||||
if(sym == 'z') return move_camera(cspin(0, 2, stepang) * cspin(1, 2, -stepang));
|
||||
if(sym == 'x') return move_camera(cspin(1, 2, -stepang));
|
||||
if(sym == 'c') return move_camera(cspin(0, 2, -stepang) * cspin(1, 2, -stepang));
|
||||
|
||||
|
||||
if(sym == '1') { stepdist = 0; println(hlog, stepdist); return true; }
|
||||
if(sym == '2') { stepdist = 0.01; println(hlog, stepdist); return true; }
|
||||
if(sym == '3') { stepdist = 0.02; println(hlog, stepdist); return true; }
|
||||
if(sym == '4') { stepdist = 0.05; println(hlog, stepdist); return true; }
|
||||
|
||||
if(sym == '6') { stepang = 0.001; println(hlog, stepang); return true; }
|
||||
if(sym == '7') { stepang = 0.003; println(hlog, stepang); return true; }
|
||||
if(sym == '8') { stepang = 0.01; println(hlog, stepang); return true; }
|
||||
if(sym == '9') { stepang = 0.03; println(hlog, stepang); return true; }
|
||||
if(sym == '0') { stepang = 0.1; println(hlog, stepang); return true; }
|
||||
|
||||
if(sym == 'p') { get_b4_distance(); return true; }
|
||||
|
||||
if(sym == SDLK_F4) {
|
||||
saving_positions = !saving_positions;
|
||||
next_pos_tick = ticks;
|
||||
println(hlog, "saving_positions = ", saving_positions);
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sym == 'b') {
|
||||
saved.pop_back();
|
||||
tie(View, nisot::local_perspective, hybrid::current_view_level, viewctr) = saved.back();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sym == 'u' && isize(saved) > 40) {
|
||||
for(int i=0; i<30; i++) saved.pop_back();
|
||||
tie(View, nisot::local_perspective, hybrid::current_view_level, viewctr) = saved.back();
|
||||
return true;
|
||||
}
|
||||
|
||||
if(sym == 'r') {
|
||||
recording = true;
|
||||
if(mouseaim_sensitivity) {
|
||||
mouseaim_sensitivity = 0;
|
||||
return true;
|
||||
}
|
||||
if(musicvolume) {
|
||||
musicvolume = 0;
|
||||
Mix_VolumeMusic(0);
|
||||
return true;
|
||||
}
|
||||
saving_positions = false;
|
||||
// vid.cells_drawn_limit = 1000000;
|
||||
int i = 0;
|
||||
shot::take("anim/start.png");
|
||||
shot::transparent = false;
|
||||
// shot::shotx = 1920;
|
||||
// shot::shoty = 1080;
|
||||
shot::shot_aa = 2;
|
||||
solv::solrange_xy = 30;
|
||||
solv::solrange_z = 6;
|
||||
vid.cells_drawn_limit = 100000;
|
||||
vid.cells_generated_limit = 1000;
|
||||
// sightranges[geometry] = 4;
|
||||
static int lasti = 0;
|
||||
|
||||
for(auto& p: saved) {
|
||||
// sightranges[geometry] = 4 + i * 2. / isize(saved);
|
||||
tie(View, nisot::local_perspective, hybrid::current_view_level, viewctr) = p;
|
||||
ticks = i * 1000 / 30;
|
||||
if(i < lasti) continue;
|
||||
|
||||
system("mkdir addons/possaver/");
|
||||
|
||||
shot::take(format("extra/possaver/%05d.png", i));
|
||||
println(hlog, "frame ", i);
|
||||
i++;
|
||||
}
|
||||
|
||||
lasti = i;
|
||||
recording = false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
auto hook =
|
||||
addHook(hooks_handleKey, 100, trailer_handleKey)
|
||||
+ addHook(hooks_drawmap, 100, trailer_frame)
|
||||
+ addHook(shmup::hooks_turn, 100, trailer_turn)
|
||||
+ 0;
|
||||
|
||||
}
|
336
devmods/solv-table.cpp
Normal file
336
devmods/solv-table.cpp
Normal file
@ -0,0 +1,336 @@
|
||||
// This generates the 'solv-geodesics.dat' file.
|
||||
// You may change the _PREC* values for more precise geodesics.
|
||||
|
||||
#include "../hyper.h"
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
||||
namespace hr {
|
||||
|
||||
const int _PRECX = 64;
|
||||
const int _PRECY = 64;
|
||||
const int _PRECZ = 64;
|
||||
|
||||
transmatrix parabolic1(ld u);
|
||||
|
||||
namespace solv {
|
||||
|
||||
typedef hyperpoint pt;
|
||||
typedef array<float, 3> ptlow;
|
||||
|
||||
ptlow be_low(pt x) { return ptlow({float(x[0]), float(x[1]), float(x[2])}); }
|
||||
|
||||
template<class T> void parallelize(int threads, int Nmin, int Nmax, T action) {
|
||||
std::vector<std::thread> v;
|
||||
for(int k=0; k<threads; k++)
|
||||
v.emplace_back([&,k] () {
|
||||
for(int i=Nmin+k; i < Nmax; i += threads) action(k, i);
|
||||
});
|
||||
for(std::thread& t:v) t.join();
|
||||
}
|
||||
|
||||
hyperpoint sol1(pt v) {
|
||||
auto [x,y,z,t] = (array<ld,4>&) v;
|
||||
if(x == 0 && z == 0) return C0;
|
||||
hyperpoint h = parabolic1(x) * xpush(-z) * C0;
|
||||
ld d = acosh(h[2]) / sqrt(h[0] * h[0] + h[1] * h[1]);
|
||||
return hyperpoint({h[1]*d, 0, -h[0]*d,1});
|
||||
}
|
||||
|
||||
hyperpoint sol2(pt v) {
|
||||
auto [x,y,z,t] = (array<ld,4>&) v;
|
||||
if(y == 0 && z == 0) return C0;
|
||||
hyperpoint h = parabolic1(y) * xpush(z) * C0;
|
||||
ld d = acosh(h[2]) / sqrt(h[0] * h[0] + h[1] * h[1]);
|
||||
return hyperpoint({0, h[1]*d, +h[0]*d,1});
|
||||
}
|
||||
|
||||
ld x_to_ix(ld u);
|
||||
|
||||
ld solerror(pt ok, pt chk) {
|
||||
auto zok = point3( x_to_ix(ok[0]), x_to_ix(ok[1]), tanh(ok[2]) );
|
||||
auto zchk = point3( x_to_ix(chk[0]), x_to_ix(chk[1]), tanh(chk[2]) );
|
||||
return hypot_d(3, zok - zchk);
|
||||
}
|
||||
|
||||
ld eucerror(pt ok, pt chk) {
|
||||
return pow(ok[0]-chk[0], 2) + pow(ok[1]-chk[1], 2) + pow(ok[2]-chk[2], 2);
|
||||
}
|
||||
|
||||
pt iterative_solve(pt xp, pt candidate, int prec, ld minerr, bool debug = false) {
|
||||
|
||||
transmatrix T = Id; T[0][1] = 8; T[2][2] = 5;
|
||||
|
||||
auto f = [&] (hyperpoint x) { return nisot::numerical_exp(x, prec); }; // T * x; };
|
||||
|
||||
auto ver = f(candidate);
|
||||
ld err = solerror(xp, ver);
|
||||
auto at = candidate;
|
||||
|
||||
ld eps = 1e-6;
|
||||
|
||||
pt c[3];
|
||||
for(int a=0; a<3; a++) c[a] = point3(a==0, a==1, a==2);
|
||||
|
||||
while(err > minerr) {
|
||||
if(debug) println(hlog, "\n\nf(", at, "?) = ", ver, " (error ", err, ")");
|
||||
array<hyperpoint, 3> pnear;
|
||||
for(int a=0; a<3; a++) {
|
||||
auto x = at + c[a] * eps;
|
||||
if(debug) println(hlog, "f(", x, ") = ", f(x), " = y + ", f(x)-ver );
|
||||
pnear[a] = (f(x) - ver) / eps; // (direct_exp(at + c[a] * eps, prec) - ver) / eps;
|
||||
}
|
||||
|
||||
transmatrix U = Id;
|
||||
for(int a=0; a<3; a++)
|
||||
for(int b=0; b<3; b++)
|
||||
U[a][b] = pnear[b][a];
|
||||
|
||||
hyperpoint diff = (xp - ver);
|
||||
|
||||
hyperpoint bonus = inverse(U) * diff;
|
||||
|
||||
if(hypot_d(3, bonus) > 0.1) bonus = bonus * 0.1 / hypot_d(3, bonus);
|
||||
|
||||
int fixes = 0;
|
||||
|
||||
if(debug)
|
||||
println(hlog, "\nU = ", U, "\ndiff = ", diff, "\nbonus = ", bonus, "\n");
|
||||
|
||||
nextfix:
|
||||
hyperpoint next = at + bonus;
|
||||
hyperpoint nextver = f(next);
|
||||
ld nexterr = solerror(xp, nextver);
|
||||
if(debug) println(hlog, "f(", next, ") = ", nextver, ", error = ", nexterr);
|
||||
|
||||
if(nexterr < err) {
|
||||
// println(hlog, "reduced error ", err, " to ", nexterr);
|
||||
at = next;
|
||||
ver = nextver;
|
||||
err = nexterr;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
bonus /= 2;
|
||||
fixes++;
|
||||
if(fixes > 10) {
|
||||
if(err > 999) {
|
||||
for(ld s = 1; abs(s) > 1e-9; s *= 0.5)
|
||||
for(int k=0; k<27; k++) {
|
||||
int kk = k;
|
||||
next = at;
|
||||
for(int i=0; i<3; i++) { if(kk%3 == 1) next[i] += s; if(kk%3 == 2) next[i] -= s; kk /= 3; }
|
||||
// next = at + c[k] * s;
|
||||
nextver = f(next);
|
||||
nexterr = solerror(xp, nextver);
|
||||
// println(hlog, "f(", next, ") = ", nextver, ", error = ", nexterr);
|
||||
if(nexterr < err) { at = next; ver = nextver; err = nexterr; goto nextiter; }
|
||||
}
|
||||
println(hlog, "cannot improve error ", err);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
goto nextfix;
|
||||
}
|
||||
|
||||
nextiter: ;
|
||||
}
|
||||
|
||||
return at;
|
||||
}
|
||||
|
||||
ptlow solution[_PRECZ][_PRECY][_PRECX];
|
||||
|
||||
ptlow mlow(ld x, ld y, ld z) { return ptlow({float(x), float(y), float(z)}); }
|
||||
|
||||
pt atxyz(ld x, ld y, ld z) { return hyperpoint({x, y, z, 1}); }
|
||||
|
||||
ptlow operator +(ptlow a, ptlow b) { return mlow(a[0]+b[0], a[1]+b[1], a[2]+b[2]); }
|
||||
ptlow operator -(ptlow a, ptlow b) { return mlow(a[0]-b[0], a[1]-b[1], a[2]-b[2]); }
|
||||
ptlow operator *(ptlow a, ld x) { return mlow(a[0]*x, a[1]*x, a[2]*x); }
|
||||
|
||||
ptlow can(pt x) {
|
||||
// azimuthal equidistant to Klein
|
||||
ld r = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
|
||||
if(r == 0) return mlow(0,0,0);
|
||||
ld make_r = tanh(r);
|
||||
ld d = make_r / r;
|
||||
return mlow(x[0]*d, x[1]*d, x[2]*d);
|
||||
}
|
||||
|
||||
pt uncan(ptlow x) {
|
||||
ld r = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
|
||||
if(r == 0) return atxyz(0,0,0);
|
||||
ld make_r = atanh(r);
|
||||
if(r == 1) make_r = 30;
|
||||
ld d = make_r / r;
|
||||
return atxyz(x[0]*d, x[1]*d, x[2]*d);
|
||||
}
|
||||
|
||||
pt uncan_info(ptlow x) {
|
||||
ld r = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
|
||||
println(hlog, "r = ", r);
|
||||
if(r == 0) return atxyz(0,0,0);
|
||||
ld make_r = atanh(r);
|
||||
println(hlog, "make_r = ", make_r);
|
||||
ld d = make_r / r;
|
||||
println(hlog, "d = ", d);
|
||||
return atxyz(x[0]*d, x[1]*d, x[2]*d);
|
||||
}
|
||||
|
||||
void fint(FILE *f, int x) { fwrite(&x, sizeof(x), 1, f); }
|
||||
void ffloat(FILE *f, float x) { fwrite(&x, sizeof(x), 1, f); }
|
||||
|
||||
void write_table(const char *fname) {
|
||||
FILE *f = fopen(fname, "wb");
|
||||
fint(f, _PRECX);
|
||||
fint(f, _PRECY);
|
||||
fint(f, _PRECZ);
|
||||
fwrite(solution, sizeof(solution), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void load_table(const char *fname) {
|
||||
int s;
|
||||
FILE *f = fopen(fname, "rb");
|
||||
fread(&s, 4, 1, f);
|
||||
fread(&s, 4, 1, f);
|
||||
fread(&s, 4, 1, f);
|
||||
fread(solution, sizeof(solution), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
ld ix_to_x(ld ix) {
|
||||
ld minx = 0, maxx = 1;
|
||||
for(int it=0; it<100; it++) {
|
||||
ld x = (minx + maxx) / 2;
|
||||
if(x_to_ix(atanh(x)) < ix) minx = x;
|
||||
else maxx = x;
|
||||
}
|
||||
return atanh(minx);
|
||||
}
|
||||
|
||||
ld iz_to_z(ld z) {
|
||||
return atanh(z); // atanh(z * 2 - 1);
|
||||
}
|
||||
|
||||
ld z_to_iz(ld z) {
|
||||
return tanh(z); // (tanh(z) + 1) / 2;
|
||||
}
|
||||
|
||||
int last_x = _PRECX-1, last_y = _PRECY-1, last_z = _PRECZ-1;
|
||||
|
||||
ld ptd(ptlow p) {
|
||||
return p[0]*p[0] + p[1]*p[1] + p[2] * p[2];
|
||||
}
|
||||
|
||||
ptlow zflip(ptlow x) { return mlow(x[1], x[0], -x[2]); }
|
||||
|
||||
void build_sols() {
|
||||
std::mutex file_mutex;
|
||||
ld max_err = 0;
|
||||
auto act = [&] (int tid, int iz) {
|
||||
|
||||
auto solve_at = [&] (int ix, int iy) {
|
||||
ld x = ix_to_x(ix / (_PRECX-1.));
|
||||
ld y = ix_to_x(iy / (_PRECY-1.));
|
||||
ld z = iz_to_z(iz / (_PRECZ-1.));
|
||||
|
||||
auto v = hyperpoint ({x,y,z,1});
|
||||
|
||||
vector<pt> candidates;
|
||||
pt cand;
|
||||
|
||||
candidates.push_back(atxyz(0,0,0));
|
||||
|
||||
static constexpr int prec = 100;
|
||||
|
||||
// sort(candidates.begin(), candidates.end(), [&] (pt a, pt b) { return solerror(v, direct_exp(a, prec)) > solerror(v, direct_exp(b, prec)); });
|
||||
|
||||
// cand_best = candidates.back();
|
||||
|
||||
vector<pt> solved_candidates;
|
||||
|
||||
for(auto c: candidates) {
|
||||
auto solt = iterative_solve(v, c, prec, 1e-6);
|
||||
solved_candidates.push_back(solt);
|
||||
if(solerror(v, nisot::numerical_exp(solt, prec)) < 1e-9) break;
|
||||
}
|
||||
|
||||
sort(solved_candidates.begin(), solved_candidates.end(), [&] (pt a, pt b) { return solerror(v, nisot::numerical_exp(a, prec)) > solerror(v, nisot::numerical_exp(b, prec)); });
|
||||
|
||||
cand = solved_candidates.back();
|
||||
|
||||
auto xerr = solerror(v, nisot::numerical_exp(cand, prec));
|
||||
|
||||
if(xerr > 1e-3) {
|
||||
println(hlog, format("[%2d %2d %2d] ", iz, iy, ix));
|
||||
println(hlog, "f(?) = ", v);
|
||||
println(hlog, "f(", cand, ") = ", nisot::numerical_exp(cand, prec));
|
||||
println(hlog, "error = ", xerr);
|
||||
println(hlog, "canned = ", can(cand));
|
||||
max_err = xerr;
|
||||
hyperpoint h1 = uncan(solution[iz][iy-1][ix]);
|
||||
hyperpoint h2 = uncan(solution[iz][iy][ix-1]);
|
||||
hyperpoint h3 = uncan(solution[iz][iy-1][ix-1]);
|
||||
hyperpoint h4 = h1 + h2 - h3;
|
||||
solution[iz][iy][ix] = can(h4);
|
||||
return;
|
||||
}
|
||||
|
||||
solution[iz][iy][ix] = can(cand);
|
||||
|
||||
for(int z=0; z<3; z++) if(isnan(solution[iz][iy][ix][z]) || isinf(solution[iz][iy][ix][z])) {
|
||||
println(hlog, cand, "canned to ", solution[iz][iy][ix]);
|
||||
exit(4);
|
||||
}
|
||||
};
|
||||
|
||||
for(int it=0; it<max(last_x, last_y); it++) {
|
||||
for(int a=0; a<it; a++) {
|
||||
if(it < last_x && a < last_y) solve_at(it, a);
|
||||
if(a < last_x && it < last_y) solve_at(a, it);
|
||||
}
|
||||
if(it < last_x && it < last_y) solve_at(it, it);
|
||||
std::lock_guard<std::mutex> fm(file_mutex);
|
||||
println(hlog, format("%2d: %2d", iz, it));
|
||||
}
|
||||
};
|
||||
|
||||
parallelize(last_z, 0, last_z, act);
|
||||
|
||||
for(int x=0; x<last_x; x++)
|
||||
for(int y=0; y<last_y; y++) {
|
||||
for(int z=last_z; z<_PRECZ; z++)
|
||||
solution[z][y][x] = solution[z-1][y][x] * 2 - solution[z-2][y][x];
|
||||
}
|
||||
|
||||
for(int x=0; x<last_x; x++)
|
||||
for(int y=last_y; y<_PRECY; y++)
|
||||
for(int z=0; z<_PRECZ; z++)
|
||||
solution[z][y][x] = solution[z][y-1][x] * 2 - solution[z][y-2][x];
|
||||
|
||||
for(int x=last_x; x<_PRECX; x++)
|
||||
for(int y=0; y<_PRECY; y++)
|
||||
for(int z=0; z<_PRECZ; z++)
|
||||
solution[z][y][x] = solution[z][y][x-1] * 2 - solution[z][y][x-2];
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
println(hlog);
|
||||
|
||||
geometry = gSol;
|
||||
|
||||
build_sols();
|
||||
write_table("solv-geodesics-generated.dat");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int phooks = addHook(hooks_main, 0, main);
|
||||
|
||||
}
|
||||
}
|
@ -8087,7 +8087,7 @@ S(
|
||||
"względów technicznych (geodezyjne do tych punktów są zbyt dziwne).")
|
||||
|
||||
S("max difference in X/Y coordinates", "maksymalna różnica współrzędnch X/Y")
|
||||
S("max difference in Z coordinate", "maksymalna różnica współrzędnej Z)
|
||||
S("max difference in Z coordinate", "maksymalna różnica współrzędnej Z")
|
||||
|
||||
S("geodesic movement in Sol/Nil", "ruch po geodezyjnych w Sol/Nil")
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user