Added plotting screen

This commit is contained in:
Robert 2020-11-09 17:28:19 +01:00
parent d0de17afa1
commit 74c34370e2
7 changed files with 152 additions and 5 deletions

27
include/Signal.hpp Normal file
View file

@ -0,0 +1,27 @@
#pragma once
#include <complex>
#include <deque>
typedef std::complex<double> CmplxDouble;
typedef struct {
double t;
CmplxDouble val;
bool valid = true;
} Sample;
static const Sample invalidSample{ 0.f, 0.f, false };
class Signal
{
public:
Signal() = default;
~Signal() = default;
friend Signal& operator<<(Signal& sig, const Sample& sample);
friend Signal& operator>>(Signal& sig, Sample& sample);
private:
std::deque<Sample> buffer;
};

View file

@ -0,0 +1,29 @@
#pragma once
#include <mutex>
#include <vector>
#include <SDL.h>
#include "../Screen.hpp"
#include "Signal.hpp"
typedef struct {
double x, y, w, h;
} fRect;
class PlotScreen : public Screen
{
public:
PlotScreen(SDL_Renderer* renderer, Signal* dataSource,
int x, int y, int w, int h,
double minX, double minY, double maxX, double maxY);
~PlotScreen();
void Update() override;
void Render(SDL_Renderer* renderer) override;
private:
void SignalToSampleList(std::vector<Sample>& container, uint32_t maxSamples = 0);
void SampleListToPointList(const std::vector<Sample>& source, std::vector<SDL_Point>& container);
fRect plotRect;
Signal* dataSource;
};

View file

@ -1,7 +1,7 @@
add_executable(fourier add_executable(fourier
"main.cpp" "main.cpp"
"RenderWindow.cpp" "RenderWindow.cpp"
"Screen.cpp" "screens/DummyScreen.cpp") "Screen.cpp" "screens/DummyScreen.cpp" "screens/PlotScreen.cpp" "Signal.cpp")
target_include_directories(fourier PRIVATE target_include_directories(fourier PRIVATE
${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/include

20
src/Signal.cpp Normal file
View file

@ -0,0 +1,20 @@
#include "Signal.hpp"
Signal& operator<<(Signal& sig, const Sample& sample)
{
sig.buffer.push_back(sample);
return sig;
}
Signal& operator>>(Signal& sig, Sample& sample)
{
if (sig.buffer.size() == 0)
sample = invalidSample;
else
{
sample = sig.buffer[0];
sig.buffer.pop_front();
}
return sig;
}

View file

@ -1,15 +1,19 @@
#include <iostream> #include <iostream>
#include "RenderWindow.hpp" #include "RenderWindow.hpp"
#include "screens/PlotScreen.hpp"
#include "screens/DummyScreen.hpp" #include "screens/DummyScreen.hpp"
#include "Signal.hpp"
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
Signal sig;
RenderWindow* window; RenderWindow* window;
DummyScreen* dScreen;
try try
{ {
window = new RenderWindow(800, 800); window = new RenderWindow(800, 800);
dScreen = new DummyScreen(window->renderer, 100, 100, 600, 600); window->AddScreen(new DummyScreen(window->renderer, 0, 0, 800, 800));
window->AddScreen(new PlotScreen(window->renderer, &sig, 50, 50, 700, 300, 0, -1.5f, 10, 1.5f));
} }
catch (const std::runtime_error& e) catch (const std::runtime_error& e)
{ {
@ -17,7 +21,6 @@ int main(int argc, char** argv)
return -1; return -1;
} }
window->AddScreen(dScreen);
window->Run(); window->Run();
return 0; return 0;

View file

@ -14,7 +14,7 @@ void DummyScreen::Update()
void DummyScreen::Render(SDL_Renderer* renderer) void DummyScreen::Render(SDL_Renderer* renderer)
{ {
SDL_SetRenderTarget(renderer, texture); SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderDrawColor(renderer, 20, 40, 210, 255); SDL_SetRenderDrawColor(renderer, 120, 120, 120, 255);
SDL_RenderClear(renderer); SDL_RenderClear(renderer);
SDL_SetRenderTarget(renderer, NULL); SDL_SetRenderTarget(renderer, NULL);

View file

@ -0,0 +1,68 @@
#include "screens/PlotScreen.hpp"
#include <vector>
#include <SDL.h>
#include "Signal.hpp"
#define MAP(A, B, a, b, val) ((val - A)*(b-a)/(B-A) + a)
PlotScreen::PlotScreen(SDL_Renderer* renderer, Signal* dataSource, int x, int y, int w, int h, double minX, double minY, double maxX, double maxY) :
Screen(renderer, x, y, w, h), dataSource(dataSource),
plotRect{ minX, minY, maxX, maxY }
{
}
PlotScreen::~PlotScreen()
{
}
void PlotScreen::Update()
{
}
void PlotScreen::Render(SDL_Renderer* renderer)
{
std::vector<Sample> samples;
SignalToSampleList(samples);
std::vector<SDL_Point> points;
SampleListToPointList(samples, points);
SDL_SetRenderTarget(renderer, texture);
SDL_SetRenderDrawColor(renderer, 240, 240, 240, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderDrawLines(renderer, points.data(), points.size());
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderCopy(renderer, texture, NULL, screenSpace);
for (int i = 0; i < 1000; i++)
{
(*dataSource) << Sample{ i / 10.0f, sin(i / 10.0f) };
}
}
void PlotScreen::SignalToSampleList(std::vector<Sample>& container, uint32_t maxSamples)
{
Sample s;
(*dataSource) >> s;
while (s.valid)
{
container.push_back(s);
if (container.size() == maxSamples)
return;
(*dataSource) >> s;
}
}
void PlotScreen::SampleListToPointList(const std::vector<Sample>& source, std::vector<SDL_Point>& container)
{
for (const Sample& sample : source)
{
container.push_back({
(int)std::floor((sample.t - plotRect.x) * screenSpace->w / (plotRect.w - plotRect.x)),
(int)std::floor(-(sample.val.real() + plotRect.y) * screenSpace->h / (plotRect.h - plotRect.y))
});
}
}