feat: add support for centering the screen around best/midpoint

Pressing 'c' will center the screen around the average position of the
particles. Pressing 'f' will center the screen on each frame.

Pressing 'b' will center the screen around the best found point.
This commit is contained in:
dvdrw 2024-11-26 00:08:47 +01:00
parent 4dae604485
commit 585fdc3a7e
Signed by: dvdrw
GPG Key ID: 3ED4E5A371C20DD7
3 changed files with 39 additions and 8 deletions

View File

@ -40,14 +40,15 @@ struct Screen {
Symbol &at(int x, int y);
Symbol &at(float x, float y);
void resize(std::size_t n);
void resize(std::size_t x, std::size_t y);
void move_to(float x, float y);
std::pair<float, float> screen_to_xy(int w, int h);
std::pair<int, int> xy_to_screen(float x, float y);
Screen(std::size_t n) : buf(nullptr) { resize(n); }
Screen(std::size_t x, std::size_t y) : buf(nullptr) { resize(x, y); }
Screen(std::size_t x, std::size_t y) : buf(nullptr)
{ resize(x, y); move_to(0, 0); }
~Screen() { delete[] buf; }
std::vector<const vec<2>*> points;

View File

@ -8,6 +8,7 @@ static constexpr int kFPS = 60;
static constexpr float kDT = 1.0 / kFPS;
float f(vec<2> x) {
// return std::pow(x.x, 2) + std::pow(x.y, 2);
return 50 * (std::pow(std::sin((x.x - 10)/2),2) + std::pow(std::sin(x.y/2),2)) +
std::pow(std::abs(x.x - 3.141592653589), 1.2) + std::pow(std::abs(x.y), 1.2);
}
@ -65,6 +66,7 @@ main(int argc, char **argv) {
bool pause = false;
bool frame_step = false;
bool auto_follow = false;
// initialize colorizer scale/translate
scr.draw();
@ -79,6 +81,15 @@ main(int argc, char **argv) {
255, 255, 255, x.x, x.y, y);
};
auto center_screen = [&]() -> void {
vec<2> pos = 0;
for(const auto &p : swarm.get_particles()) {
pos += p.get_position();
}
pos /= swarm.get_particles().size();
scr.move_to(pos.x, pos.y);
};
// We draw to the screen at a rate of `kFPS', but step()ing the swarm at
// this rate would be far too fast to be interesting to look at. On the
// other hand, step()ing once a second is too slow.
@ -102,6 +113,8 @@ main(int argc, char **argv) {
printf("Current iteration: %d\nCurrent frame: %d\n", i * 4 / kFPS, i);
}
if(auto_follow) center_screen();
if(frame_step) {
pause = true;
frame_step = false;
@ -178,6 +191,24 @@ main(int argc, char **argv) {
update_and_draw();
break;
case 'v':
scr.draw_vecs = !scr.draw_vecs;
break;
case 'b': {
const auto [_, b] = swarm.best();
scr.move_to(b.x, b.y);
break;
}
case 'c':
center_screen();
break;
case 'f':
auto_follow = !auto_follow;
break;
case 'h':
printf(" movement zoom coloring pause step \n"
" W io IK LO SPC ., \n"

View File

@ -4,11 +4,6 @@
/* Screen */
void Screen::resize(std::size_t n) {
w = n; h = 1;
buf = (Symbol *)realloc(buf, n * sizeof(Symbol));
}
void Screen::resize(std::size_t x, std::size_t y) {
w = x; h = y;
buf = (Symbol *)realloc(buf, x * y * sizeof(Symbol));
@ -41,6 +36,10 @@ std::pair<int, int> Screen::xy_to_screen(float x, float y) {
};
}
void Screen::move_to(float x, float y) {
dx = x - w*sx/2;
dy = y - h*sy/2;
}
void Screen::clear() {
static const Symbol s {' ', {0,0,0}};