|
|
#include "viewwidget.h"
|
|
|
#include <QPainter>
|
|
|
#include <thread>
|
|
|
#include <functional>
|
|
|
using namespace std;
|
|
|
//#include "coutlinedetector.h"
|
|
|
ViewWidget::ViewWidget(QWidget *parent) : MyColorMap(parent)
|
|
|
, m_type(colorfulmap)
|
|
|
,m_bTransparentColormap(false)
|
|
|
{
|
|
|
// this->setStyleSheet("QWidget { border: 1px solid black; }");
|
|
|
// 设置边框样式
|
|
|
//this->setBackgroundRole(QPalette::Light);
|
|
|
//this->setFrameShape(QFrame::Box);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
//重置坐标框范围
|
|
|
void ViewWidget::resetAxisRect(void)
|
|
|
{
|
|
|
m_dispCoordsRect.setCoords(0,0,0,0);
|
|
|
}
|
|
|
//保存当前坐标框范围到m_axisRect
|
|
|
void ViewWidget::saveCurrentAxisRect(void)
|
|
|
{
|
|
|
m_dispCoordsRect.setLeft(this->xAxis->range().lower);
|
|
|
m_dispCoordsRect.setRight(this->xAxis->range().upper);
|
|
|
m_dispCoordsRect.setBottom(this->yAxis->range().lower);
|
|
|
m_dispCoordsRect.setTop(this->yAxis->range().upper);
|
|
|
|
|
|
|
|
|
;
|
|
|
}
|
|
|
|
|
|
|
|
|
void ViewWidget::updateDraw()
|
|
|
{
|
|
|
//重绘
|
|
|
disconnect(m_colorScale, &QCPColorScale::dataRangeChanged,this, &ViewWidget::slotScaleRangeChanged);
|
|
|
|
|
|
clearPlottables();
|
|
|
clearGraphs();
|
|
|
|
|
|
if(nullptr == m_pGrid)
|
|
|
{
|
|
|
|
|
|
replot(QCustomPlot::rpQueuedReplot);
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QCustomPlot* customPlot = this;
|
|
|
|
|
|
QString demoName = " Amplitude Color Map";
|
|
|
|
|
|
// configure axis rect:
|
|
|
customPlot->setInteractions(QCP::iRangeDrag|QCP::iRangeZoom); // this will also allow rescaling the color scale by dragging/zooming
|
|
|
customPlot->axisRect()->setupFullAxesBox(true);
|
|
|
customPlot->xAxis->setLabel(m_strXLabel);
|
|
|
customPlot->yAxis->setLabel(m_strYLabel);
|
|
|
|
|
|
// set up the QCPColorMap:
|
|
|
QCPColorMap *colorMap = new QCPColorMap(customPlot->xAxis, customPlot->yAxis);
|
|
|
int nx = m_pGrid->XNum()-1;
|
|
|
int ny = m_pGrid->YNum()-1;
|
|
|
double xmin = m_pGrid->X(0);
|
|
|
double ymin = m_pGrid->Y(0);
|
|
|
double xmax = m_pGrid->X(nx);
|
|
|
double ymax = m_pGrid->Y(ny);
|
|
|
double* zrange = m_pGrid->GetRange();
|
|
|
double zmin = zrange[0];
|
|
|
double zmax = zrange[1];
|
|
|
|
|
|
zmin -= 1e-4;
|
|
|
zmax += 1e-4;
|
|
|
|
|
|
|
|
|
|
|
|
colorMap->data()->setSize(nx, ny); // we want the color map to have nx * ny data points
|
|
|
colorMap->data()->setRange(QCPRange(xmin,xmax), QCPRange(ymin,ymax)); // and span the coordinate range -4..4 in both key (x) and value (y) dimensions
|
|
|
// now we assign some data, by accessing the QCPColorMapData instance of the color map:
|
|
|
double x, y, z;
|
|
|
|
|
|
// float zmin = 1e31, zmax = -10;
|
|
|
|
|
|
for (int xIndex=0; xIndex<nx; ++xIndex)
|
|
|
{
|
|
|
for (int yIndex=0; yIndex<ny; ++yIndex)
|
|
|
{
|
|
|
colorMap->data()->cellToCoord(xIndex, yIndex, &x, &y);
|
|
|
|
|
|
z = m_pGrid->Z(xIndex,yIndex);
|
|
|
|
|
|
|
|
|
//越界数据赋空值
|
|
|
if(z < zmin || z > zmax || m_bTransparentColormap)
|
|
|
{
|
|
|
z = 1e20;
|
|
|
}
|
|
|
|
|
|
colorMap->data()->setCell(xIndex, yIndex,z);
|
|
|
|
|
|
// zmin = std::fmin(zmin,(z1+z2)/2.0);
|
|
|
// zmax = std::fmax(zmax,(z1+z2)/2.0);
|
|
|
|
|
|
}
|
|
|
}
|
|
|
|
|
|
zmin += 1e-4;
|
|
|
zmax -= 1e-4;
|
|
|
|
|
|
|
|
|
// qDebug() << "zmin = " << zmin << " zmax = " << zmax;
|
|
|
|
|
|
// add a color scale:
|
|
|
|
|
|
QCPColorScale *colorScale = m_colorScale;
|
|
|
if(nullptr == m_colorScale)
|
|
|
{
|
|
|
m_colorScale = new QCPColorScale(customPlot);
|
|
|
|
|
|
colorScale = m_colorScale; // new QCPColorScale(customPlot);
|
|
|
customPlot->plotLayout()->addElement(0, 1, colorScale); // add it to the right of the main axis rect
|
|
|
colorScale->setType(QCPAxis::atRight); // scale shall be vertical bar with tick/axis labels right (actually atRight is already the default)
|
|
|
|
|
|
}
|
|
|
|
|
|
colorMap->setColorScale(colorScale); // associate the color map with the color scale
|
|
|
|
|
|
// colorScale->setLabel("幅值");
|
|
|
// colorScale->axis()->setLabel("幅度差");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// set the color gradient of the color map to one of the presets:
|
|
|
switch(m_type)
|
|
|
{
|
|
|
case colorfulmap:
|
|
|
case colorfulmap_contours:
|
|
|
default:
|
|
|
{
|
|
|
QCPColorGradient gradient(QCPColorGradient::gpSpectrum); //定义一个渐变对象
|
|
|
// if(m_bTransparentColormap)
|
|
|
// {
|
|
|
// gradient.setColorStopAt(0, Qt::transparent); //设置特殊数值的颜色为透明色
|
|
|
// gradient.setColorStopAt(1, Qt::transparent);
|
|
|
// }
|
|
|
colorMap->setGradient(gradient); //将设置好的渐变对象赋给colormap
|
|
|
|
|
|
//colorMap->setGradient(QCPColorGradient::gpSpectrum);
|
|
|
}
|
|
|
break;
|
|
|
case graymap:
|
|
|
colorMap->setGradient(QCPColorGradient::gpGrayscale);
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
// we could have also created a QCPColorGradient instance and added own colors to
|
|
|
// the gradient, see the documentation of QCPColorGradient for what's possible.
|
|
|
|
|
|
// rescale the data dimension (color) such that all data points lie in the span visualized by the color gradient:
|
|
|
colorMap->rescaleDataRange();
|
|
|
QCPRange range(zmin, zmax);
|
|
|
colorMap->setDataRange(range);
|
|
|
|
|
|
|
|
|
|
|
|
if(graymap != m_type && m_colorScaleRange.size() > 1)
|
|
|
{
|
|
|
colorMap->colorScale()->setDataRange(m_colorScaleRange);
|
|
|
}
|
|
|
|
|
|
//colorMap->setDataRange(QCPRange(3,5));
|
|
|
|
|
|
// if(colorful == m_type)
|
|
|
// {
|
|
|
// //begin test
|
|
|
// colorMap->setDataRange(QCPRange(zmin,zmax));
|
|
|
// QCPColorGradient gradient = colorMap->gradient();
|
|
|
// gradient.setColorStopAt(zmax+1,Qt::white);
|
|
|
// gradient.setColorStopAt(zmax+10,Qt::white);
|
|
|
// // gradient.setColorStopAt(-1,Qt::white);
|
|
|
// colorMap->setGradient(gradient);
|
|
|
// // colorMap->rescaleDataRange();
|
|
|
// //end test
|
|
|
// }
|
|
|
|
|
|
// 禁用科学计数法
|
|
|
xAxis->setNumberFormat("g");
|
|
|
yAxis->setNumberFormat("g");
|
|
|
|
|
|
// 设置精度
|
|
|
xAxis->setNumberPrecision(8);
|
|
|
yAxis->setNumberPrecision(8);
|
|
|
|
|
|
|
|
|
// make sure the axis rect and color scale synchronize their bottom and top margins (so they line up):
|
|
|
QCPMarginGroup *marginGroup = new QCPMarginGroup(customPlot);
|
|
|
customPlot->axisRect()->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);
|
|
|
colorScale->setMarginGroup(QCP::msBottom|QCP::msTop, marginGroup);
|
|
|
|
|
|
|
|
|
//如果绘制轮廓线
|
|
|
if( colorfulmap_contours == m_type && m_contours.size() > 0)
|
|
|
{
|
|
|
QTime t1; t1.start();
|
|
|
drawContours();
|
|
|
qDebug()<< "drawcontours time elapsed: "<< t1.elapsed() << " ms";
|
|
|
|
|
|
}
|
|
|
|
|
|
// rescale the key (x) and value (y) axes so the whole color map is visible:
|
|
|
customPlot->rescaleAxes();
|
|
|
|
|
|
refreshAxis();
|
|
|
//replot(QCustomPlot::rpQueuedReplot);
|
|
|
connect(m_colorScale, &QCPColorScale::dataRangeChanged,this, &ViewWidget::slotScaleRangeChanged);
|
|
|
|
|
|
// // 固定纵横比
|
|
|
// setFixedSize(800, 600); // 设置绘图区域的固定大小
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
//void ViewWidget::setImage(const QImage& img, bool bUpdate)
|
|
|
//{
|
|
|
// m_img = img;
|
|
|
|
|
|
// if(bUpdate)
|
|
|
// this->update();
|
|
|
//}
|
|
|
|
|
|
//void ViewWidget::showEvent(QShowEvent *event)
|
|
|
//{
|
|
|
// this->setStyleSheet("QWidget { border: 1px solid black; }");
|
|
|
//}
|
|
|
|
|
|
//void ViewWidget::paintEvent(QPaintEvent *event)
|
|
|
//{
|
|
|
|
|
|
|
|
|
////painter.fillRect(rt,Qt::white);
|
|
|
|
|
|
|
|
|
// if(m_img.isNull())
|
|
|
|
|
|
// return;
|
|
|
//// img = QImage(rt.width(),rt.height(),QImage::Format_ARGB32);
|
|
|
//// img.fill(Qt::white);
|
|
|
|
|
|
|
|
|
// QRect rt = this->contentsRect();
|
|
|
// rt.adjust(1,1,-1,-1);
|
|
|
|
|
|
// QPainter painter(this);
|
|
|
|
|
|
// QImage img = m_img.scaled(rt.width(),rt.height(),Qt::KeepAspectRatio);
|
|
|
|
|
|
|
|
|
// painter.drawImage(rt.left() +(rt.width()-img.width())/2,rt.top()+(rt.height()-img.height())/2,img);
|
|
|
|
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
//void ViewWidget::resizeEvent(QResizeEvent *event)
|
|
|
//{
|
|
|
// this->update();
|
|
|
//}
|
|
|
|
|
|
//void ViewWidget::mouseDoubleClickEvent(QMouseEvent *event)
|
|
|
//{
|
|
|
// if(m_img.isNull())
|
|
|
// return;
|
|
|
|
|
|
|
|
|
// cv::Mat mat;
|
|
|
|
|
|
// COutlineDetector::ConvertQImageToMat(m_img,mat);
|
|
|
|
|
|
// cv::namedWindow("image",WINDOW_NORMAL);
|
|
|
|
|
|
// cv::imshow("image",mat);
|
|
|
|
|
|
// cv::waitKey(0);
|
|
|
|
|
|
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//设置轮廓线
|
|
|
void ViewWidget::setContours(vector< vector<cv::Point2f> >& contours)
|
|
|
{
|
|
|
m_contours.assign(contours.begin(),contours.end() );
|
|
|
|
|
|
}
|
|
|
//清空轮廓线
|
|
|
void ViewWidget::clearContours(void)
|
|
|
{
|
|
|
m_contours.clear();
|
|
|
}
|
|
|
|
|
|
void ViewWidget::drawContours()
|
|
|
{
|
|
|
// 添加黑色曲线
|
|
|
|
|
|
|
|
|
clearItems();
|
|
|
|
|
|
|
|
|
|
|
|
// QVector<double> xs;
|
|
|
// QVector<double> ys;
|
|
|
// QPen pen(Qt::black);
|
|
|
// int j = 0;
|
|
|
|
|
|
|
|
|
// for(auto& p: m_contours)
|
|
|
// {
|
|
|
|
|
|
// int igraph = this->graphCount();
|
|
|
// this->addGraph();
|
|
|
|
|
|
// xs.clear(); ys.clear();
|
|
|
// xs.resize(p.size()+1);
|
|
|
// ys.resize(p.size()+1);
|
|
|
// int i = 0;
|
|
|
|
|
|
|
|
|
// for(i = 0; i < p.size(); i ++ )
|
|
|
// {
|
|
|
// xs[i] = p[i].x;
|
|
|
// ys[i] = p[i].y;
|
|
|
|
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
// xs[i] = p[0].x;
|
|
|
// ys[i] = p[0].y;
|
|
|
|
|
|
|
|
|
// graph(igraph)->addData(xs,ys,true);
|
|
|
// graph(igraph)->setPen(pen);
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
for(auto& p: m_contours)
|
|
|
{
|
|
|
|
|
|
QCPItemLine* line = nullptr;
|
|
|
int i = 0;
|
|
|
for( i = 0; i < p.size()-1; i ++ )
|
|
|
{
|
|
|
line = new QCPItemLine(this);
|
|
|
line->start->setCoords(p[i].x,p[i].y);
|
|
|
line->end->setCoords(p[i+1].x,p[i+1].y);
|
|
|
|
|
|
line->setPen(QPen(Qt::black));
|
|
|
}
|
|
|
|
|
|
line = new QCPItemLine(this);
|
|
|
line->start->setCoords(p[i].x,p[i].y);
|
|
|
line->end->setCoords(p[0].x,p[0].y);
|
|
|
|
|
|
line->setPen(QPen(Qt::black));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// // 添加多边形到图层上
|
|
|
// QCPItemCurve *polygon1 = new QCPItemCurve(this);
|
|
|
|
|
|
|
|
|
// // 设置第一个多边形的顶点
|
|
|
// QVector<QPointF> polygon1Points;
|
|
|
// polygon1Points.resize(p.size()+1);
|
|
|
// int i = 0;
|
|
|
// for( i = 0; i < p.size(); i ++ )
|
|
|
// {
|
|
|
// polygon1Points[i] = QPointF(p[i].x,p[i].y);
|
|
|
// }
|
|
|
|
|
|
// polygon1Points[i] = QPointF(p[0].x,p[0].y);
|
|
|
|
|
|
|
|
|
|
|
|
// polygon1->setPen(QPen(Qt::black)); // 设置多边形的线条样式
|
|
|
// polygon1->setHead(QCPLineEnding::esNone); // 不显示线条末端箭头
|
|
|
// polygon1->setTail(QCPLineEnding::esNone); // 不显示线条末端箭头
|
|
|
// polygon1
|
|
|
|
|
|
|
|
|
}
|
|
|
// // 添加多边形到图层上
|
|
|
// QCPItemCurve *polygon1 = new QCPItemCurve(this);
|
|
|
|
|
|
|
|
|
// // 设置第一个多边形的顶点
|
|
|
// QVector<QPointF> polygon1Points;
|
|
|
// polygon1Points << QPointF(0, 0) << QPointF(100, 0) << QPointF(100, 100) << QPointF(0, 100) << QPointF(0, 0);
|
|
|
// polygon1->setPen(QPen(Qt::black)); // 设置多边形的线条样式
|
|
|
// polygon1->setHead(QCPLineEnding::esNone); // 不显示线条末端箭头
|
|
|
// polygon1->setTail(QCPLineEnding::esNone); // 不显示线条末端箭头
|
|
|
// polygon1->setCurveData(polygon1Points);
|
|
|
|
|
|
// // 设置第二个多边形的顶点
|
|
|
// QVector<QPointF> polygon2Points;
|
|
|
// polygon2Points << QPointF(50, 50) << QPointF(150, 50) << QPointF(150, 150) << QPointF(50, 150) << QPointF(50, 50);
|
|
|
// polygon2->setPen(QPen(Qt::black)); // 设置多边形的线条样式
|
|
|
// polygon2->setHead(QCPLineEnding::esNone); // 不显示线条末端箭头
|
|
|
// polygon2->setTail(QCPLineEnding::esNone); // 不显示线条末端箭头
|
|
|
// polygon2->setCurveData(polygon2Points);
|
|
|
|
|
|
// // 将多边形添加到图表中
|
|
|
// customPlot.addItem(polygon1);
|
|
|
// customPlot.addItem(polygon2);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
void ViewWidget::slotScaleRangeChanged(const QCPRange& newRange)
|
|
|
{
|
|
|
if(graymap != m_type)
|
|
|
m_colorScaleRange = newRange;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void ViewWidget::refreshAxis(void)
|
|
|
{
|
|
|
QCustomPlot* customPlot = this;
|
|
|
QRectF axisRect = customPlot->axisRect()->rect(); // 获取绘图区域的矩形
|
|
|
QCPColorScale* colorScale = m_colorScale;
|
|
|
// qDebug() << colorScale->margins().left() << " " << colorScale->margins().right();
|
|
|
|
|
|
double colorMapWidth = axisRect.width();// - colorScale->axis()->offset() - colorScale->barWidth() ; // 计算 colormap 区域的宽度
|
|
|
double colorMapHeight = axisRect.height(); // colormap 区域的高度
|
|
|
|
|
|
|
|
|
// qDebug() << "width = " << colorMapWidth;
|
|
|
// qDebug() << "height= " << colorMapHeight;
|
|
|
|
|
|
//实际坐标宽和高
|
|
|
// double xsz = customPlot->xAxis->range().size();
|
|
|
// double ysz = customPlot->yAxis->range().size();
|
|
|
|
|
|
|
|
|
|
|
|
int nx = m_pGrid->XNum()-1;
|
|
|
int ny = m_pGrid->YNum()-1;
|
|
|
|
|
|
//显示的坐标范围
|
|
|
double xmin = m_pGrid->X(0);
|
|
|
double ymin = m_pGrid->Y(0);
|
|
|
double xmax = m_pGrid->X(nx);
|
|
|
double ymax = m_pGrid->Y(ny);
|
|
|
|
|
|
if(m_dispCoordsRect.width() > 1 && m_dispCoordsRect.height() < -1)
|
|
|
{
|
|
|
xmin = m_dispCoordsRect.left();
|
|
|
|
|
|
if(xmin < m_pGrid->X(0))
|
|
|
xmin = m_pGrid->X(0);
|
|
|
|
|
|
ymin = m_dispCoordsRect.bottom();
|
|
|
if(ymin < m_pGrid->Y(0))
|
|
|
ymin = m_pGrid->Y(0);
|
|
|
|
|
|
xmax = min(m_dispCoordsRect.right(),m_pGrid->X(nx));
|
|
|
|
|
|
ymax = min(m_dispCoordsRect.top(),m_pGrid->Y(ny));
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
double xsz = xmax -xmin;
|
|
|
double ysz = ymax-ymin;
|
|
|
|
|
|
double pixelFactor = colorMapHeight/colorMapWidth; //像素宽高纵横比
|
|
|
double coordFactor = ysz/xsz; //实际坐标纵横比
|
|
|
|
|
|
|
|
|
// qDebug() << "窗口宽高 w h: " << colorMapWidth << " " << colorMapHeight << " " << 1.0/pixelFactor;
|
|
|
// qDebug() << "实际坐标纵横比 " << 1./coordFactor;
|
|
|
|
|
|
double span = 0;
|
|
|
// if(fabs(coordFactor/pixelFactor-1.0) < 1e-3)
|
|
|
// {
|
|
|
// replot(QCustomPlot::rpQueuedReplot); //重绘
|
|
|
// return;
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(coordFactor > pixelFactor) //实际坐标过高,补宽度
|
|
|
{
|
|
|
//ysz/pixelFactor 等比情况下,x的范围
|
|
|
span = ysz/pixelFactor - xsz;
|
|
|
|
|
|
xmax += span;
|
|
|
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
span = xsz * pixelFactor -ysz;
|
|
|
ymax += span;
|
|
|
|
|
|
}
|
|
|
|
|
|
// qDebug() << "span = " << span << "xmax = " <<xmax << " ymax = " << ymax;
|
|
|
|
|
|
customPlot->xAxis->setRange(xmin,xmax);
|
|
|
customPlot->yAxis->setRange(ymin,ymax);
|
|
|
replot(QCustomPlot::rpQueuedReplot); //重绘
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
void ViewWidget::resizeEvent(QResizeEvent *event)
|
|
|
{
|
|
|
|
|
|
saveCurrentAxisRect();
|
|
|
|
|
|
MyColorMap::resizeEvent(event);
|
|
|
|
|
|
if(nullptr != m_pGrid)
|
|
|
{
|
|
|
|
|
|
refreshAxis();
|
|
|
// updateDraw();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
//void ViewWidget::changeEvent(QEvent *event)
|
|
|
//{
|
|
|
// if (event->type() == QEvent::WindowStateChange)
|
|
|
// {
|
|
|
// if (windowState() & Qt::WindowMaximized)
|
|
|
// {
|
|
|
// if(nullptr != m_pGrid)
|
|
|
// {
|
|
|
|
|
|
// refreshAxis();
|
|
|
// // updateDraw();
|
|
|
|
|
|
// }
|
|
|
// }
|
|
|
// }
|
|
|
//}
|
|
|
|
|
|
|