1
0
mirror of https://github.com/zenorogue/hyperrogue.git synced 2024-12-24 17:10:36 +00:00

rogueviz:🌻: RogueViz slide, infer one of three parameters from the other two, auto-adjust rug scale when changing density, auto-resize arrays

This commit is contained in:
Zeno Rogue 2020-04-08 01:36:08 +02:00
parent 2fbccb4a84
commit fca3a79839

View File

@ -3,34 +3,68 @@
// use: commandline parameter -sunflower <quantity> <density>
// e.g.: hyper -sunflower 10000 0.01
// for spherical geometry, density is set automatically to cover the whole sphere
// e.g.: hyper -sunflower 5 0.01
#include "rogueviz.h"
namespace hr {
namespace rogueviz {
namespace sunflower {
bool on;
int qty = 100;
ld density = 1, zdensity;
ld range;
static const int maxfib = 300000;
/* which property to infer from the other two: 'd'ensity, 'q'ty or 'r'ange */
char infer;
hyperpoint ps[maxfib];
vector<hyperpoint> ps;
hyperpoint p(int i) {
ld step = M_PI * (3 - sqrt(5));
return spin(i * step) * xpush(sphere ? (i+.5) * M_PI / qty : euclid ? sqrt((i+.5) * density) : acosh(1 + (i+.5) * density)) * C0;
return spin(i * step) * xpush(sphere ? (i+.5) * density : euclid ? sqrt((i+.5) * density) : acosh(1 + (i+.5) * density)) * C0;
}
int inext[maxfib], inext2[maxfib];
vector<int> inext, inext2;
const vector<int> fibs =
{1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811};
vector<int> fibs = {1, 2};
bool sunflower_cell(cell *c, transmatrix V) {
if(!on) return false;
density = zdensity / 100;
ld qd;
if(sphere) {
if(infer == 'r')
range = qty * density;
else qd = range;
}
else if(euclid) {
if(infer == 'r')
range = sqrt(qty * density);
else qd = range * range;
}
else {
if(infer == 'r')
range = acosh(1 + qty * density);
else
qd = (cosh(range) - 1);
}
if(infer == 'q') qty = qd / density;
if(infer == 'd') density = qd / qty;
ps.resize(qty);
inext.resize(qty);
inext2.resize(qty);
while(fibs.back() < qty) {
auto add = fibs.back() + *(fibs.end()-2);
fibs.push_back(add);
}
if(c == cwt.at) {
for(int i=0; i<qty; i++) ps[i] = V * p(i);
@ -73,23 +107,102 @@ int readArgs() {
if(0) ;
else if(argis("-sunflower")) {
shift(); qty = argi();
on = true;
infer = 'r';
shift(); qty = argi();
shift(); zdensity = argf() * 100;
patterns::whichShape = '9';
nohud = true;
addHook(hooks_drawcell, 100, sunflower_cell);
addHook(dialog::hooks_display_dialog, 100, [] () {
if(current_screen_cfunction() == showMainMenu) {
dialog::addItem("sunflower", 1001);
dialog::add_action([] () { dialog::editNumber(zdensity, 0, 1, .1, 1, "density", "density"); });
}
});
}
else if(argis("-sunflower-qr")) {
on = true;
infer = 'd';
shift(); qty = argi();
shift(); range = argf();
patterns::whichShape = '9';
nohud = true;
}
else if(argis("-sunflower-dr")) {
on = true;
infer = 'q';
shift(); density = argi();
shift(); range = argf();
patterns::whichShape = '9';
nohud = true;
}
else return 1;
return 0;
}
auto hook = addHook(hooks_args, 100, readArgs);
ld distance_per_rug;
bool adjust_rug;
named_functionality o_key() {
if(on) return named_functionality("sunflower density", [] {
dialog::editNumber(zdensity, 0, 1, .1, 1, "density", "density");
dialog::reaction = [] {
if(adjust_rug)
rug::model_distance = sqrt(zdensity) * distance_per_rug;
else
distance_per_rug = rug::model_distance / sqrt(zdensity);
};
distance_per_rug = rug::model_distance / sqrt(zdensity);
dialog::extra_options = [] {
dialog::addBoolItem_action("auto-adjust the Rug", adjust_rug, 'A');
};
});
return named_functionality();
}
auto hook = 0
#if CAP_COMMANDLINE
+ addHook(hooks_args, 100, readArgs)
#endif
+ addHook(hooks_o_key, 80, o_key)
+ addHook(hooks_drawcell, 100, sunflower_cell)
+ addHook(rvtour::hooks_build_rvtour, 144, [] (vector<tour::slide>& v) {
using namespace tour;
v.push_back(
tour::slide{"unsorted/sunflower spirals", 18, LEGAL::ANY | QUICKGEO,
"A sunflower sends out its n-th seed at angle 180° (3-sqrt(5)). "
"As new seeds are created, older seeds are pushed out. Therefore. "
"the distance d(n) of the n-th seed from the center will be such that "
"the area of a circle of radius d(n) changes linearly with n.\n\n"
"In the Euclidean plane, this process creates an interesting "
"phenomenon: if we try to compute the number of spirals at a given "
"distance from the center, we usually obtain a Fibonacci number. "
"The further from the start we are, the larger Fibonacci number we "
"get.\n\n"
"Because of the exponential growth in the hyperbolic plane, we "
"get to larger Fibonacci numbers faster.\n\n"
"Press 123 to change the geometry, 5 to see this in the Hypersian Rug model. "
"Press o to change the density.",
[] (presmode mode) {
setCanvas(mode, '0');
if((mode == pmStop || mode == pmGeometry) && rug::rugged) rug::close();
if(mode == pmKey) {
if(rug::rugged) rug::close();
else rug::init();
}
if(mode == pmStart) {
stop_game();
tour::slide_backup(on, true);
tour::slide_backup(range, sphere ? 2 * M_PI : euclid ? 10 : 6);
tour::slide_backup<ld>(zdensity, 1);
tour::slide_backup(infer, 'q');
start_game();
}
}}
);
});
}