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);
_peakPoint = getPeakPoint();
logde<<"peak point:"<<_peakPoint.x()<<","<<_peakPoint.y();
//根据峰谷重置选择点。
@ -197,7 +198,8 @@ QVector<QPointF> PointCalculate::getPeakPointGroup()
{
QVector<QPointF> pointVtr;
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));
}
}
@ -205,7 +207,7 @@ QVector<QPointF> PointCalculate::getPeakPointGroup()
return pointVtr;
}
double PointCalculate::calculateArea() {
float PointCalculate::calculateArea() {
//getPoint group
QVector<QPointF> points = getPeakPointGroup();
@ -218,27 +220,27 @@ double PointCalculate::calculateArea() {
}
//find a line.
double k = (_leftSelectedPoint.y() - _rightSelectedPoint.y()) /
float k = (_leftSelectedPoint.y() - _rightSelectedPoint.y()) /
(_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) {
#if 1
double x1 = points[i].x();
double y1 = points[i].y();
float x1 = points[i].x();
float y1 = points[i].y();
double x2 = points[i + 1].x();
double y2 = points[i + 1].y();
float x2 = points[i + 1].x();
float y2 = points[i + 1].y();
#endif
double yLine1 = k * x1 + b;
double yLine2 = k * x2 + b;
float yLine1 = k * x1 + b;
float yLine2 = k * x2 + b;
double diff1 = y1 - yLine1;
double diff2 = y2 - yLine2;
float diff1 = y1 - yLine1;
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);
}
@ -289,9 +291,9 @@ void PointCalculate::updateStartEndPoint()
}
}
QString PointCalculate::textFormatPeakPoint(const float enthalpyValue,
const float peakValue,
const float startPoint,
const float endPoint)
const float peakValue,
const float startPoint,
const float endPoint)
{
return QString("峰的综合信息:\n"
"焓值:%1 J/g \n"
@ -306,7 +308,7 @@ QString PointCalculate::textFormatPeakPoint(const float enthalpyValue,
// 计算两条直线的交点
QPointF PointCalculate::calculateIntersection(const QPointF p1,const QPointF p2,
const QPointF p3, const QPointF p4){
const QPointF p3, const QPointF p4){
// 直线的一般式: A1x + B1y + C1 = 0 和 A2x + B2y + C2 = 0
float A1 = p2.y() - p1.y();
float B1 = p1.x() - p2.x();
@ -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)
{
#if 0
@ -362,7 +402,7 @@ QPointF PointCalculate::getClosestPointByX(const float targetX)
if(left > 0 &&
std::abs(resultPointF.x() - targetX) >
std::abs(_dataVtr.at(left - 1).sampleTemp - targetX)){
//
//
resultPointF = QPointF(_dataVtr.at(left - 1).sampleTemp,
_dataVtr.at(left - 1).dsc);
}
@ -381,10 +421,11 @@ QString PointCalculate::textFormatNumbericalLabel(const QPointF point)
QPair<QPointF, QPointF> PointCalculate::getStartAndEndPoint()
{
if(_dataVtr.empty()){
return qMakePair(QPointF(), QPointF());
return qMakePair(QPointF(), QPointF());
}
FileManager::ExperimentData startPoint = _dataVtr.at(0);
FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1);
FileManager::ExperimentData startPoint = _dataVtr.at(0);
FileManager::ExperimentData endPoint = _dataVtr.at(_dataVtr.size() - 1);
return qMakePair<QPointF,QPointF>(
QPointF(startPoint.sampleTemp,startPoint.dsc),
@ -405,12 +446,16 @@ QString PointCalculate::textFormatEndPoint(const QPointF point)
).arg(QString::number(point.x(), 'f', 3));
}
QPair<float,float> PointCalculate::getCurveInflectionPointTangent()
QPointF PointCalculate::getClosestPointByY(const float left,const float right,const float valueY)
{
}
QVector<QPointF> PointCalculate::getRegionPoints(const float, const float)
{
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);
}
}
}
return QPointF();
}

View File

@ -12,7 +12,13 @@ QPair<QPointF,QPointF> getStartAndEndPoint();
void setRegionPointX(const float,const float);
QPointF getClosestPointByX(const float);
QPointF getClosestPointByY(const float left,const float right,const float valueY);
QPointF getPeakPoint();
QPair<QPointF,QPointF> calculateStartAndEndPoint();
float calculateArea();
// text format
QString textFormatPeakPoint(const float enthalpyValue,
const float peakValue,
const float startPoint,
@ -21,12 +27,14 @@ QString textFormatNumbericalLabel(const QPointF);
QString textFormatStartPoint(const QPointF);
QString textFormatEndPoint(const QPointF);
QPair<QPointF,QPointF> calculateStartAndEndPoint();
double calculateArea();
// glass transition
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
void updateStartEndPoint();
QPair<QPointF,QPointF> calculateMaxDiffPointLeft();

View File

@ -231,9 +231,9 @@ void CentralWidget::slotAnalysisSettingApply()
<<startEndPointPair.second.x();
drawText(peakPoint,PointCalculate::textFormatPeakPoint(enthalpyValue,
peakPoint.x(),
startEndPointPair.first.x(),
startEndPointPair.second.x()));
peakPoint.x(),
startEndPointPair.first.x(),
startEndPointPair.second.x()));
//
break;
}
@ -322,19 +322,72 @@ void CentralWidget::glassTransitionHandle()
logde<<"point2:"<<point2.x()<<","<<point2.y();
QCPItemStraightLine *line1 = new QCPItemStraightLine(_customPlot);
line1->point1->setCoords(point1.x() - 55,point1.y());
line1->point2->setCoords(point1.x() + 55,point1.y());
line1->setPen(QPen(Qt::darkGreen));
line1->point1->setCoords(point1.x() - 5,point1.y());
line1->point2->setCoords(point1.x() + 5,point1.y());
line1->setPen(QPen(Qt::darkRed));
line1->setSelectable(false);
line1->setVisible(true);
QCPItemStraightLine *line2 = new QCPItemStraightLine(_customPlot);
line2->point1->setCoords(point2.x() - 55,point2.y());
line2->point2->setCoords(point2.x() + 55,point2.y());
line2->point1->setCoords(point2.x() - 5,point2.y());
line2->point2->setCoords(point2.x() + 5,point2.y());
line2->setPen(QPen(Qt::darkGreen));
line2->setSelectable(false);
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();
}

View File

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