My omnium-gatherom of scripts and source code.
at main 107 lines 2.0 kB view raw
1#include <array> 2#include <cmath> 3#include <expected> 4#include <fstream> 5#include "prelude.hpp" 6 7enum class Error { 8 file_error 9}; 10 11struct RGB { 12 U8 Red; 13 U8 Green; 14 U8 Blue; 15 16 RGB(U8 r, U8 g, U8 b); 17}; 18 19struct Color { 20 F32 hue; 21 F32 saturation; 22 F32 value; 23 Color(); 24 Color(U32 val); 25 Color(F32 hue, F32 saturation, F32 value); 26 27 fn to_rgb() const noexcept -> RGB; 28 fn lerp(ref<const Color>, F64) const noexcept -> Color; 29}; 30 31struct Point { 32 F64 x; 33 F64 y; 34 35 Point(F64 x, F64 y); 36}; 37 38template<Size width, Size height> 39class Canvas { 40 F64 x_max; 41 F64 y_max; 42 F64 x_min; 43 F64 y_min; 44 std::array<Color, width * height> pixels; 45 46 public: 47 Canvas(F64 min_x, F64 min_y, F64 max_x, F64 max_y) 48 : x_max(max_x) 49 , y_max(max_y) 50 , x_min(min_x) 51 , y_min(min_y) 52 { } 53 54 Canvas(Point p, Size size) 55 { 56 let delta = size / 2.0; 57 x_max = p.x + delta; 58 x_min = p.x - delta; 59 y_max = p.y + delta; 60 y_min = p.y - delta; 61 } 62 63 fn save_to_ppm(const char* file_path) const noexcept -> std::expected<Unit, Error> 64 { 65 var f = 66 std::fstream(file_path, std::ios::binary | std::ios::out); 67 if (not f.is_open()) 68 return std::unexpected(Error::file_error); 69 70 f << "P6\n" << width << " " << height << " 255\n"; 71 for (let &color : pixels) { 72 var c = color.to_rgb(); 73 let rgb = std::make_tuple(c.Red, c.Green, c.Blue); 74 f << fst(rgb) << snd(rgb) << thr(rgb) ; 75 } 76 f.close(); 77 return Unit(); 78 } 79 80 fn coordinate(Size index) const noexcept -> Point 81 { 82 return Point( 83 std::lerp(x_min, x_max, 84 (index % width) / (F64)width), 85 std::lerp(y_min, y_max, 86 ((F64)index / height) / height)); 87 } 88 89 fn construct(auto op) noexcept -> Unit 90 { 91 #pragma omp parallel for 92 for (Size idx = 0; idx < width * height; idx++) 93 pixels[idx] = op(coordinate(idx)); 94 95 return Unit(); 96 } 97 98 fn operator[](Size index) noexcept -> ref<Color> 99 { 100 return pixels[index]; 101 } 102 103 fn operator()(Size row, Size col) noexcept -> ref<Color> 104 { 105 return pixels[row * width + col]; 106 } 107};