Math to get relative scale from level stack

后端 未结 3 1673
清酒与你
清酒与你 2021-01-28 11:18

Apologies for the horrible title. I spent 10 minutes trying to explain this in one sentence and failed.

Although the application prompting this question is in Java (And

相关标签:
3条回答
  • 2021-01-28 11:42

    Your "levels" can be defined by the following exponential function (with your levels starting at 1):
    level(x) = baseSize * 2<sup>x-1</sup>

    For simplicity, let's assume you have s<sub>x</sub> (scale) and level(x) and you're trying to find level(y).

    Seeing how level(x) is defined, you can see that

    2<sup>a</sup> * level(x) = level(x+a)

    However, your scale is not given in neat powers of 2 like that, so you can find a with the following (rounding up as per your scenario):

    ⌈log<sub>2</sub>(s<sub>x</sub>)⌉ = a

    Which means that y = x + ⌈log<sub>2</sub>(s<sub>x</sub>)⌉ and level(y) = 2<sup>⌈log<sub>2</sub>(s<sub>x</sub>)⌉</sup> * level(x)

    Now that we have the new level, we have the following equation:
    s<sub>x</sub> * level(x) = s<sub>y</sub> * level(y)<br>
    s<sub>x</sub> * baseSize * 2<sup>x-1</sup> = s<sub>y</sub> * baseSize * 2<sup>y-1</sup>
    s<sub>x</sub> * 2<sup>x-1</sup> / 2<sup>y-1</sup> = s<sub>y</sub>
    s<sub>x</sub> * 2<sup>x-y</sup> = s<sub>y</sub>

    /edit
    Yes, that's what 2x-1 means.

    • sx is just some constant that goes with x (in this case it's your scale), likewise, sy is some constant that goes with y.

    • The weird square brackets with just the top bit (⌈ ⌉) are just the ceiling function (Math.ceil).

    • Logarithms are the inverse of exponentiation. Logarithms are defined as the following: if ac = b, then loga(b) = c. For instance, log2(8) = 3 because 23 = 8. Is anything else confusing?

    /java sample

    int newLevel = oldLevel + (int) Math.ceil(Math.log(oldScale) / Math.log(2));
    double newScale = oldScale * Math.pow(2, oldLevel - newLevel);

    We have to use the change of base formula for logarithms because Math only provides loge and log10. It might be worthwhile to create a constant for Math.log(2) so you aren't constantly recalculating it.

    0 讨论(0)
  • 2021-01-28 11:44

    so far...

    public static void getZoom(int currentLevel, double userScale){
            double ns = (1 << (currentLevel - 1)) * userScale;
            int newLevel = 1;
            int ts = 1;
            while(ts < ns){
                ts <<= 1;
                newLevel++;
            }
            double newScale = ns / ts;
            System.out.println(newLevel + ", " + newScale);
        }
    
    0 讨论(0)
  • 2021-01-28 11:59

    This simple matching game uses enum Gameto specify the constants needed for the game's four levels. By overriding toString() (and slightly violating the case convention for constants) the Game.values() can be used to populate the level selection gameCombo directly. Changing levels then requires little more than replacing the components and invoking validate() on the enclosing Container.

    0 讨论(0)
提交回复
热议问题