2025-04-01T17:25:11

This commit is contained in:
yuntang 2025-04-01 17:25:12 +08:00
parent 8f1d0427d3
commit fc961c8e0b
8 changed files with 147 additions and 137 deletions

View File

@ -17,7 +17,8 @@
}
],
"externalConsole": false,
"miDebuggerPath": "D:/qt/Qt5.14.2/5.14.2/mingw73_64/bin/gdb.exe"
"miDebuggerPath": "D:/qt/Qt5.14.2/5.14.2/mingw73_64/bin/gdb.exe",
"visualizerFile": "c:\\Users\\sunqu\\AppData\\Roaming\\Trae CN\\User\\workspaceStorage\\7f93734217a2e383fe34beaf49d497fe\\tonka3000.qtvsctools\\qt.natvis.xml"
}
]
}

View File

@ -10,6 +10,12 @@ QPointF PeakPoint::_leftSelectedPoint,PeakPoint::_rightSelectedPoint;
void PeakPoint::setExperimentData(const QVector<FileManager::ExperimentData> &dataVtr)
{
_dataVtr = dataVtr;
FileManager::ExperimentData startPoint = _dataVtr.at(0);
FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1);
_leftSelectedPoint = QPointF(startPoint.sampleTemp,startPoint.dsc);
_rightSelectedPoint = QPointF(endPoint.sampleTemp,endPoint.dsc);
}
QPointF PeakPoint::findPeakPoint(){
@ -20,13 +26,9 @@ QPointF PeakPoint::findPeakPoint(){
}
QPointF uniquePeak;
// 初始化为 float 类型能表示的最小负数,确保能处理负数 y 值
float maxY = -std::numeric_limits<float>::infinity();
bool isPeak = false;
float maxDiff = -std::numeric_limits<float>::infinity();
#if 1
// 直接在遍历过程中找出最大波峰
for (int i = 10; i < n - 10; ++i) { // 从第11个点开始到倒数第11个点结束
for (int i = 0; i < n; ++i) {
const float currentX = _dataVtr.at(i).sampleTemp;
const float currentY = _dataVtr.at(i).dsc;
@ -37,31 +39,18 @@ QPointF PeakPoint::findPeakPoint(){
break;
}
bool isPeak = true;
// 比较当前点与前后10个点的y值
for (int j = 1; j <= 10; ++j) {
const float preY = _dataVtr.at(i - j).dsc;
const float lastY = _dataVtr.at(i + j).dsc;
// 计算当前点与左选择点 y 值的差值
float diffLeft = std::abs(currentY - _leftSelectedPoint.y());
// 计算当前点与右选择点 y 值的差值
float diffRight = std::abs(currentY - _rightSelectedPoint.y());
// 取两个差值中的较大值
float currentDiff = std::max(diffLeft, diffRight);
if (currentY < preY || currentY < lastY) {
isPeak = false;
break;
}
}
if(isPeak){
#if 1
float absY = std::abs(currentY);
if(absY > maxY){
maxY = absY;
uniquePeak = QPointF(currentX,currentY);
// logde<<"preY:"<<preY<<",lastY:"<<lastY;
}
#endif
if (currentDiff > maxDiff) {
maxDiff = currentDiff;
uniquePeak = QPointF(currentX, currentY);
}
}
#endif
_peakPoint = uniquePeak;
@ -125,24 +114,25 @@ QPair<QPointF, QPointF> PeakPoint::calculateMaxDiffPointRight()
return calculateMaxDiffPointDetail(MaxDiffPointDetailType::Right);
}
float PeakPoint::findClosestY(float targetX)
#if 0
QPointF PeakPoint::findClosestY(float targetX)
{
float minDiff = std::numeric_limits<float>::max();
float closestY = 0.0;
QPointF resultPointF;
for(FileManager::ExperimentData &ed:_dataVtr){
// 计算当前 x 与目标 x 的差值的绝对值
float diff = std::abs(ed.sampleTemp - targetX);
// 更新最小差值和对应的 y 值
if (diff < minDiff) {
minDiff = diff;
closestY = ed.dsc;
resultPointF = QPointF(ed.sampleTemp,ed.dsc);
}
}
return closestY;
return resultPointF;
}
#endif
#if 0
QPointF PeakPoint::findClosestPointByX(float x) {
int left = 0;
int right = _dataVtr.size() - 1;
@ -169,18 +159,23 @@ QPointF PeakPoint::findClosestPointByX(float x) {
return targetPoint;
}
#endif
void PeakPoint::setRegionPointX(const float left, const float right)
{
logde<<"select point param left,right:"<<left<<","<<right;
_leftSelectedPoint = findClosestPointByX(left);
_rightSelectedPoint = findClosestPointByX(right);
findPeakPoint();
_peakPoint = findPeakPoint();
logde<<"peak point:"<<_peakPoint.x()<<","<<_peakPoint.y();
//根据峰谷重置选择点。
updateStartEndPoint();
qDebug()<<"left,right select point:"<<_leftSelectedPoint
<<","<<_rightSelectedPoint;
logde<<"select point left:"<<_leftSelectedPoint.x()<<","<<_leftSelectedPoint.y();
logde<<"select point right:"<<_rightSelectedPoint.x()<<","<<_rightSelectedPoint.y();
}
QVector<QPointF> PeakPoint::getPeakPointGroup()
@ -272,11 +267,16 @@ QPair<QPointF, QPointF> PeakPoint::calculateStartAndEndPoint()
logde<<"b1:"<<leftMaxDiffPointPair.first.x()<<","<<leftMaxDiffPointPair.first.y();
logde<<"b2:"<<leftMaxDiffPointPair.second.x()<<","<<leftMaxDiffPointPair.second.y();
logde<<"b3:"<<rightMaxDiffPointPair.first.x()<<","<<rightMaxDiffPointPair.first.y();
logde<<"b4:"<<rightMaxDiffPointPair.second.x()<<","<<rightMaxDiffPointPair.second.y();
QPointF startPoint = calculateIntersection(_leftSelectedPoint,_rightSelectedPoint,
leftMaxDiffPointPair.first,leftMaxDiffPointPair.second);
leftMaxDiffPointPair.first,
leftMaxDiffPointPair.second);
QPointF endPoint = calculateIntersection(_leftSelectedPoint,_rightSelectedPoint,
rightMaxDiffPointPair.first,rightMaxDiffPointPair.second);
rightMaxDiffPointPair.first,
rightMaxDiffPointPair.second);
return qMakePair(startPoint,endPoint);
}
@ -298,13 +298,12 @@ void PeakPoint::updateStartEndPoint()
_rightSelectedPoint.setY(ed.dsc);
}
}
}
}
QString PeakPoint::textFormat(const float enthalpyValue,
const float peakValue,
const float startPoint,
const float endPoint)
QString PeakPoint::textFormatPeakPoint(const float enthalpyValue,
const float peakValue,
const float startPoint,
const float endPoint)
{
return QString("峰的综合信息:\n"
"焓值:%1 J/g \n"
@ -341,8 +340,36 @@ QPointF PeakPoint::calculateIntersection(const QPointF p1,const QPointF p2,
}
}
QPointF PeakPoint::findClosestPointByX(const float targetX)
{
float minDiff = std::numeric_limits<float>::max();
QPointF resultPointF;
for(FileManager::ExperimentData &ed:_dataVtr){
float diff = std::abs(ed.sampleTemp - targetX);
if (diff < minDiff) {
minDiff = diff;
resultPointF = QPointF(ed.sampleTemp,ed.dsc);
}
}
return resultPointF;
}
QString PeakPoint::textFormatNumbericalLabel(const QPointF point)
{
return QString("数值:\n"
"%1℃,%2"
).arg(QString::number(point.x(), 'f', 3))
.arg(QString::number(point.y(), 'f', 3));
}
QPair<QPointF, QPointF> PeakPoint::getStartAndEndPoint()
{
FileManager::ExperimentData startPoint = _dataVtr.at(0);
FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1);
return qMakePair<QPointF,QPointF>(
QPointF(startPoint.sampleTemp,startPoint.dsc),
QPointF(endPoint.sampleTemp,endPoint.dsc));
}

