| 1348 | } |
| 1349 | |
| 1350 | double Envelope::SolveIntegralOfInverse( double t0, double area ) const |
| 1351 | { |
| 1352 | if(area == 0.0) |
| 1353 | return t0; |
| 1354 | |
| 1355 | const auto count = mEnv.size(); |
| 1356 | if(count == 0) // 'empty' envelope |
| 1357 | return t0 + area * mDefaultValue; |
| 1358 | |
| 1359 | // Correct for offset! |
| 1360 | t0 -= mOffset; |
| 1361 | return mOffset + [&] { |
| 1362 | // Now we can safely assume t0 is relative time! |
| 1363 | double lastT, lastVal; |
| 1364 | int i; // this is the next point to check |
| 1365 | if(t0 < mEnv[0].GetT()) // t0 preceding the first point |
| 1366 | { |
| 1367 | if (area < 0) { |
| 1368 | return t0 + area * mEnv[0].GetVal(); |
| 1369 | } |
| 1370 | else { |
| 1371 | i = 1; |
| 1372 | lastT = mEnv[0].GetT(); |
| 1373 | lastVal = mEnv[0].GetVal(); |
| 1374 | double added = (lastT - t0) / lastVal; |
| 1375 | if(added >= area) |
| 1376 | return t0 + area * mEnv[0].GetVal(); |
| 1377 | area -= added; |
| 1378 | } |
| 1379 | } |
| 1380 | else if(t0 >= mEnv[count - 1].GetT()) // t0 at or following the last point |
| 1381 | { |
| 1382 | if (area < 0) { |
| 1383 | i = (int)count - 2; |
| 1384 | lastT = mEnv[count - 1].GetT(); |
| 1385 | lastVal = mEnv[count - 1].GetVal(); |
| 1386 | double added = (lastT - t0) / lastVal; // negative |
| 1387 | if(added <= area) |
| 1388 | return t0 + area * mEnv[count - 1].GetVal(); |
| 1389 | area -= added; |
| 1390 | } |
| 1391 | else { |
| 1392 | return t0 + area * mEnv[count - 1].GetVal(); |
| 1393 | } |
| 1394 | } |
| 1395 | else // t0 enclosed by points |
| 1396 | { |
| 1397 | // Skip any points that come before t0 using binary search |
| 1398 | int lo, hi; |
| 1399 | BinarySearchForTime(lo, hi, t0); |
| 1400 | lastVal = InterpolatePoints(mEnv[lo].GetVal(), mEnv[hi].GetVal(), (t0 - mEnv[lo].GetT()) / (mEnv[hi].GetT() - mEnv[lo].GetT()), mDB); |
| 1401 | lastT = t0; |
| 1402 | if (area < 0) |
| 1403 | i = lo; |
| 1404 | else |
| 1405 | i = hi; // the point immediately after t0. |
| 1406 | } |
| 1407 |
no test coverage detected