15 const int ControlPanel::DECIMALS = 8;
16 QMovie* ControlPanel::loaderMovie =
nullptr;
18 ControlPanel::ControlPanel(QWidget *parent)
20 locale(), movieLabel(nullptr), curve_was_ok(false)
26 ui.toolBox->setCurrentIndex(FrechetViewApplication::ALGORITHM_K_FRECHET);
29 ui.epsSlider->setMinimum(0);
30 ui.epsSlider->setMaximum(100);
31 ui.epsSlider->setTickInterval(5);
39 connect(
ui.showGreedy, SIGNAL(clicked()),
this, SLOT(
onGreedyButton()), Qt::QueuedConnection);
41 connect(
ui.showBF, SIGNAL(clicked()),
this, SLOT(
onBFButton()), Qt::QueuedConnection);
43 FrechetViewApplication* app = FrechetViewApplication::instance();
44 connect(
ui.optCurve, SIGNAL(clicked()), app, SLOT(startStopOptimiseCurve()), Qt::QueuedConnection);
45 connect(
ui.approxCurve, SIGNAL(clicked()), app, SLOT(startStopApproximateCurve()), Qt::QueuedConnection);
47 connect(
ui.decidePoly, SIGNAL(clicked()), app, SLOT(startStopDecidePolygon()), Qt::QueuedConnection);
48 connect(
ui.optPoly, SIGNAL(clicked()), app, SLOT(startStopOptimisePolygon()), Qt::QueuedConnection);
49 connect(
ui.approxPoly, SIGNAL(clicked()), app, SLOT(startStopApproximatePolygon()), Qt::QueuedConnection);
59 settings.beginGroup(group);
63 settings.setValue(
"algorithm", FrechetViewApplication::instance()->currentAlgorithm());
70 settings.beginGroup(group);
74 int algo = settings.value(
"algorithm", FrechetViewApplication::ALGORITHM_K_FRECHET).toInt();
75 FrechetViewApplication::instance()->setCurrentAlgorithm((FrechetViewApplication::Algorithm)algo);
76 ui.toolBox->setCurrentIndex(algo);
84 ui.epsSlider->blockSignals(
true);
87 ui.epsSlider->blockSignals(
false);
89 if (
eps != this->eps) {
101 QString s = QString::number(number);
102 return s.replace(
'.',
locale.decimalPoint());
110 return ok ?
eps : NAN;
129 if (eps_max <= 10.0) {
132 else if (eps_max <= 50.0) {
135 else if (eps_max <= 100.0) {
143 ui.epsSlider->setSingleStep(1);
144 ui.epsSlider->setPageStep(3);
145 ui.epsSlider->setTickInterval(1);
147 double current =
toDouble(
ui.epsEdit->text());
148 if (std::isnan(current) || (current < 0.0))
150 else if (current > eps_max)
165 if (
ui.showGreedy->isChecked())
167 else if (
ui.showBF->isChecked())
179 text =
"k="+QVariant(bf.
k_optimal).toString();
186 text += QString::number(bf.
k_min)+
" <= ";
199 text +=
" <= "+QString::number(bf.
k_max);
201 ui.resultBF->setText(text);
209 ui.resultBF->setText(
"--");
212 ui.resultBF->setText(
"?");
215 ui.resultBF->setText(
"...");
227 ui.showBF->setEnabled(
false);
228 ui.showBF->setCheckable(
false);
229 ui.showBF->setChecked(
false);
230 ui.showBF->setText(
"Show");
233 ui.showBF->setEnabled(
true);
234 ui.showBF->setCheckable(
false);
235 ui.showBF->setChecked(
false);
236 ui.showBF->setText(
"Go");
239 ui.showBF->setEnabled(
true);
240 ui.showBF->setCheckable(
false);
241 ui.showBF->setChecked(
false);
242 ui.showBF->setText(
"Stop");
245 ui.showBF->setEnabled(
true);
246 ui.showBF->setCheckable(
true);
247 ui.showBF->setText(
"Show");
280 text =
"k="+QString::number(k);
282 text +=
", "+QString::number(k2);
286 ui.resultGreedy->setText(text);
292 ui.showGreedy->setEnabled(
false);
293 ui.showGreedy->setChecked(
false);
296 ui.showGreedy->setEnabled(
false);
300 ui.showGreedy->setEnabled(
true);
316 "P is empty",
"Q is empty",
317 "P is not closed",
"Q is not closed",
319 "P is not simple",
"Q is not simple",
321 "P_NOT_COUNTER_CLOCKWISE",
"Q_NOT_COUNTER_CLOCKWISE",
323 "P is convex",
"Q is convex" 329 Algorithm::ptr poly = FrechetViewApplication::instance()->getPolyAlgorithm();
331 ui.resultPoly->setText(
"?");
337 int status = FrechetViewApplication::instance()->getPolyAlgorithm()->status();
338 if (status<=Algorithm::RUNNING) {
339 ui.resultPoly->setText(
"...");
340 ui.resultCurve->setText(
"...");
346 if (status <= Algorithm::RUNNING) {
347 if (status <= Algorithm::RUNNING_APPROX_POLY)
349 else if (status <= Algorithm::RUNNING_APPROX_CURVE)
352 else if (FrechetViewApplication::instance()->currentAlgorithm()==FrechetViewApplication::ALGORITHM_CURVE) {
357 ui.decidePoly->setEnabled (poly->canDecidePoly());
358 ui.optPoly->setEnabled (poly->canOptimisePoly());
359 ui.approxPoly->setEnabled (poly->canOptimisePoly());
360 ui.optCurve->setEnabled (poly->canOptimiseCurve());
361 ui.approxCurve->setEnabled (poly->canOptimiseCurve());
363 ui.decidePoly->setText(
"Decide");
364 ui.optPoly->setText(
"Optimise");
365 ui.approxPoly->setText(
"Approximate");
366 ui.optCurve->setText(
"Optimise");
367 ui.approxCurve->setText(
"Approximate");
373 ui.decidePoly->setEnabled(
false);
378 ui.decidePoly->setEnabled(
false);
380 case Algorithm::SET_UP:
382 ui.decidePoly->setEnabled(
true);
384 case Algorithm::RUNNING_OPT_CURVE:
385 ui.optCurve->setText(
"Stop");
386 ui.optCurve->setEnabled(
true);
388 case Algorithm::RUNNING_OPT_POLY:
389 ui.optPoly->setText(
"Stop");
390 ui.optPoly->setEnabled(
true);
392 case Algorithm::RUNNING_APPROX_CURVE:
393 ui.approxCurve->setText(
"Stop");
394 ui.approxCurve->setEnabled(
true);
396 case Algorithm::RUNNING_APPROX_POLY:
397 ui.approxPoly->setText(
"Stop");
398 ui.approxPoly->setEnabled(
true);
400 case Algorithm::RUNNING_DECIDE_POLY:
401 ui.decidePoly->setText(
"Stop");
402 ui.decidePoly->setEnabled(
true);
405 ui.decidePoly->setChecked(
false);
412 if (
ui.showBF->isChecked())
414 if (
ui.showGreedy->isChecked())
420 if (FrechetViewApplication::instance()->currentAlgorithm()==
421 FrechetViewApplication::ALGORITHM_CURVE)
425 ui.resultCurve->setText(ok ?
"OK":
"no solution");
428 if (FrechetViewApplication::instance()->currentAlgorithm()==
429 FrechetViewApplication::ALGORITHM_POLYGON)
438 if (! std::isnan(
eps))
444 FrechetViewApplication::instance()->setCurrentAlgorithm((FrechetViewApplication::Algorithm)algorithm);
457 if (alg->greedyResult().valid() &&
ui.showGreedy->isChecked()) {
458 ui.showBF->setChecked(
false);
470 int k = alg->optimalResult().k_optimal;
477 FrechetViewApplication::instance()->startKBruteForce();
480 FrechetViewApplication::instance()->cancelBackgroundJob();
484 if (
ui.showBF->isChecked()) {
485 ui.showGreedy->setChecked(
false);
505 setIcon(label,
":/awesome/question-circle.svg",
"solution not yet calculated");
509 setIcon(label,
":/awesome/check-circle.svg",
"found a solution");
512 setIcon(label,
":/awesome/times-circle.svg",
"there is no solution");
519 label->setToolTip(
"calculation in progress");
528 label->setPixmap(icon.pixmap(24,24));
529 label->setToolTip(tooltip);
549 case Qt::Key_PageUp:
pageStep(
ui.epsSlider,+1);
break;
550 case Qt::Key_PageDown:
pageStep(
ui.epsSlider,-1);
break;
static const int DECIMALS
number of decimals in the epsilon control
void onCurveFinished(bool)
called when the curve algorithm finishes; update the "curve" panel to show latest results
void singleStep(QAbstractSlider *, double factor)
perform a single step on a slider
initial status; the algorithm has not ye been run
static QString POLY_STATUS[]
texts to display for algorithm results
void swap(gpuword **A, gpuword **B)
void updateGreedyResult(const k::kAlgorithm::Greedy &kalg)
update results of the k-Frechet greedy algorithm
int k_optimal
optimal value so far
void onBFButton()
called when the user clicks the "Show" button in the "brute-force" section. Triggers showOptimalResul...
global definitions for all algorithms.
int toSliderValue(double x)
map an epsilon value to a slider location
QString toString(double x)
format a number for display, with appropriate locale
Results of the Greedy algorithm.
void onEdit()
called after the user has edited the value of epsilon. Triggers epsilonChanged(), which in turn trigg...
QLabel * movieLabel
label that display the rotating icon
void showIcon(QLabel *label, int status)
show a status icon in the control panel
void onGreedyButton()
called when the user clicks the "Show" button in the "greedy" section. Triggers showGreedyResult(),...
double fromSliderValue(int i)
map a slider location to a value of epsilon
indicates that the algorithm is currently running
void pageStep(QAbstractSlider *, double factor)
perform a page step on a slider
boost::shared_ptr< Algorithm > ptr
(smart) pointer to an Algorithm object
void updatePolyResult()
update the "Polygon" pabel to show the lastest results of the poly-algorithm
void onShowBounds(bool)
called when the user clicks the "Show Bounds" button
double eps
the current value of epsilon
void onAlgorithmChanged(int algorithm)
called when the user selects a algorithm panel. Calls on FrechetViewApplication to update the current...
double eps_step
step size for epsilon slider control
static QMovie * loaderMovie
displays a rotatin icon (during a long-running algorithm)
int k_yx
number of components, when scanning the y-axis first. 0 if the axes can no be covered.
void setEpsilon(double eps, bool notify)
updates the value of epsilon
void setEpsilonWithNotify(double eps)
update the value of epsilon and raise signals
bool curve_was_ok
latest result of the decision algorithm for curves
int k_max
upper bound derived from greedy results. k_max = min{greedy.k_xy,greedy.k_yx}
void saveSettings(QSettings &settings, QString group)
store settings to application preferences
void setIcon(QLabel *label, QString text, QString tooltip="")
show a status icon in the control panel
void updateOptimalResult(const k::kAlgorithm::BruteForce &bfres)
update results of the k-Frechet brute-force algorithm
void restoreSettings(QSettings &settings, QString group)
load settings from application preferences
Ui::ControlPanel ui
UI elements (auto-generated by Qt)
results of the brute-force algorithm
void clearResults()
reset the k-Frechet panel
void showOptimalResult()
raised when the user clicks the "Show" button in the k-Frechet panel. Updates the free-space diagram ...
QDoubleValidator * epsValidator
validator for epsilon input
void wheelEvent(QWheelEvent *) override
Result
negative values for k indicate the special conditions of the computation
QLocale locale
locale used for number formatting
int k_min
lower bound derived from greedy results. k_min = max{greedy.k_x,greedy.k_y}
void epsilonChanged(double eps)
raised when the value of epsilon changes (e.g. when the user operates the slider control)....
boost::shared_ptr< kAlgorithm > ptr
smart pointer to an kAlgorithm object
int k_xy
number of components, when scanning the x-axis first. 0 if the axes can no be covered.
void onSlider(int value)
called when the user moves the slider control for epsilon. Triggers epsilonChanged(),...
void keyPressEvent(QKeyEvent *event) override
void hideResult()
raised when the user clicks the "Hide" button in the k-Frechet panel. Resets the free-space diagram t...
double toDouble(QString text)
parse a number input
there is no solution at all
void updateResults()
update the k-Frechet panel to show the latest results of the k-Frechet algorithm
void setEpsilonMax(double eps_max)
update the maximum value of epsilon; adjusts the slider control
void showGreedyResult()
raised when the user clicks the "Show" button in the k-Frechet panel. Updates the free-space diagram ...