2025-04-08T17:30:32
This commit is contained in:
parent
47a55ee938
commit
d349c689ac
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user