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); populationSize = 30; ui->popSizeSpinBox->setValue(populationSize); srand(static_cast <unsigned> (time(0))); stopFlag = false; pop = new Population(populationSize,true); setup(); model = new PopulationModel(*pop); ui->listView->setModel(model); QVector<double> ax(11); for(int i=0;i<11;i++){ ax[i] = i*100; } QCPCurve *newCurve = new QCPCurve(ui->citiesPlot->xAxis, ui->citiesPlot->yAxis); newCurve->setKeyAxis(ui->citiesPlot->xAxis); newCurve->setValueAxis(ui->citiesPlot->yAxis); newCurve->setLineStyle(QCPCurve::lsNone); newCurve->setPen(QPen(Qt::red)); newCurve->setScatterStyle(QCPScatterStyle(QCPScatterStyle::ssCircle, Qt::blue, Qt::darkBlue, 5)); for(int i=0; i<TourManager::numberOfCities(); i++){ int x = TourManager::getCity(i).getX(); int y = TourManager::getCity(i).getY(); newCurve->addData(x, y); } newCurve->addData(TourManager::getCity(0).getX(), TourManager::getCity(0).getY()); ui->citiesPlot->addPlottable(newCurve); ui->citiesPlot->xAxis->setRange(0, 1000); ui->citiesPlot->yAxis->setRange(0, 1000); ui->citiesPlot->xAxis->setAutoTickStep(false); ui->citiesPlot->yAxis->setAutoTickStep(false); ui->citiesPlot->xAxis->setTickStep(100); ui->citiesPlot->yAxis->setTickStep(100); ui->citiesPlot->xAxis->setTickVector(ax); ui->citiesPlot->yAxis->setTickVector(ax); //ui->citiesPlot->xAxis->setTicks(false); //ui->citiesPlot->yAxis->setTicks(false); ui->citiesPlot->xAxis->setTickLabels(true); ui->citiesPlot->yAxis->setTickLabels(true); ui->citiesPlot->xAxis->grid()->setPen(Qt::SolidLine); ui->citiesPlot->yAxis->grid()->setPen(Qt::SolidLine); //ui->citiesPlot->yAxis->setScaleRatio(ui->citiesPlot->xAxis,1.0); ui->statPlot->setBackground(Qt::gray); ui->statPlot->addGraph(); ui->statPlot->addGraph(); ui->statPlot->graph(0)->setPen(QPen(Qt::red)); ui->statPlot->graph(1)->setPen(QPen(Qt::blue)); ui->statPlot->graph(0)->setName(tr("Best")); ui->statPlot->graph(0)->addToLegend(); ui->statPlot->graph(1)->setName(tr("Average")); ui->statPlot->graph(1)->addToLegend(); ui->statPlot->xAxis->setRangeLower(0); QFont legendFont = font(); legendFont.setPointSize(9); QMargins margins(0,0,0,0); ui->statPlot->legend->setFont(legendFont); ui->statPlot->legend->setMargins(margins); ui->statPlot->legend->setVisible(true); ui->statPlot->axisRect()->insetLayout()->setInsetAlignment(0, Qt::AlignTop|Qt::AlignRight); //Population pop(50, true); generation = 0; ui->statPlot->graph(0)->addData(0, pop->getFittest().getDistance()); ui->statPlot->graph(1)->addData(0,pop->getAverage()); ui->statPlot->graph(1)->rescaleAxes(); ui->statPlot->xAxis->setRange(0, 101); ui->statPlot->xAxis->setTickStep(1); ui->statPlot->yAxis->setRangeLower(0); ui->statPlot->setInteraction(QCP::iRangeZoom); ui->statPlot->setInteraction(QCP::iRangeDrag); //ui->statPlot->axisRect()->setRangeDrag(Qt::Horizontal); GeneticEngine *ge = new GeneticEngine(); ui->mutationSpinBox->setValue(GeneticEngine::getMutationRate()); ui->tournamentSpinBox->setValue(GeneticEngine::getTournamentSize()); ui->tournamentSpinBox->setMaximum(pop->populationSize()); ui->elitismCheckBox->setChecked(GeneticEngine::getElitism()); ui->mutTypeComboBox->setCurrentIndex(GeneticEngine::getMutationType()); ui->crossTypeComboBox->setCurrentIndex(GeneticEngine::getCrossoverType()); ui->listView->setWindowTitle(tr("Generation :")); connect(ui->listView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)),this, SLOT(drawPath(QItemSelection))); connect(ui->runButton, SIGNAL(clicked(bool)),this, SLOT(run())); connect(ui->repopulateButton, SIGNAL(clicked()), this, SLOT(restart())); connect(ui->mutationSpinBox, SIGNAL(valueChanged(double)), ge,SLOT(setMutationRate(double))); connect(ui->tournamentSpinBox, SIGNAL(valueChanged(int)), ge, SLOT(setTournamentSize(int))); connect(ui->elitismCheckBox, SIGNAL(toggled(bool)), ge, SLOT(setElitism(bool))); connect(ui->mutTypeComboBox, SIGNAL(currentIndexChanged(int)), ge, SLOT(setMutationType(int))); connect(ui->crossTypeComboBox, SIGNAL(currentIndexChanged(int)), ge, SLOT(setCrossoverType(int))); connect(ui->popSizeSpinBox, SIGNAL(valueChanged(int)), this, SLOT(setPopulationSize(int))); connect(ui->actionAbout_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt())); connect(ui->actionSave, SIGNAL(triggered()), this, SLOT(save())); connect(ui->actionRandom_Initialization, SIGNAL(triggered()), this, SLOT(randInit())); connect(ui->actionLoad, SIGNAL(triggered()), this, SLOT(open())); readSettings(); //qDebug()<<pop->getFittest().getDistance(); }