git.haldean.org dotmatrix / 3ecde2c
animations Haldean Brown 2 years ago
1 changed file(s) with 143 addition(s) and 39 deletion(s). Raw diff Collapse all Expand all
0 #include <cstdint>
01 #include <iostream>
2 #include <random>
13 #include <vector>
4
25 #include <Eigen/Dense>
3 #include <cstdint>
46 #include <png++/png.hpp>
7
58 #include "perspective.hpp"
69
7 #define W 1200
10 using namespace Eigen;
11
12 #define W 1000
813 #define H 400
914
10 static Eigen::Matrix<uint16_t, Eigen::Dynamic, Eigen::Dynamic> img;
15 static Matrix<uint16_t, Dynamic, Dynamic> img;
1116 typedef png::basic_rgb_pixel<uint8_t> pixel;
1217
13 //int c[] { 255, 150, 100, 70, 50, 20, 0 };
1418 uint8_t c[7][3] {
1519 { 0, 0, 40 },
1620 { 140, 0, 0 },
2125 { 255, 255, 240 },
2226 };
2327
28 Vector2f random_uv()
29 {
30 static std::random_device rd;
31 static std::default_random_engine rande(rd());
32 static std::uniform_real_distribution<float> dist_u(0, 2 * M_PI);
33 static std::normal_distribution<float> dist_v(M_PI / 2, M_PI / 6);
34
35 float u = dist_u(rande);
36 float v = dist_v(rande);
37 return Vector2f(u, v);
38 }
39
40 void point(Vector2i p)
41 {
42 int x = p[0];
43 int y = p[1];
44 if (x >= 0 && x < img.rows() && y >= 0 && y < img.cols())
45 img(x, y)++;
46 }
47
48 void line(Vector2i start, Vector2i end)
49 {
50 if (start[0] > end[0])
51 std::swap(start, end);
52 Vector2i delta = end - start;
53 bool flip = false;
54 if (fabs(delta[1]) > fabs(delta[0]))
55 {
56 int t;
57 t = start[0]; start[0] = start[1]; start[1] = t;
58 t = end[0]; end[0] = end[1]; end[1] = t;
59 t = delta[0]; delta[0] = delta[1]; delta[1] = t;
60 flip = true;
61 }
62
63 double derr = fabs((double) delta[1] / (double) delta[0]);
64 double err = derr - 0.5;
65 int y = start[1];
66 if (delta[0] == 0)
67 {
68 for (int y = start[0]; y <= start[1]; delta[1] > 0 ? y++ : y--)
69 point(Vector2i(start[0], y));
70 return;
71 }
72 for (int x = start[0]; x <= end[0]; x++)
73 {
74 if (flip)
75 point(Vector2i(y, x));
76 else
77 point(Vector2i(x, y));
78 err += derr;
79 while (err >= 0.5)
80 {
81 if (delta[1] > 0) y++;
82 else y--;
83 err -= 1.;
84 }
85 }
86 }
87
88 Vector2i uv2ss(Vector2f uv, float t)
89 {
90 static Matrix4f view = lookAt<float>(
91 Vector3f(0, 10, 0),
92 //Vector3f(0.75, 0.65, 0),
93 Vector3f(0, 0, 0),
94 Vector3f(0, 0, 1));
95 static Matrix4f proj =
96 perspective<float>(M_PI / 7, 1., 0.1, 100);
97 static Matrix4f mvp = proj * view;
98
99 Vector4f h;
100 h.block(0, 0, 3, 1) =
101 AngleAxisf(4 * M_PI * t, Vector3f::UnitX()) *
102 AngleAxisf(uv[0] + 2 * M_PI * t, Vector3f::UnitZ()) *
103 AngleAxisf(uv[1], Vector3f::UnitY()) *
104 Vector3f::UnitZ();
105 h[3] = 1;
106 Vector4f p = mvp * h;
107 int x = int(roundf(p[0] * 100)) + W / 2;
108 int y = int(roundf(p[1] * 100)) + H / 2;
109 return Vector2i(x, y);
110 }
111
24112 int main() {
25113 img.resize(W, H);
26 img.setZero();
27114
28 Eigen::Vector3f r3;
29 Eigen::Vector4f p;
115 Vector3f r3;
116 Vector4f p;
30117 size_t i, j;
118 float u, v;
119 Vector2i s, e;
31120
32 Eigen::Matrix4f view = lookAt<float>(
33 Eigen::Vector3f(2, 6, 3),
34 Eigen::Vector3f(0.75, 0.65, 0),
35 Eigen::Vector3f(0, 0, 1));
36 Eigen::Matrix4f proj = perspective<float>(M_PI / 32, 1, 0.1, 100);
37 Eigen::Matrix4f mvp = proj * view;
121 std::vector<std::pair<Vector2f, Vector2f>> edges;
122 for (int i = 0; i < 1000; i++)
123 {
124 Vector2f uv1 = random_uv();
125 Vector2f uv2 = random_uv();
126 edges.push_back(std::make_pair(uv1, uv2));
127 }
38128
39 const float step = 0.0002;
40 for (float u = 0; u < 2 * M_PI; u += step)
129 const int framecount = 200;
130 for (int f = 0; f < framecount; f++)
41131 {
42 for (float v = 0; v < M_PI; v += step)
132 float t = (float) f / framecount;
133 img.setZero();
134 if (true)
43135 {
44 Eigen::Vector4f h;
45 h.block(0, 0, 3, 1) =
46 Eigen::AngleAxisf(u, Eigen::Vector3f::UnitZ()) *
47 Eigen::AngleAxisf(v, Eigen::Vector3f::UnitY()) *
48 Eigen::Vector3f::UnitZ();
49 h[3] = 1;
50 p = mvp * 2 * h;
51 i = size_t(p[0] * 100) + W / 2;
52 j = size_t(p[1] * 100) + H / 2;
53 if (i >= 0 && i < img.rows() && j >= 0 && j < img.cols())
54 img(i, j) += 1;
136 for (const auto &pp : edges)
137 {
138 s = uv2ss(pp.first, t);
139 e = uv2ss(pp.second, t);
140 line(s, e);
141 }
55142 }
143 if (false)
144 {
145 const float step = 0.01;
146 for (float u = 0; u < 2 * M_PI; u += step)
147 {
148 for (float v = 0; v < M_PI; v += step)
149 {
150 e = uv2ss(Vector2f(u, v), t);
151 point(e);
152 }
153 }
154 }
155
156 png::image<pixel> out(W, H);
157 for (i = 0; i < W; i++)
158 {
159 for (j = 0; j < H; j++)
160 {
161 uint16_t step = img(i, j);
162 if (step > 6)
163 step = 6;
164 auto px = pixel(
165 c[step][0], c[step][1], c[step][2]);
166 out.set_pixel(i, j, px);
167 }
168 }
169 char buf[32];
170 sprintf(buf, "output-%06d.png", f);
171 out.write(buf);
56172 }
57 png::image<pixel> out(W, H);
58 for (i = 0; i < W; i++)
59 {
60 for (j = 0; j < H; j++)
61 {
62 uint16_t step = img(i, j);
63 if (step > 6)
64 step = 6;
65 out.set_pixel(i, j, pixel(c[step][0], c[step][1], c[step][2]));
66 }
67 }
68 out.write("output.png");
69173 return 0;
70174 }