mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-19 16:57:31 +01:00
[apps] Add a proof for CurveViewRange::computeGridUnit's algorithm
This commit is contained in:
@@ -27,15 +27,99 @@ float CurveViewRange::computeGridUnit(Axis axis, float min, float max) {
|
||||
constexpr int unitsCount = 3;
|
||||
float units[unitsCount] = {k_smallGridUnitMantissa, k_mediumGridUnitMantissa, k_largeGridUnitMantissa};
|
||||
for (int k = 0; k < unitsCount; k++) {
|
||||
float unit = units[k];
|
||||
int b1 = std::floor(std::log10(d/(unit*maxNumberOfUnits)));
|
||||
int b2 = std::floor(std::log10(d/(unit*minNumberOfUnits)));
|
||||
float currentA = units[k];
|
||||
int b1 = std::floor(std::log10(d/(currentA*maxNumberOfUnits)));
|
||||
int b2 = std::floor(std::log10(d/(currentA*minNumberOfUnits)));
|
||||
if (b1 != b2) {
|
||||
b = b2;
|
||||
a = unit;
|
||||
a = currentA;
|
||||
}
|
||||
}
|
||||
return a*std::pow(10.0f,b);
|
||||
|
||||
/* Proof of the algorithm:
|
||||
*
|
||||
* We want to find gridUnit = a*10^b, with a in {1; 2; 5} and b an integer
|
||||
* We want: minNumberOfUnits <= range/gridUnit < maxNumberOfUnits
|
||||
*
|
||||
* A solution thus needs to verify:
|
||||
*
|
||||
* minNumberOfUnits/range <= 1/(a*10^b) < maxNumberOfUnits/range
|
||||
* => range/minNumberOfUnits >= a*10^b > range/maxNumberOfUnits
|
||||
* => range/(a*minNumberOfUnits) >= 10^b > range/(a*maxNumberOfUnits)
|
||||
* => log10(range/(a*minNumberOfUnits)) >= b > log10(range/(a*maxNumberOfUnits))
|
||||
* => (1) log10(range/(a*maxNumberOfUnits)) < b <= log10(range/(a*minNumberOfUnits))
|
||||
* And, because b must be an integer,
|
||||
* => floor(log10(range/(a*maxNumberOfUnits))) != floor(log10(range/(a*minNumberOfUnits)))
|
||||
* The solution is then b = floor(log10(range/(a*minNumberOfUnits)))
|
||||
*
|
||||
* Is there always at least one solution ?
|
||||
*
|
||||
* (1) also gives:
|
||||
* E1 = log10(range)-log10(a)-log10(maxNumberOfUnits) < b <= log10(range)-log10(a)-log10(maxNumberOfUnits) = E2
|
||||
*
|
||||
* Let's compute E2-E1:
|
||||
* E2-E1 = log10(maxNumberOfUnits) - log10(minNumberOfUnits)
|
||||
* For minNumberOfUnits=7 and maxNumberOfUnits=18, E2-E1 = 0.41...
|
||||
* For minNumberOfUnits=5 and maxNumberOfUnits=13, E2-E1 = 0.41...
|
||||
*
|
||||
* Let's compute the union of the [E1;E2] for a in {1; 2; 5}:
|
||||
* [E1;E2 for a=1] U [E1;E2 for a=2] U [E1;E2 for a=5]
|
||||
* = [e1;e2] U [e1-log10(2); e2-log10(2)] U [e1-log10(5); e2-log10(5)]
|
||||
* = [e1;e2] U [e1-0.3; e2-0.3] U [e1-0.7; e2-0.7]
|
||||
* = [e1-0.7; e2-0.7] U [e1-0.3; e2-0.3] U [e1;e2]
|
||||
* = [e1-0.7; e2] because e2-0.7 > e1-0.3 as e2-e1 > 0.7-0.3 and e2-e1 = E2-E1 = 0.41...
|
||||
* and e2-0.3 > e1 as e2-e1 > 0.3
|
||||
*
|
||||
* The union of the [E1;E2] for a in {1; 2; 5} is an interval of size
|
||||
* e2-e1+0.7 = 1.1 > 1.
|
||||
* We will thus always have at least one a in {1; 2; 5} for which E1 and E2
|
||||
* are on each side of an integer.
|
||||
*
|
||||
* Let's make a drawing.
|
||||
*
|
||||
* n n+1 n+2 n+3 n+4 n+5
|
||||
* |.........|.........|.........|.........|.........|...
|
||||
* E1^---^E2
|
||||
* 0.41
|
||||
* *
|
||||
* To have a solution, we need E1 and E2 to be on each side of an integer.
|
||||
*
|
||||
* --------------------------------------------------------------------------------------------
|
||||
* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* If e1 - floor(e1) > 1-(e2-e1) = 0.58..., a=1 is a solution
|
||||
*
|
||||
* n n+0.2 n+0.4 n+0.6 n+0.8 n+1
|
||||
* .........||....|....|....|....|....|....|....|....|....|....||... a=1
|
||||
* e1^--------------------^e2
|
||||
*
|
||||
* --------------------------------------------------------------------------------------------
|
||||
* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* If log10(5)-(e2-e1) = 0.29... < e1 - floor(e1) < log10(5) = 0.69..., a=5 is a solution
|
||||
*
|
||||
* n n+0.2 n+0.4 n+0.6 n+0.8 n+1
|
||||
* .........||....|....|....|....|....|....|....|....|....|....||...
|
||||
* e1^--------------------^e2
|
||||
*
|
||||
* n n+0.2 n+0.4 n+0.6 n+0.8 n+1
|
||||
* .........||....|....|....|....|....|....|....|....|....|....||... a=5
|
||||
* E1^--------------------^E2 <- shift by log10(5) = 0.7
|
||||
*
|
||||
* --------------------------------------------------------------------------------------------
|
||||
* --------------------------------------------------------------------------------------------
|
||||
*
|
||||
* If e1 - floor(e1) < log10(2) = 0.3..., a=2 is a solution
|
||||
* n n+0.2 n+0.4 n+0.6 n+0.8 n+1
|
||||
* .........||....|....|....|....|....|....|....|....|....|....||...
|
||||
* e1^--------------------^e2
|
||||
*
|
||||
* n n+0.2 n+0.4 n+0.6 n+0.8 n+1
|
||||
* .........||....|....|....|....|....|....|....|....|....|....||... a=2
|
||||
* E1^--------------------^E2 <- shift by log10(2) = 0.3
|
||||
*
|
||||
* */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user