diff --git a/src/Application.cpp b/src/Application.cpp index 6703fb4..be63b86 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -34,6 +34,36 @@ Application::Application(int width, int height, const char* title) return; } + + // Construct dummy velocity field + // TODO: Remove eventually + int fieldSize = 49; + double curl1 = -1.0; + double curl2 = 1.0; + std::vector hori(fieldSize * fieldSize); + std::vector vert(fieldSize * fieldSize); + + for (int y = 0; y < fieldSize; y++) + { + for (int x = 0; x < fieldSize; x++) + { + // map internal coords to "real world" coordinates + double realX = -2.0 + (4.0 / (double)fieldSize) * (double)x; + double realY = -2.0 + (4.0 / (double)fieldSize) * (double)y; + + // hori[y * fieldSize + x] = (realY + 1.0) / sqrt((realX + 1.0) * (realX + 1.0) + (realY + 1.0) * (realY + 1.0)) - (realY - 1.0) / sqrt((realX - 1.0) * (realX - 1.0) + (realY - 1.0) * (realY - 1.0)); + // vert[y * fieldSize + x] = -(realX + 1.0) / sqrt((realX + 1.0) * (realX + 1.0) + (realY + 1.0) * (realY + 1.0)) + (realX - 1.0) / sqrt((realX - 1.0) * (realX - 1.0) + (realY - 1.0) * (realY - 1.0)); + + // hori[y * fieldSize + x] = realY / sqrt(realX * realX + realY * realY); + // vert[y * fieldSize + x] = -realX / sqrt(realX * realX + realY * realY); + + hori[y * fieldSize + x] = -realY; + vert[y * fieldSize + x] = realX; + + } + } + + velocity = VectorField(fieldSize, fieldSize, hori, vert); } Application::~Application() @@ -85,5 +115,8 @@ void Application::Render() SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); + + velocity.Draw(renderer, {10, 10, 790, 790}); + SDL_RenderPresent(renderer); } diff --git a/src/Application.hpp b/src/Application.hpp index 51a5335..4ffbe8b 100644 --- a/src/Application.hpp +++ b/src/Application.hpp @@ -1,5 +1,7 @@ #pragma once +#include "VectorField.hpp" + // Forward Declarations struct SDL_Window; struct SDL_Renderer; @@ -23,4 +25,6 @@ private: SDL_Renderer* renderer = nullptr; bool shouldClose = false; + + VectorField velocity; }; \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e488fd0..ac395a3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required (VERSION 3.8) # Add source to this project's executable. -add_executable (EulerFluid "main.cpp" "Application.hpp" "Application.cpp") +add_executable (EulerFluid "main.cpp" "Application.hpp" "Application.cpp" "VectorField.hpp" "VectorField.cpp") target_include_directories(EulerFluid PUBLIC ${SDL2_INCLUDE_DIRS}) target_link_libraries(EulerFluid PUBLIC ${SDL2_LIBRARIES}) diff --git a/src/VectorField.cpp b/src/VectorField.cpp new file mode 100644 index 0000000..f7360d9 --- /dev/null +++ b/src/VectorField.cpp @@ -0,0 +1,64 @@ +#include "VectorField.hpp" + +#include + +VectorField::VectorField() : + width(0), height(0), biggestMagnitude(1.0) +{ +} + +VectorField::VectorField(int width, int height) : + width(width), height(height) +{ + horizontal = std::vector(width * height, 0.0); + vertical = std::vector(width * height, 0.0); + + biggestMagnitude = 1.0f; +} + +VectorField::VectorField(int width, int height, const std::vector& hori, const std::vector& vert) : + width(width), height(height) +{ + horizontal = hori; + vertical = vert; + + for (double u : horizontal) + { + for (double v : vertical) + { + biggestMagnitude = std::max(biggestMagnitude, u * u + v * v); + } + } + + if (biggestMagnitude == 0.0) // should use an epsilon probably + biggestMagnitude = 1.0; + + biggestMagnitude = sqrt(biggestMagnitude); +} + +void VectorField::Draw(SDL_Renderer* renderer, const SDL_Rect& targetRect) +{ + double cellWidth = (double)(targetRect.w - targetRect.x) / (double)width; + double cellHeight = (double)(targetRect.h - targetRect.y) / (double)height; + + SDL_FRect vectorCenterSquare; + vectorCenterSquare.w = cellWidth / 5.0; + vectorCenterSquare.h = cellHeight / 5.0; + + SDL_SetRenderDrawColor(renderer, 200, 20, 20, 255); + for (int y = 0; y < height; y++) + { + for (int x = 0; x < width; x++) + { + vectorCenterSquare.x = (double)targetRect.x + cellWidth * (x + 0.4); // cellWidth * x + cellWidth / 2 - cellWidth / 10 + vectorCenterSquare.y = (double)targetRect.y + cellHeight * (y + 0.4); + SDL_RenderFillRectF(renderer, &vectorCenterSquare); + SDL_RenderDrawLineF(renderer, + (double)targetRect.x + cellWidth * (x + 0.5), + (double)targetRect.y + cellHeight * (y + 0.5), + (double)targetRect.x + cellWidth * (x + 0.5) + horizontal[y * width + x] / biggestMagnitude * cellWidth, + (double)targetRect.y + cellHeight * (y + 0.5) + vertical[y * width + x] / biggestMagnitude * cellHeight + ); + } + } +} diff --git a/src/VectorField.hpp b/src/VectorField.hpp new file mode 100644 index 0000000..e3b1b5d --- /dev/null +++ b/src/VectorField.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include + +struct SDL_Rect; +struct SDL_Renderer; + +class VectorField +{ +public: + VectorField(); + VectorField(int width, int height); + VectorField(int width, int height, const std::vector& hori, const std::vector& vert); + + void Draw(SDL_Renderer* renderer, const SDL_Rect& targetRect); + +private: + int width, height; + + std::vector horizontal; + std::vector vertical; + + double biggestMagnitude = 0.0; +}; \ No newline at end of file