Added plotting screen
This commit is contained in:
parent
d0de17afa1
commit
74c34370e2
27
include/Signal.hpp
Normal file
27
include/Signal.hpp
Normal 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;
|
||||
};
|
29
include/screens/PlotScreen.hpp
Normal file
29
include/screens/PlotScreen.hpp
Normal 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;
|
||||
};
|
|
@ -1,7 +1,7 @@
|
|||
add_executable(fourier
|
||||
"main.cpp"
|
||||
"RenderWindow.cpp"
|
||||
"Screen.cpp" "screens/DummyScreen.cpp")
|
||||
"Screen.cpp" "screens/DummyScreen.cpp" "screens/PlotScreen.cpp" "Signal.cpp")
|
||||
|
||||
target_include_directories(fourier PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
|
|
20
src/Signal.cpp
Normal file
20
src/Signal.cpp
Normal 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;
|
||||
}
|
|
@ -1,15 +1,19 @@
|
|||
#include <iostream>
|
||||
#include "RenderWindow.hpp"
|
||||
#include "screens/PlotScreen.hpp"
|
||||
#include "screens/DummyScreen.hpp"
|
||||
#include "Signal.hpp"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
Signal sig;
|
||||
|
||||
RenderWindow* window;
|
||||
DummyScreen* dScreen;
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -17,7 +21,6 @@ int main(int argc, char** argv)
|
|||
return -1;
|
||||
}
|
||||
|
||||
window->AddScreen(dScreen);
|
||||
window->Run();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -14,7 +14,7 @@ void DummyScreen::Update()
|
|||
void DummyScreen::Render(SDL_Renderer* renderer)
|
||||
{
|
||||
SDL_SetRenderTarget(renderer, texture);
|
||||
SDL_SetRenderDrawColor(renderer, 20, 40, 210, 255);
|
||||
SDL_SetRenderDrawColor(renderer, 120, 120, 120, 255);
|
||||
SDL_RenderClear(renderer);
|
||||
|
||||
SDL_SetRenderTarget(renderer, NULL);
|
||||
|
|
68
src/screens/PlotScreen.cpp
Normal file
68
src/screens/PlotScreen.cpp
Normal 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))
|
||||
});
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue