Browse Source

day 9 animation

master
mid-kid 2 years ago
parent
commit
a57a3eba0a
  1. 68
      d09.cc
  2. BIN
      d09_anim.webm
  3. 13
      makeanim.sh

68
d09.cc

@ -2,6 +2,11 @@
#include <vector>
#include <unordered_set>
//#define ANIMATE
#ifdef ANIMATE
#include <fstream>
#endif
using namespace std;
enum Dir {
@ -71,6 +76,50 @@ Input parse()
return data;
}
#ifdef ANIMATE
bool animate;
int min_x, max_x, min_y, max_y;
unsigned frame;
void output_img(const vector<Pos2d> &knot, const unordered_set<Pos2d> &visited)
{
enum Grid {
NONE,
VISITED,
TAIL,
HEAD
};
unsigned width = max_x - min_x;
unsigned height = max_y - min_y;
auto map = vector<enum Grid>(width * height);
for (auto i : visited) map[(i.y - min_y) * width + (i.x - min_x)] = VISITED;
for (auto i : knot) map[(i.y - min_y) * width + (i.x - min_x)] = TAIL;
map[(knot.front().y - min_y) * width + (knot.front().x - min_x)] = HEAD;
char fname[] = "img/00000.pam";
sprintf(fname, "img/%05d.pam", frame++);
auto file = ofstream(fname);
file << "P7\n";
file << "WIDTH " << width << "\n";
file << "HEIGHT " << height << "\n";
file << "DEPTH 3\n";
file << "MAXVAL 255\n";
file << "TUPLTYPE RGB\n";
file << "ENDHDR\n";
for (auto i : map) {
uint32_t color = 0;
switch (i) {
case NONE: color = 0x000000; break;
case VISITED: color = 0xFF0000; break;
case TAIL: color = 0x00FF00; break;
case HEAD: color = 0x0000FF; break;
}
file.write((char *)&color, 3);
}
file.close();
}
#endif
unsigned p1(const Input &input, unsigned count = 2)
{
auto knot = vector<Pos2d>(count);
@ -90,6 +139,18 @@ unsigned p1(const Input &input, unsigned count = 2)
break;
}
visited.insert(knot.back());
#ifdef ANIMATE
if (!animate) {
for (auto cur : knot) {
if (cur.x < min_x) min_x = cur.x;
if (cur.x > max_x) max_x = cur.x;
if (cur.y < min_y) min_y = cur.y;
if (cur.y > max_y) max_y = cur.y;
}
} else {
output_img(knot, visited);
}
#endif
}
}
return visited.size();
@ -103,6 +164,13 @@ unsigned p2(const Input &input)
int main()
{
auto input = parse();
#ifdef ANIMATE
animate = false;
p1(input, 10);
animate = true;
p1(input, 10);
return 0;
#endif
cout << p1(input) << endl;
cout << p2(input) << endl;
}

BIN
d09_anim.webm

Binary file not shown.

13
makeanim.sh

@ -0,0 +1,13 @@
#!/bin/sh
rm img/*.gif
waitjobs() {
while [ "$(jobs -p | wc -l)" -ge "$1" ]; do wait; done
}
for x in img/*.pam; do
echo "$x"
pamtogif -quiet "$x" > "$x.gif" &
waitjobs "$(nproc)"
done
wait
gifsicle -d1 --verbose img/*.gif > anim.gif
ffmpeg -i anim.gif -filter:v "setpts=0.1*PTS,scale=iw*4:ih*4:flags=neighbor" -r 100 anim.webm
Loading…
Cancel
Save