Skip to content

Instantly share code, notes, and snippets.

@symroc
Created September 15, 2020 16:16
Show Gist options
  • Save symroc/f94e0230cca5fe9da683836c2205e912 to your computer and use it in GitHub Desktop.
Save symroc/f94e0230cca5fe9da683836c2205e912 to your computer and use it in GitHub Desktop.
Plot Data choosing local file. Based on libreplot
/*
* This file is part of libreplot.
* Copyright (C) 2014-2016 Kuldeep Singh Dhaka <kuldeep@madresistor.com>
*
* libreplot 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.
*
* libreplot 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 libreplot. If not, see <http://www.gnu.org/licenses/>.
*/
#include "cartesianLocal.h"
#include <QMouseEvent>
#include <QApplication>
#include <QDesktopWidget>
#include <QPaintDevice>
#include <Qt>
#include <math.h>
#include <QDebug>
Cartesian::Cartesian(QWidget *parent):
QOpenGLWidget(parent),
m_cartesian(NULL),
m_axis_left(NULL),
m_axis_bottom(NULL),
// m_curve(NULL),
// m_circle(NULL),
// m_text(NULL),
m_surface_width(0),
m_surface_height(0)
{
m_data = (lp_vec2f *) malloc(sizeof(lp_vec2f) * (20));
}
void Cartesian::setCh(int mych)
{
ch=mych;
}
Cartesian::~Cartesian()
{
makeCurrent();
lp_cartesian_del(m_cartesian);
lp_cartesian_axis_del(m_axis_left);
lp_cartesian_axis_del(m_axis_bottom);
lp_cartesian_curve_del(m_curve);
lp_circle_del(m_circle);
lp_text_del(m_text);
free(m_data);
doneCurrent();
}
void Cartesian::setData(float * data,uint size)
{
m_data = (lp_vec2f *) malloc(sizeof(lp_vec2f) * (size));
global_min=data[0];
global_max=data[0];
m_data = (lp_vec2f *) malloc(sizeof(lp_vec2f) * size);
for (uint i = 0; i < size; i++) {
double x = static_cast<double>(i)/static_cast<double>(3600000);
float y = data[i];
m_data[i].x = x;
m_data[i].y = y;
if (data[i]<global_min) global_min=data[i];
if (data[i]>global_max) global_max=data[i];
}
// qDebug()<<global_min<<global_max;
m_data_len=size;
m_axis_bottom = lp_cartesian_axis_gen();
m_axis_left = lp_cartesian_axis_gen();
lp_cartesian_axis_2float(m_axis_bottom, LP_CARTESIAN_AXIS_VALUE_RANGE, 0, size/3600000);
lp_cartesian_axis_2float(m_axis_left, LP_CARTESIAN_AXIS_VALUE_RANGE, 1.2*global_min, 1.2*global_max);
replot(size);
}
void Cartesian::replot(uint size){
m_curve = lp_cartesian_curve_gen();
lp_cartesian_pointer(m_cartesian, LP_CARTESIAN_AXIS_AT_LEFT, m_axis_left);
lp_cartesian_pointer(m_cartesian, LP_CARTESIAN_AXIS_AT_BOTTOM, m_axis_bottom);
switch (ch){
case 1:
lp_cartesian_curve_4float(m_curve, LP_CARTESIAN_CURVE_LINE_COLOR, 0.9529 , 0.4039, 0.2902, 1);
break;
case 2:
lp_cartesian_curve_4float(m_curve, LP_CARTESIAN_CURVE_LINE_COLOR, 0.1725 , 0.3725, 0.1765, 1);
break;
default:
lp_cartesian_curve_4float(m_curve, LP_CARTESIAN_CURVE_LINE_COLOR, 0 , 0.4470 , 0.8410, 1);
break;
}
lp_cartesian_curve_float(m_curve, LP_CARTESIAN_CURVE_LINE_WIDTH, 1);
lp_cartesian_curve_data(m_curve, LP_CARTESIAN_CURVE_X,
0, GL_FLOAT, sizeof(lp_vec2f), &m_data[0].x, size);
lp_cartesian_curve_data(m_curve, LP_CARTESIAN_CURVE_Y,
0, GL_FLOAT, sizeof(lp_vec2f), &m_data[0].y, size);
update();
}
void Cartesian::mousePressEvent(QMouseEvent *e)
{
if (e->buttons() & (Qt::LeftButton | Qt::RightButton)) {
last_x = e->x();
last_y = e->y();
e->accept();
}
}
void Cartesian::axis_translate(lp_cartesian_axis *axis, int surface, float diff,bool isHorizontal)
{
float min, max, tmp;
lp_get_cartesian_axis_2float(axis, LP_CARTESIAN_AXIS_VALUE_RANGE, &min, &max);
tmp = (max - min) * (diff / surface);
min -= tmp;
max -= tmp;
lp_cartesian_axis_2float(axis, LP_CARTESIAN_AXIS_VALUE_RANGE, min, max);
if (isHorizontal){
QVector<float> values={min,max};
emit xmoved(values);}
}
void Cartesian::axis_scale(lp_cartesian_axis *axis, int surface, float diff,bool isHorizontal)
{
float min, max, tmp;
lp_get_cartesian_axis_2float(axis, LP_CARTESIAN_AXIS_VALUE_RANGE, &min, &max);
tmp = ((max - min) / 2) * (diff / surface);
tmp *= 5; /* speed up */
min += tmp;
max -= tmp;
lp_cartesian_axis_2float(axis, LP_CARTESIAN_AXIS_VALUE_RANGE, min, max);
if (isHorizontal){
QVector<float> values={min,max};
emit xmoved(values);}
}
void Cartesian::SyncTranslation(QVector<float> l)
{
float xmin,xmax,ymin,ymax,min,max;
uint start,finish;
lp_cartesian_axis_2float(m_axis_bottom, LP_CARTESIAN_AXIS_VALUE_RANGE, l[0], l[1]);
lp_get_cartesian_axis_2float(m_axis_bottom, LP_CARTESIAN_AXIS_VALUE_RANGE, &xmin, &xmax);
// qDebug()<<ch<<xmin<<xmax;
if (m_data_len>50){
lp_get_cartesian_axis_2float(m_axis_left, LP_CARTESIAN_AXIS_VALUE_RANGE, &min, &max);
start=(uint)(xmin*3600000);
finish=(uint)(xmax*3600000);
if (xmin>0 && xmax<m_data_len && xmax!=xmin && start<m_data_len && finish<m_data_len){
ymin=m_data[start].y;
ymax=m_data[start].y;
}else if (finish<m_data_len){
ymin=m_data[0].y;
ymax=m_data[0].y;
start=0;
}
else{
ymin=m_data[0].y;
ymax=m_data[0].y;
start=0;
finish=m_data_len;
}
// qDebug()<<start<<finish<<m_data_len;
for (uint i = start; i < finish; i++) {
if(m_data[i].y>ymax) ymax=m_data[i].y;
if(m_data[i].y<ymin) ymin=m_data[i].y;
// qDebug()<<ch<<xmin<<xmax<<ymin<<ymax;
// qDebug()<<ch<<min<<max;
if (abs(min)<abs(ymin))min=1.2*ymin;
if (max<ymax)max=1.2*ymax;
if (abs(min)>abs(3*ymin)&&ymin<0)min=1.2*ymin;
if (max>3*ymax)max=1.2*ymax;
lp_cartesian_axis_2float(m_axis_left, LP_CARTESIAN_AXIS_VALUE_RANGE, min, max);
}
}
update();
}
void Cartesian::mouseMoveEvent(QMouseEvent *e)
{
int x = e->x(), y = e->y();
/* -1 multiplied because:
* from top->bottom [mouse coordinate]
* to bottom->top [graph].
* (only for Y axis) */
if (e->buttons() & Qt::LeftButton) {
axis_translate(m_axis_left, m_surface_height, -1 * (y - last_y),false);
axis_translate(m_axis_bottom, m_surface_width, (x - last_x),true);
} else if (e->buttons() & Qt::RightButton) {
axis_scale(m_axis_left, m_surface_height, -1 * (y - last_y),false);
axis_scale(m_axis_bottom, m_surface_width, x - last_x,true);
} else {
return;
}
last_x = x;
last_y = y;
e->accept();
update();
}
void Cartesian::mouseReleaseEvent(QMouseEvent *e)
{
e->accept();
update();
}
void Cartesian::axis_scroll(lp_cartesian_axis *axis, int steps,bool isVertical)
{
float min, max, tmp;
lp_get_cartesian_axis_2float(axis, LP_CARTESIAN_AXIS_VALUE_RANGE, &min, &max);
tmp = ((max - min) / 6) * steps;
min += tmp;
max -= tmp;
if (!isVertical){
QVector<float> values={min,max};
emit xmoved(values);
}
lp_cartesian_axis_2float(axis, LP_CARTESIAN_AXIS_VALUE_RANGE, min, max);
}
void Cartesian::wheelEvent(QWheelEvent *e)
{
QPoint numPixels = e->pixelDelta();
QPoint numDegrees = e->angleDelta() / 8;
qreal numSteps;
if (!numPixels.isNull()) {
numSteps = numPixels.y() / 15.0;
} else if (!numDegrees.isNull()) {
numSteps = numDegrees.y() / 15.0;
} else {
numSteps = 0;
}
axis_scroll(m_axis_left, numSteps,true);
axis_scroll(m_axis_bottom, numSteps,false);
update();
e->accept();
}
void Cartesian::initializeGL()
{
initializeOpenGLFunctions();
lp_init();
m_cartesian = lp_cartesian_gen();
m_dpi.x = physicalDpiX();
m_dpi.y = physicalDpiY();
lp_cartesian_2float(m_cartesian, LP_CARTESIAN_DPI, m_dpi.x, m_dpi.y);
m_axis_bottom = lp_cartesian_axis_gen();
m_axis_left = lp_cartesian_axis_gen();
lp_cartesian_axis_2float(m_axis_bottom, LP_CARTESIAN_AXIS_VALUE_RANGE, -10, +10);
lp_cartesian_axis_2float(m_axis_left, LP_CARTESIAN_AXIS_VALUE_RANGE, -10, +10);
lp_cartesian_pointer(m_cartesian, LP_CARTESIAN_AXIS_AT_LEFT, m_axis_left);
lp_cartesian_pointer(m_cartesian, LP_CARTESIAN_AXIS_AT_BOTTOM, m_axis_bottom);
m_curve = lp_cartesian_curve_gen();
lp_cartesian_curve_4float(m_curve, LP_CARTESIAN_CURVE_LINE_COLOR, 0, 0, 1, 1);
lp_cartesian_curve_float(m_curve, LP_CARTESIAN_CURVE_LINE_WIDTH, 3);
lp_cartesian_curve_data(m_curve, LP_CARTESIAN_CURVE_X,
0, GL_FLOAT, sizeof(lp_vec2f), &m_data[0].x, m_data_len);
lp_cartesian_curve_data(m_curve, LP_CARTESIAN_CURVE_Y,
0, GL_FLOAT, sizeof(lp_vec2f), &m_data[0].y, m_data_len);
lp_texture *marker = lp_texture_gen_text((uint8_t *)"◩", 7, lp_font_gen(), &m_dpi);
//lp_texture *marker = lp_texture_gen_png_file("/home/kuldeep/Desktop/not-gate-md.png");
lp_cartesian_curve_pointer(m_curve, LP_CARTESIAN_CURVE_MARKER_TEXTURE, marker);
lp_texture_del(marker);
lp_cartesian_curve_bool(m_curve, LP_CARTESIAN_CURVE_LINE_SHOW, true);
lp_cartesian_curve_bool(m_curve, LP_CARTESIAN_CURVE_MARKER_SHOW, false);
// m_circle = lp_circle_gen();
// lp_circle_float(m_circle, LP_CIRCLE_RADIUS, 3);
// m_text = lp_text_gen();
// lp_text_pointer(m_text, LP_TEXT_STRING, (void *) "Libreplot");
}
void Cartesian::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
lp_cartesian_4uint(m_cartesian, LP_CARTESIAN_SURFACE, 0, 0, w, h);
m_surface_width = w;
m_surface_height = h;
}
void Cartesian::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
lp_cartesian_draw_start(m_cartesian);
lp_cartesian_draw_curve(m_cartesian, m_curve);
// lp_cartesian_draw_circle(m_cartesian, m_circle);
// lp_cartesian_draw_text(m_cartesian, m_text);
lp_cartesian_draw_end(m_cartesian);
}
/*
* This file is part of libreplot.
* Copyright (C) 2014-2016 Kuldeep Singh Dhaka <kuldeep@madresistor.com>
*
* libreplot 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.
*
* libreplot 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 libreplot. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CARTESIANLocal_H
#define CARTESIANLocal_H
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QQuaternion>
#include <QVector2D>
extern "C"{
#include <libreplot/libreplot.h>
}
class Cartesian : public QOpenGLWidget, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit Cartesian(QWidget *parent = nullptr);
virtual ~Cartesian();
void setData(float * data,uint size);
void setCh(int mych);
public slots:
void SyncTranslation(QVector<float> l);
protected:
float global_min=-1.0;
float global_max=1.0;
void mousePressEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *e) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent * event) Q_DECL_OVERRIDE;
void wheelEvent(QWheelEvent * event) Q_DECL_OVERRIDE;
void axis_scale(lp_cartesian_axis *axis, int surface, float diff,bool isHorizontal);
void axis_translate(lp_cartesian_axis *axis, int surface, float diff,bool isHorizontal);
void axis_scroll(lp_cartesian_axis *axis, int steps,bool isVertical);
void initializeGL() Q_DECL_OVERRIDE;
void resizeGL(int w, int h) Q_DECL_OVERRIDE;
void paintGL() Q_DECL_OVERRIDE;
void replot(uint size);
lp_cartesian *m_cartesian;
lp_cartesian_axis *m_axis_left;
lp_cartesian_axis *m_axis_bottom;
lp_cartesian_curve *m_curve;
lp_circle *m_circle;
lp_text *m_text;
lp_vec2f *m_data;
lp_vec2f m_dpi;
uint m_data_len;
bool translate_active, scale_active;
int last_x, last_y;
int ch;
int m_surface_width, m_surface_height;
signals:
void xmoved(QVector<float> l);
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment