void WindPlot::updatePlot() { clearPlottables(); clearItems(); // Return now if plot empty if (mMainWindow->dataSize() == 0) return; double lower = mMainWindow->rangeLower(); double upper = mMainWindow->rangeUpper(); QVector< double > t, x, y; double xMin, xMax; double yMin, yMax; int start = mMainWindow->findIndexBelowT(lower) + 1; int end = mMainWindow->findIndexAboveT(upper); bool first = true; for (int i = start; i < end; ++i) { const DataPoint &dp = mMainWindow->dataPoint(i); t.append(dp.t); if (mMainWindow->units() == PlotValue::Metric) { x.append(dp.velE * MPS_TO_KMH); y.append(dp.velN * MPS_TO_KMH); } else { x.append(dp.velE * MPS_TO_MPH); y.append(dp.velN * MPS_TO_MPH); } if (first) { xMin = xMax = x.back(); yMin = yMax = y.back(); first = false; } else { if (x.back() < xMin) xMin = x.back(); if (x.back() > xMax) xMax = x.back(); if (y.back() < yMin) yMin = y.back(); if (y.back() > yMax) yMax = y.back(); } } QCPCurve *curve = new QCPCurve(xAxis, yAxis); curve->setData(t, x, y); curve->setPen(QPen(Qt::lightGray, mMainWindow->lineThickness())); setViewRange(xMin, xMax, yMin, yMax); if (mMainWindow->markActive()) { const DataPoint &dpEnd = mMainWindow->interpolateDataT(mMainWindow->markEnd()); t.clear(); x.clear(); y.clear(); QVector< double > xMark, yMark; if (mMainWindow->units() == PlotValue::Metric) { xMark.append(dpEnd.velE * MPS_TO_KMH); yMark.append(dpEnd.velN * MPS_TO_KMH); } else { xMark.append(dpEnd.velE * MPS_TO_MPH); yMark.append(dpEnd.velN * MPS_TO_MPH); } QCPGraph *graph = addGraph(); graph->setData(xMark, yMark); graph->setPen(QPen(Qt::black, mMainWindow->lineThickness())); graph->setLineStyle(QCPGraph::lsNone); graph->setScatterStyle(QCPScatterStyle::ssDisc); } updateWind(start, end); QVector< double > xMark, yMark; if (mMainWindow->units() == PlotValue::Metric) { xMark.append(mWindE * MPS_TO_KMH); yMark.append(mWindN * MPS_TO_KMH); } else { xMark.append(mWindE * MPS_TO_MPH); yMark.append(mWindN * MPS_TO_MPH); } QCPGraph *graph = addGraph(); graph->setData(xMark, yMark); graph->setPen(QPen(Qt::red, mMainWindow->lineThickness())); graph->setLineStyle(QCPGraph::lsNone); graph->setScatterStyle(QCPScatterStyle::ssDisc); const double x0 = mWindE; const double y0 = mWindN; const double r = mVelAircraft; QVector< double > tCircle, xCircle, yCircle; for (int i = 0; i <= 100; ++i) { tCircle.append(i); const double x = x0 + r * cos((double) i / 100 * 2 * M_PI); const double y = y0 + r * sin((double) i / 100 * 2 * M_PI); if (mMainWindow->units() == PlotValue::Metric) { xCircle.append(x * MPS_TO_KMH); yCircle.append(y * MPS_TO_KMH); } else { xCircle.append(x * MPS_TO_MPH); yCircle.append(y * MPS_TO_MPH); } } curve = new QCPCurve(xAxis, yAxis); curve->setData(tCircle, xCircle, yCircle); curve->setPen(QPen(Qt::red, mMainWindow->lineThickness())); // Add label to show best fit QCPItemText *textLabel = new QCPItemText(this); const double factor = (mMainWindow->units() == PlotValue::Metric) ? MPS_TO_KMH : MPS_TO_MPH; const QString units = (mMainWindow->units() == PlotValue::Metric) ? "km/h" : "mph"; double direction = atan2(-mWindE, -mWindN) / M_PI * 180.0; if (direction < 0) direction += 360.0; QPainter painter(this); double mmPerPix = (double) painter.device()->widthMM() / painter.device()->width(); double xRatioPerPix = 1.0 / axisRect()->width(); double xRatioPerMM = xRatioPerPix / mmPerPix; double yRatioPerPix = 1.0 / axisRect()->height(); double yRatioPerMM = yRatioPerPix / mmPerPix; textLabel->setPositionAlignment(Qt::AlignBottom|Qt::AlignRight); textLabel->setTextAlignment(Qt::AlignRight); textLabel->position->setType(QCPItemPosition::ptAxisRectRatio); textLabel->position->setCoords(1 - 5 * xRatioPerMM, 1 - 5 * yRatioPerMM); textLabel->setText( QString("Wind speed = %1 %2\nWind direction = %3 deg\nAircraft speed = %4 %5") .arg(sqrt(mWindE * mWindE + mWindN * mWindN) * factor) .arg(units) .arg(direction) .arg(mVelAircraft * factor) .arg(units)); replot(); }
void LiftDragPlot::updatePlot() { clearPlottables(); clearItems(); xAxis->setLabel(tr("Drag Coefficient")); yAxis->setLabel(tr("Lift Coefficient")); double lower = mMainWindow->rangeLower(); double upper = mMainWindow->rangeUpper(); QVector< double > t, x, y; double xMin, xMax; double yMin, yMax; int start = mMainWindow->findIndexBelowT(lower) + 1; int end = mMainWindow->findIndexAboveT(upper); double s10 = 0, s01 = 0, s20 = 0, s11 = 0; double s21 = 0, s30 = 0, s40 = 0; bool first = true; for (int i = start; i < end; ++i) { const DataPoint &dp = mMainWindow->dataPoint(i); t.append(dp.t); x.append(dp.drag); y.append(dp.lift); if (first) { xMax = x.back(); yMax = y.back(); first = false; } else { if (x.back() > xMax) xMax = x.back(); if (y.back() > yMax) yMax = y.back(); } s10 += dp.lift; s01 += dp.drag; s20 += dp.lift * dp.lift; s11 += dp.lift * dp.drag; s21 += dp.lift * dp.lift * dp.drag; s30 += dp.lift * dp.lift * dp.lift; s40 += dp.lift * dp.lift * dp.lift * dp.lift; } QCPCurve *curve = new QCPCurve(xAxis, yAxis); curve->setData(t, x, y); curve->setPen(QPen(Qt::lightGray, mMainWindow->lineThickness())); curve->setLineStyle(QCPCurve::lsNone); curve->setScatterStyle(QCPScatterStyle::ssDisc); addPlottable(curve); setViewRange(xMax, yMax); // Update plot limits xMin = xAxis->range().lower; xMax = xAxis->range().upper; yMin = yAxis->range().lower; yMax = yAxis->range().upper; if (mMainWindow->markActive()) { int i1 = mMainWindow->findIndexBelowT(mMainWindow->markEnd()) + 1; int i2 = mMainWindow->findIndexAboveT(mMainWindow->markEnd()) - 1; const DataPoint &dp1 = mMainWindow->dataPoint(i1); const DataPoint &dp2 = mMainWindow->dataPoint(i2); QVector< double > xMark, yMark; if (mMainWindow->markEnd() - dp1.t < dp2.t - mMainWindow->markEnd()) { xMark.append(dp1.drag); yMark.append(dp1.lift); } else { xMark.append(dp2.drag); yMark.append(dp2.lift); } QCPGraph *graph = addGraph(); graph->setData(xMark, yMark); graph->setPen(QPen(Qt::black, mMainWindow->lineThickness())); graph->setLineStyle(QCPGraph::lsNone); graph->setScatterStyle(QCPScatterStyle::ssDisc); } // x = ay^2 + c const double m = 1 / mMainWindow->maxLD(); const double c = mMainWindow->minDrag(); const double a = m * m / (4 * c); // Draw tangent line const double yt = sqrt(c / a); if (a != 0) { x.clear(); y.clear(); x << m * yMin << m * yMax; y << yMin << yMax; QCPGraph *graph = addGraph(); graph->setData(x, y); graph->setPen(QPen(Qt::blue, mMainWindow->lineThickness(), Qt::DashLine)); } // Draw minimum drag x.clear(); y.clear(); x << mMainWindow->minDrag() << mMainWindow->minDrag(); y << yMin << yMax; QCPGraph *graph = addGraph(); graph->setData(x, y); graph->setPen(QPen(Qt::blue, mMainWindow->lineThickness(), Qt::DashLine)); // Draw maximum lift x.clear(); y.clear(); x << xMin << xMax; y << mMainWindow->maxLift() << mMainWindow->maxLift(); graph = addGraph(); graph->setData(x, y); graph->setPen(QPen(Qt::blue, mMainWindow->lineThickness(), Qt::DashLine)); // Draw saved curve t.clear(); x.clear(); y.clear(); for (int i = 0; i <= 100; ++i) { const double yy = yMin + (yMax - yMin) / 100 * i; t.append(yy); x.append(a * yy * yy + c); y.append(yy); } curve = new QCPCurve(xAxis, yAxis); curve->setData(t, x, y); curve->setPen(QPen(Qt::red, mMainWindow->lineThickness())); addPlottable(curve); // Draw dot at maximum L/D x.clear(); y.clear(); x << a * yt * yt + c; y << yt; graph = addGraph(); graph->setData(x, y); graph->setPen(QPen(Qt::red, mMainWindow->lineThickness())); graph->setLineStyle(QCPGraph::lsNone); graph->setScatterStyle(QCPScatterStyle::ssDisc); // Add label to show equation for saved curve QCPItemText *textLabel = new QCPItemText(this); addItem(textLabel); QPainter painter(this); double mmPerPix = (double) painter.device()->widthMM() / painter.device()->width(); double xRatioPerPix = 1.0 / axisRect()->width(); double xRatioPerMM = xRatioPerPix / mmPerPix; double yRatioPerPix = 1.0 / axisRect()->height(); double yRatioPerMM = yRatioPerPix / mmPerPix; textLabel->setPositionAlignment(Qt::AlignBottom|Qt::AlignRight); textLabel->setTextAlignment(Qt::AlignRight); textLabel->position->setType(QCPItemPosition::ptAxisRectRatio); textLabel->position->setCoords(1 - 5 * xRatioPerMM, 1 - 5 * yRatioPerMM); textLabel->setText( QString("Minimum drag = %1\nMaximum lift = %2\nMaximum L/D = %3") .arg(fabs(c)) .arg(mMainWindow->maxLift()) .arg(1/ m)); replot(); }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); QVector<double> x(100), y(100); QFile file("F:\\Github\\SplinesQt\\bin\\debug\\coords.txt" ); if(!file.open(QIODevice::ReadOnly)) { QMessageBox::information(0,"error",file.errorString()); qDebug() << "Error!!!!"; } qDebug() << "Hello!!!!"; QTextStream in(&file); std::vector<gte::Vector2<float>> mSamples; int i = 0; while(!in.atEnd()) { QString line = in.readLine(); QStringList fields = line.split(" "); x[i] = fields.at(0).toDouble(); y[i] = fields.at(1).toDouble(); gte::Vector2<float> point; point[0] = x[i]; point[1] = y[i]; mSamples.push_back(point); qDebug() << x[i] << " " << y[i] << "\n"; i++; } file.close(); int pointsNumber = i; /* int xmin = x[0], ymin = y[0]; for (int kk = 0; kk < pointsNumber; kk++) { x[kk] -= xmin; y[kk] -= ymin; qDebug() << x[kk] << " " << y[kk] << "\n"; }*/ ui->customPlot->addGraph(); ui->customPlot->xAxis->setRange(60, 150); ui->customPlot->yAxis->setRange(60, 150); ui->customPlot->graph(0)->setData(x, y); ui->customPlot->graph(0)->setScatterStyle(QCPScatterStyle::ssCircle); ui->customPlot->graph(0)->setLineStyle(QCPGraph::LineStyle::lsNone); QVector<double> x2(10000), y2(10000); int mDegree = 3; int mNumControls = pointsNumber / 2; gte::BSplineCurveFit<float>* mSpline = new gte::BSplineCurveFit<float>(2, (int)mSamples.size(), (float const*)&mSamples[0], mDegree, mNumControls); /* std::vector<int> vecU = calculateKnotVector(pointsNumber,3); double du = 0.01; int k = 0; i--; for (double u = 0; u < 4; u += du) { x2[k] = 0; for (int j = 0; j <= i; j++) { x2[k] += x[j] * calcBSpline(j, 3, u, vecU); } y2[k] = 0; for (int j = 0; j <= i; j++) { y2[k] += y[j] * calcBSpline(j, 3, u, vecU); } qDebug() << x2[k] << " " << y2[k] << "\n"; k++; }*/ QVector<qreal> tData; unsigned int numSamples = (unsigned int)mSamples.size(); float multiplier = 1.0f / (2 * (numSamples - 1.0f)); for (unsigned int i = 0; i < 2 * numSamples; ++i) { float t = multiplier * i; float xxx[2]; mSpline->GetPosition(t, (float*)&xxx); //tData[i] = t; x2[i] = xxx[0]; y2[i] = xxx[1]; } QCPCurve *newCurve = new QCPCurve(ui->customPlot->xAxis, ui->customPlot->yAxis); ui->customPlot->addPlottable(newCurve); newCurve->setName("B-spline"); newCurve->setData(x2, y2); /* ui->customPlot->addGraph(); ui->customPlot->graph(1)->setData(x2, y2); ui->customPlot->graph(1)->setScatterStyle(QCPScatterStyle::ssDisc); ui->customPlot->graph(1)->setLineStyle(QCPGraph::LineStyle::lsNone); ui->customPlot->graph(1)->setPen(QPen(Qt::red));*/ factorial(5, 3); }