数学从级别堆栈获得相对比例

时间:2012-02-12 04:34:18

标签: java math

为可怕的头衔道歉。我花了10分钟试图用一句话解释这一点而失败了。

虽然提示这个问题的应用程序是在Java(Android)中,但我认为它非常通用且适用于任何语言。 Psuedo-code(或简单的英语)回复是受欢迎的。我不确定我是否应该只标记所有常用语言,但这似乎有点垃圾。

我的实际要求与以下一些示例的结构相比有点简单,但我会尝试简单明了地提出这个想法。

假设我有5个“图像级别”,每个级别是前一级别的两倍:

  • 1级= 100px square
  • 2级= 200px square
  • 等级3 = 400px square
  • 等级4 = 800px square
  • 等级5 = 1600px square

这些图像级别都显示相同的内容,但具有不同程度的细节(最小的图像仅显示主要特征;最大的图像显示精细的细节)。

假设我们从不想缩放较大的图像以避免失真,并且只应对图像进行变换以使其变小,目标是使用最小的缩放量的最大适当图像。

假设用户处于第3级(400px)并执行缩放操作至1.8。新的大小将是(1.8 * 400 = 720),这意味着我应该显示4级(800px),缩放到0.9(800 * 0.9 = 720)。

另一个例子 - 用户在2级并且扩展到5.2。大小将是(5.2 * 200 = 1040)。所以显示等级5,缩放到0.65(1600 * 0.65 = 1040)。

了解关卡的大小,逻辑非常简单。

  1. 获取当前级别的大小,将其乘以用户比例。请拨打此newSize
  2. 找到尺寸大于该数字的最低级别。请拨打此targetLevel
  3. newSize除以targetLevel的大小。这是相对比例。
  4. 现在让我说我实际上并不知道图像的实际大小,并且没有办法找到它们,也许它们的确不是它们应该具有的大小(尽管它们总是会呈现出之前的两倍)级别),可能有任何级别。

    仅使用当前级别和用户定义的比例值,获取适当的目标级别及其相对(新)比例所涉及的数学或逻辑是什么?

    更多例子......

    • 级别5上的用户缩放为0.2。新级别应为3,新级别应为0.8
    • 级别1上的用户扩展到3.6。新级别应为3,新级别应为0.9
    • 级别1上的用户扩展到5.0。新等级应为4,新等级应为0.625
    • 级别2上的用户扩展到5.0。新等级应为5,新等级应为0.625
    • 级别3上的用户扩展到3.0。新等级应为5,新等级应为0.75
    • 级别4上的用户缩放到0.3。新的水平应该是3,新的水平应该是0.6
    • 级别4上的用户扩展到1.6。新的水平应该是5,新的水平应该是0.8
    • 级别4上的用户缩放到0.6。新等级应为4,新等级应为0.6 [1]

    [1]可能很明显,但任何小于1但大于0.5的东西都会保持不变

    TYIA

3 个答案:

答案 0 :(得分:3)

您的“等级”可以通过以下指数函数定义(等级从1开始):
level(x) = baseSize * 2<sup>x-1</sup>

为简单起见,我们假设您有s<sub>x</sub>(比例)和level(x),而您正试图找到level(y)

了解如何定义level(x),您可以看到

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

但是,你的比例并不像2那样以2的整齐权力给出,所以你可以找到一个具有以下内容(根据你的场景进行四舍五入):

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

这意味着y = x + ⌈log<sub>2</sub>(s<sub>x</sub>)⌉level(y) = 2<sup>⌈log<sub>2</sub>(s<sub>x</sub>)⌉</sup> * level(x)

现在我们有了新的水平,我们有以下等式:
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>

/编辑
是的,这就是2 x-1 的含义。

  • s x 只是一些与x一致的常量(在这种情况下它是你的比例),同样,s y 是一个与y一起的常量。

  • 只有顶部位(⌈⌈)的奇怪方括号只是天花板功能(Math.ceil)。

  • 对数是取幂的倒数。对数定义如下:如果 c = b,则log a (b)= c。例如,log 2 (8)= 3,因为2 3 = 8.还有其他令人困惑的事吗?

/ java sample

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

我们必须使用change of base公式作为对数,因为Math仅提供logelog10。为Math.log(2)创建常量可能是值得的,因此您不会经常重新计算它。

答案 1 :(得分:1)

这个简单的matching game使用enum Game来指定游戏四个级别所需的常量。通过覆盖toString()(并略微违反常量的大小写惯例),可以使用Game.values()直接填充级别选择gameCombo。更改级别只需更换组件并在封闭的validate()上调用Container

答案 2 :(得分:0)

到目前为止......

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);
    }