commit 8307154070a832a80d608923d5a376fae8f50a74 Author: Timofey Khoruzhii Date: Tue Jan 3 22:29:07 2023 +0300 Init project diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..d10c1ef --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.14) + +project(thro) + +set(CMAKE_CXX_STANDARD 20) + +file(GLOB_RECURSE SOURCES_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/*) + +add_executable(thor ${SOURCES_FILES}) + +target_include_directories(thor PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) +target_link_libraries(thor cpp-terminal) + +set(CPPTERMINAL_ENABLE_TESING OFF) + +include(FetchContent) +FetchContent_Declare( + cpp-terminal + GIT_REPOSITORY https://github.com/jupyter-xeus/cpp-terminal.git + GIT_TAG origin/master +) +FetchContent_MakeAvailable(cpp-terminal) + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..819039a --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,142 @@ +#include + +#include + +#include +#include + +#include +#include +#include +#include + +struct vec3 { + vec3 operator-(vec3 o) { + return vec3{x - o.x, y - o.y, z - o.z}; + } + vec3 operator+(vec3 o) { + return vec3{x + o.x, y + o.y, z + o.z}; + } + vec3 operator*(float c) { + return vec3{x * c, y * c, z * c}; + } + vec3 operator/(float c) { + return vec3{x / c, y / c, z / c}; + } + friend vec3 operator*(float c, vec3 a) { + return a * c; + } + + friend std::ostream& operator<<(std::ostream& out, vec3& v) { + out << "{" << v.x << ", " << v.y << ", " << v.z << "}"; + return out; + } + + float x, y, z; +}; + +float dot(vec3 a, vec3 b) { + return a.x * b.x + a.y * b.y + a.z * b.z; +} + +float len2(vec3 a) { + return a.x * a.x + a.y * a.y + a.z * a.z; +} + +float len(vec3 a) { + return std::sqrt(len2(a)); +} + +// o - point in pane, p - perp, v - point +// dot(p, p) = 1 +vec3 prj_pane(vec3 o, vec3 p, vec3 v) { + return v - dot(p, v - o) * p; +} + +vec3 prj_shpere(vec3 o, float r, vec3 v, vec3 def) { + auto t = v - o; + if (len(t) == 0) { + return def; + } + t = (t / len(t)) * r; + return t + o; +} + +struct thor { + vec3 o; + vec3 p; + float r1, r2; +}; + +float dist_to_thor(thor t, vec3 v) { + auto u = prj_pane(t.o, t.p, v); + float q = t.r1 - len(u - t.o); + + return sqrt(len2(v - u) + q * q) - t.r2; +} + +struct Sphere { + vec3 o; + float r; +}; + +float dist_to_shere(Sphere s, vec3 v) { + return len(v - s.o) - s.r; +} + +const float eps = 1e-5; + +vec3 norm(vec3 v) { + return v / len(v); +} + +int main() { + thor t{vec3{20, 0, 0}, vec3{0, 1, 0}, 4, 1}; + Sphere s{vec3{20, 0, 0}, .5}; + + auto& win = gui::Window::Get(); + auto [w, h] = win.GetSize(); + + for (long long it = 0; it < 1000000000000000; ++it) { + float alp = it / 10.; + t.p.x = cos(alp); + t.p.y = sin(alp); + s.r = sin(alp * sqrt(2)); + + win.Clear(); + + for (int i = 0; i < h; ++i) { + for (int j = 0; j < w; ++j) { + int y = (i - h / 2) * 5; + int x = (j - w / 2) * 10; + float fx = float(x) / (w); + float fy = float(y) / (h); + + vec3 to{4, fx, fy}; + for (int i = 0; i < 20; ++i) { + float d = std::min(dist_to_thor(t, to), dist_to_shere(s, to)); + if (d < eps) { + break; + } + to = to + (to / len(to)) * d; + if (len(to) >= 30) { + break; + } + } + + if (len(to) < 30) { + win(j, i) = 'X'; + } + } + } + + win.Draw(); + } + + { + char t; + std::cin >> t; + } + + return 0; +} diff --git a/src/window/window.cpp b/src/window/window.cpp new file mode 100644 index 0000000..b026168 --- /dev/null +++ b/src/window/window.cpp @@ -0,0 +1,63 @@ +#include + +#include +#include +#include "cpp-terminal/input.hpp" + +namespace gui { +Window::Window() { + ReloadSize(); +} + +void Window::ReloadSize() { + std::tie(height_, width_) = Term::get_size(); + + current_grid_.resize(width_); + buffer_grid_.resize(width_); + + for (std::size_t i = 0; i < width_; ++i) { + current_grid_[i].resize(height_); + buffer_grid_[i].resize(height_); + } +} + +void Window::Clear() { + std::cout << Term::cursor_move(0, 0); + for (std::size_t row = 0; row < height_; ++row) { + for (std::size_t col = 0; col < width_; ++col) { + auto& buf = buffer_grid_[col][row]; + buf = ' '; + // std::cout << " "; + } + } + // std::cout << std::flush; +} + +void Window::Draw() { + for (std::size_t row = 0; row < height_; ++row) { + for (std::size_t col = 0; col < width_; ++col) { + auto& buf = buffer_grid_[col][row]; + auto& cur = current_grid_[col][row]; + if (buf != cur) { + if (buf.not_empty_background_color) { + std::cout << Term::color_bg(buf.background_color); + } + if (buf.not_empty_font_color) { + std::cout << Term::color_fg(buf.font_color); + } + + std::cout << Term::cursor_move(1 + row, 1 + col) << buf.x; + cur = buf; + + if (buf.not_empty_background_color) { + std::cout << Term::color_bg(Term::Color4::DEFAULT); + } + if (buf.not_empty_font_color) { + std::cout << Term::color_fg(Term::Color4::DEFAULT); + } + } + } + } + std::cout << std::flush; +} +} // namespace gui diff --git a/src/window/window.hpp b/src/window/window.hpp new file mode 100644 index 0000000..c264f9a --- /dev/null +++ b/src/window/window.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include +#include + +#include + +namespace gui { + +/* +using Character = char; +*/ + +struct Color { + bool operator==(const Color&) const = default; + bool operator!=(const Color&) const = default; + + operator Term::RGB() { + return Term::RGB{r, g, b}; + } + + uint8_t r, g, b; +}; + +struct Character { + Character() {} + Character(char x) : x(x) {} + + bool operator==(const Character&) const = default; + bool operator!=(const Character&) const = default; + + char x = ' '; + + // bool bold : 1 = false; + // bool italic : 1 = false; + // bool underscore : 1 = false; + // bool crossed : 1 = false; + bool not_empty_font_color : 1 = false; + bool not_empty_background_color : 1 = false; + + Color font_color{}; + Color background_color{}; +}; + +class Window { + public: + static Window& Get() { + static Window w; + + return w; + } + + void ReloadSize(); + void Clear(); + void Draw(); + + std::pair GetSize() { + return {width_, height_}; + } + + Character& operator()(std::size_t col, std::size_t row) { + return buffer_grid_[col][row]; + } + + private: + Window(); + + std::vector> current_grid_; + std::vector> buffer_grid_; + + std::size_t width_; + std::size_t height_; +}; +} // namespace gui