aboutsummaryrefslogtreecommitdiffstats
path: root/pointcloud.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'pointcloud.cpp')
-rw-r--r--pointcloud.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/pointcloud.cpp b/pointcloud.cpp
new file mode 100644
index 0000000..417c31c
--- /dev/null
+++ b/pointcloud.cpp
@@ -0,0 +1,183 @@
+/*
+ Copyright (C) 2015
+ Matthias P. Braendli, matthias.braendli@mpb.li
+
+ http://opendigitalradio.org
+ */
+/*
+ This file is part of ODR-DPD.
+
+ ODR-DPD is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+
+ ODR-DPD is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with ODR-DPD. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "pointcloud.hpp"
+
+#include <iostream>
+#include <vector>
+
+#include <SDL/SDL.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <algorithm>
+
+using namespace std;
+
+PointCloud::PointCloud(size_t num_points) :
+ m_num_points(num_points),
+ m_rxgain(1.0),
+ m_txgain(1.0)
+{
+ SDL_Init(SDL_INIT_VIDEO);
+ atexit(SDL_Quit);
+ SDL_WM_SetCaption("Point Cloud", NULL);
+ SDL_SetVideoMode(720,640, 32, SDL_OPENGL);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ gluPerspective(6,(double)640/480,1,1000);
+}
+
+// Not really a border, but you get the idea
+vector<Point> PointCloud::generate_border(void)
+{
+ vector<Point> points(4);
+ points[0].x = 0;
+ points[0].y = 0;
+
+ points[1].x = 1;
+ points[1].y = 0;
+
+ points[2].x = 0;
+ points[2].y = 1;
+
+ points[3].x = 1;
+ points[3].y = 1;
+
+ for (auto &p : points) {
+ p.r = 255;
+ p.g = 255;
+ p.b = 0;
+ }
+
+ return points;
+}
+
+void PointCloud::push_samples(std::pair<std::vector<complexf>, std::vector<complexf> > &data)
+{
+ auto &rx = data.first;
+ auto &tx = data.second;
+
+ if (rx.size() != tx.size()) {
+ throw std::runtime_error("RX and TX have different size");
+ }
+
+ std::lock_guard<std::mutex> lock(m_mutex);
+
+ for (size_t i = 0; i < rx.size(); i++) {
+ Point p;
+
+ // Magnitude is position
+ p.x = std::abs(rx[i]) * m_rxgain;
+ p.y = std::abs(tx[i]) * m_txgain;
+ p.z = 0.0;
+
+ double arg_rx = std::arg(rx[i]);
+ double arg_tx = std::arg(tx[i]);
+
+ // Phase is colour
+ p.r = p.g = p.b = 255;
+ if (arg_rx > arg_tx) {
+ int corr = 255 - 10 * (arg_rx - arg_tx);
+
+ if (corr < 0) {
+ corr = 0;
+ }
+
+ p.r = corr;
+ }
+ else {
+ int corr = 255 - 10 * (arg_tx - arg_rx);
+
+ if (corr < 0) {
+ corr = 0;
+ }
+
+ p.b = corr;
+ }
+
+ m_points.push_back(p);
+ }
+
+ if (m_points.size() > m_num_points + rx.size()) {
+ m_points.erase(m_points.begin(), m_points.begin() + rx.size());
+ }
+}
+
+void PointCloud::handle_event()
+{
+ SDL_Event event;
+ while (SDL_PollEvent(&event))
+ {
+ switch(event.type){
+ case SDL_QUIT:
+ throw sdl_quit();
+ break;
+ }
+ }
+}
+
+void PointCloud::draw()
+{
+ std::lock_guard<std::mutex> lock(m_mutex);
+
+ size_t num_points_drawn = std::min(m_num_points, m_points.size());
+ vector<Point> v(m_num_points);
+ for (size_t i = 0; i < num_points_drawn; i++) {
+ v[i] = m_points[i];
+ }
+
+ m_mutex.unlock();
+
+ vector<Point> border = generate_border();
+ v.insert(v.end(), border.begin(), border.end());
+
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+ glPushMatrix();
+
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ gluLookAt(
+ 0.5,0.5,10,
+ 0.5,0.5,0,
+ 0,1,0);
+
+ glPointSize(4.0);
+
+ glBegin(GL_POINTS);
+ for (size_t n = 0; n < v.size(); n++){
+ glColor3ub(v[n].r, v[n].g, v[n].b);
+ glVertex3d(v[n].x, v[n].y, v[n].z);
+ }
+ glEnd();
+
+ glFlush();
+ SDL_GL_SwapBuffers();
+
+ glPopMatrix();
+ glPopAttrib();
+}
+