View File

@ -5,16 +5,18 @@
#include "filemanager.h"
namespace PeakPoint{
void setExperimentData(const QVector<FileManager::ExperimentData>&);
QPair<QPointF,QPointF> getStartAndEndPoint();
void setRegionPointX(const float,const float);
float findClosestY(float targetX);
QPointF findClosestPointByX(const float);
QPointF findPeakPoint();
QString textFormat(const float enthalpyValue,
QString textFormatPeakPoint(const float enthalpyValue,
const float peakValue,
const float startPoint,
const float endPoint);
QString textFormatNumbericalLabel(const QPointF);
QPair<QPointF,QPointF> calculateStartAndEndPoint();
double calculateArea();
@ -30,7 +32,6 @@ QPair<QPointF,QPointF> calculateMaxDiffPointDetail(const MaxDiffPointDetailType
QPointF calculateIntersection(const QPointF p1,const QPointF p2,
const QPointF p3, const QPointF p4);
QPointF findClosestPointByX(float target);
QVector<QPointF> getPeakPointGroup();
extern QVector<FileManager::ExperimentData> _dataVtr;

View File

@ -95,6 +95,9 @@ void MainWindow::connections()
_centralWidget,&CentralWidget::slotAnalysisSettingUndo);
connect(_analysisSettingWidget,&AnalysisSettingForm::sigCancel,
_centralWidget,&CentralWidget::slotAnalysisSettingCancel);
connect(_centralWidget,&CentralWidget::sigRightDockWidgetHide,
[&](){ _rightWidget->hide(); });
}
void MainWindow::setActionEnable(const bool flag)

View File

@ -45,6 +45,7 @@ AnalysisSettingForm::AnalysisSettingForm(QWidget *parent) :
layout->addLayout(buttonLayout);
layout->addStretch(1);
//
#if 0
connect(_applyButton,&QPushButton::clicked,
this,&AnalysisSettingForm::slotApply);
connect(_confirmButton,&QPushButton::clicked,
@ -53,6 +54,15 @@ AnalysisSettingForm::AnalysisSettingForm(QWidget *parent) :
this,&AnalysisSettingForm::slotUndo);
connect(_cancelButton,&QPushButton::clicked,
this,&AnalysisSettingForm::slotCancel);
#endif
connect(_applyButton,&QPushButton::clicked,
this,&AnalysisSettingForm::sigApply);
connect(_confirmButton,&QPushButton::clicked,
this,&AnalysisSettingForm::sigConfirm);
connect(_undoButton,&QPushButton::clicked,
this,&AnalysisSettingForm::sigUndo);
connect(_cancelButton,&QPushButton::clicked,
this,&AnalysisSettingForm::sigCancel);
//
_leftBorderSpinBox->setRange(0.0, 10000.0); // 设置范围
_rightBorderSpinBox->setRange(0.0, 10000.0); // 设置范围
@ -72,6 +82,7 @@ void AnalysisSettingForm::slotRecvLineXCoord(const int index, const double point
}
}
#if 0
void AnalysisSettingForm::slotApply()
{
emit sigApply();
@ -79,15 +90,18 @@ void AnalysisSettingForm::slotApply()
void AnalysisSettingForm::slotConfirm()
{
emit sigConfirm();
hide();
}
void AnalysisSettingForm::slotUndo()
{
emit sigUndo();
}
void AnalysisSettingForm::slotCancel()
{
emit sigCancel();
hide();
}
#endif

View File

@ -21,10 +21,12 @@ signals:
public slots:
void slotRecvLineXCoord(const int,const double);
private slots:
#if 0
void slotApply();
void slotUndo();
void slotConfirm();
void slotCancel();
#endif
private:
QDoubleSpinBox *_leftBorderSpinBox,*_rightBorderSpinBox;
QLineEdit *_thresholdLineEdit;

View File

@ -81,7 +81,7 @@ void CentralWidget::setAnalysisMode(const CentralWidget::AnalysisMode mode)
_nanlysisMode = mode;
}
#endif
_nanlysisMode = mode;
_nanlysisMode = mode;
switch (mode)
{
@ -147,14 +147,6 @@ void CentralWidget::slotRecvAnalysisFileName(const QString &fileName)
return;
}
#if 0
//判断界面上是不是有曲线,有的话先删除。
_customPlot->clearGraphs();
// 创建画布,设置画布上的点数据
_customPlot->addGraph();
#endif
PeakPoint::setExperimentData(_dataVtr);
// 设置坐标轴标签
@ -187,7 +179,11 @@ void CentralWidget::slotAnalysisSettingApply()
switch (_nanlysisMode) {
case AnalysisMode::NumericalLabel:
{
drawText(_line1->point1->coords(),"11111");
QPointF selectPoint = PeakPoint::findClosestPointByX(
_line1->point1->coords().x());
drawText(selectPoint,PeakPoint::textFormatNumbericalLabel(selectPoint));
break;
}
case AnalysisMode::PeakSynthesisAnalysis:
@ -205,12 +201,13 @@ void CentralWidget::slotAnalysisSettingApply()
QPointF peakPoint = PeakPoint::findPeakPoint();
// qDebug()<<"peak point:"<<point;
//start point and end point
QPair<QPointF, QPointF> startEndPointPair = PeakPoint::calculateStartAndEndPoint();
QPair<QPointF, QPointF> startEndPointPair =
PeakPoint::calculateStartAndEndPoint();
drawText(peakPoint,PeakPoint::textFormat(enthalpyValue,
peakPoint.x(),
startEndPointPair.first.x(),
startEndPointPair.second.x()));
drawText(peakPoint,PeakPoint::textFormatPeakPoint(enthalpyValue,
peakPoint.x(),
startEndPointPair.first.x(),
startEndPointPair.second.x()));
//
break;
}
@ -221,17 +218,25 @@ void CentralWidget::slotAnalysisSettingApply()
void CentralWidget::slotAnalysisSettingConfirm()
{
slotAnalysisSettingApply();
setAnalysisMode(CentralWidget::AnalysisMode::None);
_line1->setVisible(false);
emit sigRightDockWidgetHide();
}
void CentralWidget::slotAnalysisSettingUndo()
{
clearData(ClearDataMode::Undo);
}
void CentralWidget::slotAnalysisSettingCancel()
{
clearData(ClearDataMode::Undo);
setAnalysisMode(CentralWidget::AnalysisMode::None);
_line1->setVisible(false);
emit sigRightDockWidgetHide();
}
void CentralWidget::slotAnalysisSettingLineXPoint(const int index, const double)
@ -392,8 +397,8 @@ void CentralWidget::fillGraph(const double x1, const double x2)
{
//todo.未寻找x1\x2之间最大值。
double y1 = PeakPoint::findClosestY(x1);
double y2 = PeakPoint::findClosestY(x2);
double y1 = PeakPoint::findClosestPointByX(x1).y();
double y2 = PeakPoint::findClosestPointByX(x2).y();
QVector<double> xVtr,yVtr;
xVtr.push_back(x1);
@ -416,19 +421,21 @@ void CentralWidget::fillGraph(const double x1, const double x2)
_customPlot->replot();
}
void CentralWidget::clearAllData()
void CentralWidget::clearData(const CentralWidget::ClearDataMode mode)
{
#if 1
// Set lines visiable false.
_line1->setVisible(false);
_line2->setVisible(false);
if(mode == ClearDataMode::All){
// Clear the data of graph.
if (_customPlot->graphCount() > 0 && _graph)
{
_graph->setData(QVector<double>(), QVector<double>());
}
// Clear the data of graph.
if (_customPlot->graphCount() > 0 && _graph)
{
_graph->setData(QVector<double>(), QVector<double>());
// Set lines visiable false.
_line1->setVisible(false);
_line2->setVisible(false);
}
// Clear filled area.
_graph->setBrush(QBrush(Qt::transparent));
// Clear graph on plot.
@ -451,60 +458,9 @@ void CentralWidget::clearAllData()
// 重绘图表以显示更改
_customPlot->replot();
#endif
#if 0
// 删除不需要的 Item
for (auto *item : itemsToRemove) {
_customPlot->removeItem(item);
delete item;
}
_customPlot->replot();
//
if (_customPlot->graphCount() > 0 && _graph)
{
// 清除第一个图表上的数据
_graph->setData(QVector<double>(), QVector<double>());
}
_customPlot->clearItems(); // 清除所有 QCPItem 对象
_customPlot->replot(); // 刷新显示
#endif
#if 0
// 从后向前遍历更安全
for (int i = _customPlot->itemCount()-1; i >= 0; --i) {
QCPItem* item = _customPlot->item(i);
if (item != _line1 && item != _line2) {
_customPlot->removeItem(item);
delete item;
}
}
_customPlot->replot();
#endif
#if 0
// 遍历并删除所有图形元素,除了指定的元素
for (int i = _customPlot->itemCount() - 1; i >= 0; --i) {
QCPAbstractItem *item = _customPlot->item(i);
if (item != _line1 && item != _line2) {
_customPlot->removeItem(item);
}
}
// 遍历并删除所有绘图元素,除了指定的元素
for (int i = _customPlot->graphCount() - 1; i >= 0; --i) {
QCPGraph *graph = _customPlot->graph(i);
if (graph != _graph) {
_customPlot->removeGraph(graph);
}
}
// 遍历并删除所有文本元素
for (int i = _customPlot->textLayoutCount() - 1; i >= 0; --i) {
QCPTextElement *textElement = _customPlot->textLayout(i);
_customPlot->removeTextLayout(textElement);
}
#endif
}
void CentralWidget::clearAllData()
{
clearData(ClearDataMode::All);
}

View File

@ -29,12 +29,14 @@ public:
signals:
void sigContextMenuShow(const QPoint);
void sigSendLineXCoord(const int,const double);
void sigRightDockWidgetHide();
public slots:
void slotModeModify(const Global::Mode);
void slotRecvCommonData(const CommonData&);
void slotRecvAnalysisFileName(const QString&);
//analysis setting
void slotAnalysisSettingLineXPoint(const int index,const double);
void slotAnalysisSettingApply();
void slotAnalysisSettingConfirm();
void slotAnalysisSettingUndo();
@ -45,8 +47,12 @@ protected:
private:
void setEventHandlerEnable(const bool);
void drawText(const QPointF,const QString);
// double findClosestY(double targetX);
void fillGraph(const double x1,const double x2);
enum ClearDataMode{
All,
Undo
};
void clearData(const ClearDataMode);
private:
AnalysisMode _nanlysisMode;
QCustomPlot *_customPlot;