diff options
author | Robert C. Helling <helling@atdotde.de> | 2017-08-28 23:59:58 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2017-08-29 06:49:44 -0700 |
commit | 2832141d2ca00c9ec502f6c4f7ecbb09a2095516 (patch) | |
tree | 999b8435ded4607999907fa4b96fa9071430b4a0 /qt-models/diveplannermodel.cpp | |
parent | e6545a7b0f262d9185a43054f945aa0bc068ac37 (diff) | |
download | subsurface-2832141d2ca00c9ec502f6c4f7ecbb09a2095516.tar.gz |
Compute variations of plans
Print out partial derivatives of stop times with respect to
variation of depth and duratin of last manual segment.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
Diffstat (limited to 'qt-models/diveplannermodel.cpp')
-rw-r--r-- | qt-models/diveplannermodel.cpp | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index 473076586..c0f5598be 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -844,6 +844,7 @@ void DivePlannerPointsModel::createTemporaryPlan() if (recalcQ() && !diveplan_empty(&diveplan)) { struct decostop stoptable[60]; plan(&diveplan, &displayed_dive, DECOTIMESTEP, stoptable, &cache, isPlanner(), false); + computeVariations(); emit calculatedPlanNotes(); } // throw away the cache @@ -869,6 +870,103 @@ void DivePlannerPointsModel::saveDuplicatePlan() createPlan(true); } +struct divedatapoint * DivePlannerPointsModel::cloneDiveplan(struct diveplan *plan_copy) +{ + divedatapoint *src, *last_segment; + divedatapoint **dp; + + src = diveplan.dp; + *plan_copy = diveplan; + dp = &plan_copy->dp; + while (src && (!src->time || src->entered)) { + *dp = (struct divedatapoint *)malloc(sizeof(struct divedatapoint)); + **dp = *src; + dp = &(*dp)->next; + src = src->next; + } + (*dp) = NULL; + + last_segment = plan_copy->dp; + while (last_segment->next->next) + last_segment = last_segment->next; + return last_segment; +} + +void DivePlannerPointsModel::analyzeVariations(struct decostop *min, struct decostop *mid, struct decostop *max, const char *unit) +{ + int leftsum = 0; + int rightsum = 0; + while (mid->depth > min->depth) + ++mid; + while (max->depth > mid->depth) + ++max; + + while (mid->depth) { + int left = mid->time - min->time; + leftsum += left; + int right = max->time - mid->time; + rightsum += right; + if (min->time + mid->time + max->time) + printf("%dm: %dmin + %ds/%s +- %ds/%s\n", mid->depth / 1000, + (mid->time + 1)/60, + (left + right) / 2, unit, + (right - left) / 2, unit); + ++min; + ++mid; + ++max; + } + printf("Total + %d:%02d/%s +- %d:%02d/%s\n\n", FRACTION((leftsum + rightsum) / 2, 60), unit, + FRACTION((rightsum - leftsum) / 2, 60), unit); +} + +void DivePlannerPointsModel::computeVariations() +{ + bool oldRecalc = setRecalc(false); + struct dive *dive = alloc_dive(); + copy_dive(&displayed_dive, dive); + struct decostop original[60], deeper[60], shallower[60], shorter[60], longer[60]; + struct deco_state *cache = NULL, *save = NULL; + struct diveplan plan_copy; + struct divedatapoint *last_segment; + + cache_deco_state(&save); + cloneDiveplan(&plan_copy); + plan(&plan_copy, dive, 1, original, &cache, true, false); + free_dps(&plan_copy); + restore_deco_state(save, false); + + last_segment = cloneDiveplan(&plan_copy); + last_segment->depth.mm += 1000; + last_segment->next->depth.mm += 1000; + plan(&plan_copy, dive, 1, deeper, &cache, true, false); + free_dps(&plan_copy); + restore_deco_state(save, false); + + last_segment = cloneDiveplan(&plan_copy); + last_segment->depth.mm -= 1000; + last_segment->next->depth.mm -= 1000; + plan(&plan_copy, dive, 1, shallower, &cache, true, false); + free_dps(&plan_copy); + restore_deco_state(save, false); + + last_segment = cloneDiveplan(&plan_copy); + last_segment->next->time += 60; + plan(&plan_copy, dive, 1, longer, &cache, true, false); + free_dps(&plan_copy); + restore_deco_state(save, false); + + last_segment = cloneDiveplan(&plan_copy); + last_segment->next->time -= 60; + plan(&plan_copy, dive, 1, shorter, &cache, true, false); + free_dps(&plan_copy); + restore_deco_state(save, false); + + printf("\n\n"); + analyzeVariations(shallower, original, deeper, "m"); + analyzeVariations(shorter, original, longer, "min"); + setRecalc(oldRecalc); +} + void DivePlannerPointsModel::createPlan(bool replanCopy) { // Ok, so, here the diveplan creates a dive |