swarmc/include/screen.hpp
dvdrw 585fdc3a7e
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.
2024-11-26 00:08:47 +01:00

96 lines
2.1 KiB
C++

#pragma once
#include "vec.hpp"
#include <cstddef>
#include <cstdlib>
#include <cstdio>
#include <functional>
#include <unistd.h>
#include <termios.h>
#include <vector>
struct Screen {
/**
* Unit pixel information struct
*/
struct Symbol {
char sym;
vec<3> color = {0,0,0};
bool visible = true;
Symbol &operator=(char c) { sym = c; return *this; };
};
/**
* Function taking screen coords and space coords and returning a Symbol for
* that position
*/
using char_shader_t = std::function<Symbol(int, int, float, float)>;
std::size_t w, h;
float dx = 0, dy = 0;
float sx = 1, sy = 1.8;
void draw();
void clear();
Symbol &at(std::size_t n);
Symbol &at(int x, int y);
Symbol &at(float x, float y);
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 x, std::size_t y) : buf(nullptr)
{ resize(x, y); move_to(0, 0); }
~Screen() { delete[] buf; }
std::vector<const vec<2>*> points;
std::vector<std::pair<const vec<2>*,const vec<2>*>> vecs;
char_shader_t shader;
bool draw_vecs = true;
private:
Symbol *buf;
Symbol _dummy;
static inline void gotoxy(int x, int y)
{
std::printf("\033[%d;%dH", y, x);
}
};
using colorizer_t = std::function<vec<3>(float)>;
struct TanhColorizer {
float scale = 1.0;
float translate = 0.0;
vec<3> operator()(float y);
private:
static vec<3> hsl_to_rgb(float h, float s, float l);
static float hue_to_rgb(float p, float q, float t);
};
static termios old, current;
static inline void enter_noncanonical_mode(void)
{
tcgetattr(STDIN_FILENO, &old);
current = old;
current.c_lflag &= ~ICANON; /* disable buffered i/o */
current.c_lflag &= ~ECHO; /* set no echo mode */
current.c_cc[VMIN] = 0;/* no wait */
current.c_cc[VTIME] = 0;/* no wait */
tcsetattr(STDIN_FILENO, TCSANOW, &current);
}
static inline void enter_canonical_mode(void){ tcsetattr(0, TCSANOW, &old); }