2025-04-08T17:30:32

This commit is contained in:
yuntang 2025-04-08 17:30:33 +08:00
parent 47a55ee938
commit d349c689ac
4 changed files with 149 additions and 42 deletions

View File

@ -184,6 +184,7 @@ void PointCalculate::setRegionPointX(const float left, const float right)
_rightSelectedPoint = getClosestPointByX(right); _rightSelectedPoint = getClosestPointByX(right);
_peakPoint = getPeakPoint(); _peakPoint = getPeakPoint();
logde<<"peak point:"<<_peakPoint.x()<<","<<_peakPoint.y(); logde<<"peak point:"<<_peakPoint.x()<<","<<_peakPoint.y();
//根据峰谷重置选择点。 //根据峰谷重置选择点。
@ -197,7 +198,8 @@ QVector<QPointF> PointCalculate::getPeakPointGroup()
{ {
QVector<QPointF> pointVtr; QVector<QPointF> pointVtr;
for(FileManager::ExperimentData& ed:_dataVtr) { for(FileManager::ExperimentData& ed:_dataVtr) {
if(ed.sampleTemp >= _leftSelectedPoint.x() && ed.sampleTemp <= _rightSelectedPoint.x()){ if(ed.sampleTemp >= _leftSelectedPoint.x() &&
ed.sampleTemp <= _rightSelectedPoint.x()){
pointVtr.push_back(QPointF(ed.sampleTemp,ed.dsc)); pointVtr.push_back(QPointF(ed.sampleTemp,ed.dsc));
} }
} }
@ -205,7 +207,7 @@ QVector<QPointF> PointCalculate::getPeakPointGroup()
return pointVtr; return pointVtr;
} }
double PointCalculate::calculateArea() { float PointCalculate::calculateArea() {
//getPoint group //getPoint group
QVector<QPointF> points = getPeakPointGroup(); QVector<QPointF> points = getPeakPointGroup();
@ -218,27 +220,27 @@ double PointCalculate::calculateArea() {
} }
//find a line. //find a line.
double k = (_leftSelectedPoint.y() - _rightSelectedPoint.y()) / float k = (_leftSelectedPoint.y() - _rightSelectedPoint.y()) /
(_leftSelectedPoint.x() - _rightSelectedPoint.x()); (_leftSelectedPoint.x() - _rightSelectedPoint.x());
double b = _leftSelectedPoint.y() - k * _leftSelectedPoint.x(); float b = _leftSelectedPoint.y() - k * _leftSelectedPoint.x();
for (size_t i = 0; i < n - 1; ++i) { for (size_t i = 0; i < n - 1; ++i) {
#if 1 #if 1
double x1 = points[i].x(); float x1 = points[i].x();
double y1 = points[i].y(); float y1 = points[i].y();
double x2 = points[i + 1].x(); float x2 = points[i + 1].x();
double y2 = points[i + 1].y(); float y2 = points[i + 1].y();
#endif #endif
double yLine1 = k * x1 + b; float yLine1 = k * x1 + b;
double yLine2 = k * x2 + b; float yLine2 = k * x2 + b;
double diff1 = y1 - yLine1; float diff1 = y1 - yLine1;
double diff2 = y2 - yLine2; float diff2 = y2 - yLine2;
double dx = x2 - x1; float dx = x2 - x1;
double cellArea = (diff1 + diff2) * dx /2.0; float cellArea = (diff1 + diff2) * dx /2.0;
integral += std::abs(cellArea); integral += std::abs(cellArea);
} }
@ -328,6 +330,44 @@ QPointF PointCalculate::calculateIntersection(const QPointF p1,const QPointF p2,
} }
} }
QPair<float,float> PointCalculate::getCurveInflectionPointTangent(const float x1,const float x2)
{
std::vector<float> dataVtr;
for(FileManager::ExperimentData& ed:_dataVtr){
if(x1 < ed.sampleTemp && ed.sampleTemp < x2){
dataVtr.push_back(ed.sampleTemp);
}
}
//
std::vector<float> processedVtr = movingAverage(dataVtr,5);
// find max slope.
float maxSlope = 0.0;
float targetX = 0.0;
for (size_t i = 1; i < processedVtr.size(); ++i) {
float slope = processedVtr[i] - processedVtr[i - 1];
if(std::abs(slope) > maxSlope){
maxSlope = slope;
targetX = processedVtr[i];
}
}
// calculate line slope and axis Y space number b.
QPointF point = getClosestPointByX(targetX);
// 使用点斜式方程求y轴截距
// y = m * x + b
// double b = y - m * x;
float b = point.y() - maxSlope * point.x();
return qMakePair<float,float>(maxSlope,b);
}
QPointF PointCalculate::getIntersectionBySlope(const LineStruct& line1, const LineStruct& line2) {
float x = (line2.intercept - line1.intercept) / (line1.slope - line2.slope);
float y = line1.slope * x + line1.intercept;
// return {x, y};
return QPointF(x,y);
}
QPointF PointCalculate::getClosestPointByX(const float targetX) QPointF PointCalculate::getClosestPointByX(const float targetX)
{ {
#if 0 #if 0
@ -383,6 +423,7 @@ QPair<QPointF, QPointF> PointCalculate::getStartAndEndPoint()
if(_dataVtr.empty()){ if(_dataVtr.empty()){
return qMakePair(QPointF(), QPointF()); return qMakePair(QPointF(), QPointF());
} }
FileManager::ExperimentData startPoint = _dataVtr.at(0); FileManager::ExperimentData startPoint = _dataVtr.at(0);
FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1); FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1);
@ -405,12 +446,16 @@ QString PointCalculate::textFormatEndPoint(const QPointF point)
).arg(QString::number(point.x(), 'f', 3)); ).arg(QString::number(point.x(), 'f', 3));
} }
QPair<float,float> PointCalculate::getCurveInflectionPointTangent()
QPointF PointCalculate::getClosestPointByY(const float left,const float right,const float valueY)
{ {
float minValue = 100.0;
for(FileManager::ExperimentData& ed:_dataVtr){
if(left < ed.sampleTemp && ed.sampleTemp < right){
if(std::abs(ed.dsc - valueY) < minValue){
return QPointF(ed.sampleTemp,ed.dsc);
} }
}
QVector<QPointF> PointCalculate::getRegionPoints(const float, const float) }
{ return QPointF();
} }

