#include "pch.h" #include "viewwidget.h" #include #include #include 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; xIndexdata()->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 >& contours) { m_contours.assign(contours.begin(),contours.end() ); } //清空轮廓线 void ViewWidget::clearContours(void) { m_contours.clear(); } void ViewWidget::drawContours() { // 添加黑色曲线 clearItems(); // QVector xs; // QVector 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 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 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 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 = " <