git.haldean.org
animations Haldean Brown 4 years ago
1 changed file(s) with 143 addition(s) and 39 deletion(s).
+143
-39
main.cpp
 0 #include 0 1 #include 2 #include 1 3 #include 4 2 5 #include 3 #include 4 6 #include 7 5 8 #include "perspective.hpp" 6 9 7 #define W 1200 10 using namespace Eigen; 11 12 #define W 1000 8 13 #define H 400 9 14 10 static Eigen::Matrix img; 15 static Matrix img; 11 16 typedef png::basic_rgb_pixel pixel; 12 17 13 //int c[] { 255, 150, 100, 70, 50, 20, 0 }; 14 18 uint8_t c[7][3] { 15 19 { 0, 0, 40 }, 16 20 { 140, 0, 0 }, 21 25 { 255, 255, 240 }, 22 26 }; 23 27 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 dist_u(0, 2 * M_PI); 33 static std::normal_distribution 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( 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(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 24 112 int main() { 25 113 img.resize(W, H); 26 img.setZero(); 27 114 28 Eigen::Vector3f r3; 29 Eigen::Vector4f p; 115 Vector3f r3; 116 Vector4f p; 30 117 size_t i, j; 118 float u, v; 119 Vector2i s, e; 31 120 32 Eigen::Matrix4f view = lookAt( 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(M_PI / 32, 1, 0.1, 100); 37 Eigen::Matrix4f mvp = proj * view; 121 std::vector> 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 } 38 128 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++) 41 131 { 42 for (float v = 0; v < M_PI; v += step) 132 float t = (float) f / framecount; 133 img.setZero(); 134 if (true) 43 135 { 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 } 55 142 } 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 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); 56 172 } 57 png::image 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"); 69 173 return 0; 70 174 }