View File

@ -12,7 +12,13 @@ QPair<QPointF,QPointF> getStartAndEndPoint();
void setRegionPointX(const float,const float); void setRegionPointX(const float,const float);
QPointF getClosestPointByX(const float); QPointF getClosestPointByX(const float);
QPointF getClosestPointByY(const float left,const float right,const float valueY);
QPointF getPeakPoint(); QPointF getPeakPoint();
QPair<QPointF,QPointF> calculateStartAndEndPoint();
float calculateArea();
// text format
QString textFormatPeakPoint(const float enthalpyValue, QString textFormatPeakPoint(const float enthalpyValue,
const float peakValue, const float peakValue,
const float startPoint, const float startPoint,
@ -21,12 +27,14 @@ QString textFormatNumbericalLabel(const QPointF);
QString textFormatStartPoint(const QPointF); QString textFormatStartPoint(const QPointF);
QString textFormatEndPoint(const QPointF); QString textFormatEndPoint(const QPointF);
QPair<QPointF,QPointF> calculateStartAndEndPoint(); // glass transition
double calculateArea(); QPair<float,float> getCurveInflectionPointTangent(const float,const float);
struct LineStruct {
float slope; //
float intercept; //
};
QPointF getIntersectionBySlope(const LineStruct& line1, const LineStruct& line2);
//​获取曲线拐点处的切线
QPair<float,float> getCurveInflectionPointTangent();
QVector<QPointF> getRegionPoints(const float,const float);
//private //private
void updateStartEndPoint(); void updateStartEndPoint();
QPair<QPointF,QPointF> calculateMaxDiffPointLeft(); QPair<QPointF,QPointF> calculateMaxDiffPointLeft();

View File

@ -322,19 +322,72 @@ void CentralWidget::glassTransitionHandle()
logde<<"point2:"<<point2.x()<<","<<point2.y(); logde<<"point2:"<<point2.x()<<","<<point2.y();
QCPItemStraightLine *line1 = new QCPItemStraightLine(_customPlot); QCPItemStraightLine *line1 = new QCPItemStraightLine(_customPlot);
line1->point1->setCoords(point1.x() - 55,point1.y()); line1->point1->setCoords(point1.x() - 5,point1.y());
line1->point2->setCoords(point1.x() + 55,point1.y()); line1->point2->setCoords(point1.x() + 5,point1.y());
line1->setPen(QPen(Qt::darkGreen)); line1->setPen(QPen(Qt::darkRed));
line1->setSelectable(false); line1->setSelectable(false);
line1->setVisible(true); line1->setVisible(true);
QCPItemStraightLine *line2 = new QCPItemStraightLine(_customPlot); QCPItemStraightLine *line2 = new QCPItemStraightLine(_customPlot);
line2->point1->setCoords(point2.x() - 55,point2.y()); line2->point1->setCoords(point2.x() - 5,point2.y());
line2->point2->setCoords(point2.x() + 55,point2.y()); line2->point2->setCoords(point2.x() + 5,point2.y());
line2->setPen(QPen(Qt::darkGreen)); line2->setPen(QPen(Qt::darkGreen));
line2->setSelectable(false); line2->setSelectable(false);
line2->setVisible(true); line2->setVisible(true);
_customPlot->replot();
//
PointCalculate::LineStruct lineStrc1,lineStrc2,tangetLineStrc;
lineStrc1.slope = 0.0;
lineStrc1.intercept = point1.y();
lineStrc2.slope = 0.0;
lineStrc2.intercept = point2.y();
QPair<float,float> tangentLinePair = PointCalculate::getCurveInflectionPointTangent(point1.x(),point2.x());
tangetLineStrc.slope = tangentLinePair.first;
tangetLineStrc.intercept = tangentLinePair.second;
QPointF intersection1 = PointCalculate::getIntersectionBySlope(tangetLineStrc,lineStrc1);
QPointF intersection2 = PointCalculate::getIntersectionBySlope(tangetLineStrc,lineStrc2);
// logde<<"intersection1 x:"<<intersection1.x();
// logde<<"intersection2 x:"<<intersection2.x();
//
float averageY = (point1.y() + point2.y()) /2;
QPointF averagePoint = PointCalculate::getClosestPointByY(point1.x(),point2.x(),averageY);
// logde<<"average y:"<<averageY;
logde<<"averagePoint x,y:"<<averagePoint.x()<<","
<<averagePoint.y();
logde<<"glass T1:"<<intersection1.x()
<<",Tg:"<<averagePoint.x()
<<",T2:"<<intersection2.x();
#if 0
// 创建一个圆形绘图项
QCPItemEllipse *circle = new QCPItemEllipse(_customPlot);
// _customPlot->addItem(circle);
// 设置圆形的位置和大小
circle->topLeft->setCoords(-5, 5);
circle->bottomRight->setCoords(5, -5);
// 设置圆形的填充和边框颜色
circle->setBrush(QBrush(Qt::cyan));
circle->setPen(QPen(Qt::blue));
#endif
QCPItemStraightLine *line3 = new QCPItemStraightLine(_customPlot);
line3->point1->setCoords(averagePoint.x() + 2,averagePoint.y() + 2);
line3->point2->setCoords(averagePoint.x() - 2,averagePoint.y() - 2);
line3->setPen(QPen(Qt::black));
line3->setSelectable(false);
line3->setVisible(true);
_customPlot->replot(); _customPlot->replot();
} }

View File

@ -50,6 +50,7 @@ private:
void setEventHandlerEnable(const bool); void setEventHandlerEnable(const bool);
void drawText(const QPointF,const QString); void drawText(const QPointF,const QString);
void fillGraph(const double x1,const double x2); void fillGraph(const double x1,const double x2);
enum ClearDataMode{ enum ClearDataMode{
All, All,
Undo Undo