数学从级别堆栈获得相对比例 [英] Math to get relative scale from level stack

查看:79
本文介绍了数学从级别堆栈获得相对比例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



说我有5个图像级别,每个级别是上一级:




  • 级别1 = 100px square

  • 级别2 = 200px square

  • 等级3 = 400px square

  • 等级4 = 800px square

  • 等级5 = 1600px square



这些图像水平都显示相同的东西,但具有不同程度的细节(最小的图像仅显示主要特征;最大的图像显示精细的细节)。 / p>

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



假设用户在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. 按<$ c的大小划分 newSize $ C> targetLevel 。这是相对比例。

现在让我说我实际上并不知道图像的实际尺寸,而且没有办法得到他们,也许他们的确不是他们应该的大小(尽管他们总是会重复出现前一个级别的两倍),并且可能有任意数量的级别。



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



更多示例...




  • 级别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

解决方案

你的等级可以通过以下指数函数定义(级别从1开始):



为简单起见,我们假设你有(比例)和你试图找到。



看看如何定义,你可以看到





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





这意味着和



现在我们有了新的等级,我们有以下等式:









/ edit

是的,这就是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);

我们必须使用更改基数对数公式,因为 数学 仅提供 log e log 10 。为 Math.log(2)创建常量可能是值得的,因此您不会经常重新计算它。


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 (Android), I think it's pretty general and applicable to any language. Psuedo-code (or just plain English) replies are welcome. I wasn't sure if I should just tag all the common languages, but that seemed a little spammy.

My actual requirement is a little less simply structured than some of the examples that follow, but I'll try to present the idea simply and clearly.

Say I've got 5 "image levels", each level is double the size of the previous level:

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

These image levels all show the same thing but with varying degree of detail (the smallest image shows only major features; the largest image shows fine detail).

Assume we never want to scale an image larger to avoid distortion, and should only perform transforms on an image that make it smaller, the goal being to use the largest appropriate image with the least amount of scaling.

Say a user is on level 3 (400px) and performs a scale operation to 1.8. The new size would be (1.8 * 400 = 720), which means I should show level 4 (800px), scaled to 0.9 (800 * 0.9 = 720).

Another example - a user is on level 2 and scales to 5.2. Size would be (5.2 * 200 = 1040). So show level 5, scaled to 0.65 (1600 * 0.65 = 1040).

Knowing the sizes of the levels, the logic is pretty simple.

  1. Take the size of the current level, multiply it by the user scale. Call this newSize
  2. Find the lowest level whose size is larger than that number. Call this targetLevel
  3. Divide newSize by the size of the targetLevel. This is the relative scale.

Now let's say I don't actually know the actual sizes of the images, and there's no way to get to them, and perhaps they're not really exactly the size they should be (although they will always respresent double the previous level), and there might be any number of levels.

Using just the current level, and the user-defined scale value, what math or logic is involved in getting back the appropriate destination level and it's relative (new) scale?

More examples...

  • User on Level 5 scales to 0.2. New Level should be 3, new scale should be 0.8
  • User on Level 1 scales to 3.6. New Level should be 3, new scale should be 0.9
  • User on Level 1 scales to 5.0. New level should be 4, new scale should be 0.625
  • User on Level 2 scales to 5.0. New level should be 5, new scale should be 0.625
  • User on Level 3 scales to 3.0. New level should be 5, new scale should be 0.75
  • User on Level 4 scales to 0.3. New level should be 3, new scale should be 0.6
  • User on Level 4 scales to 1.6. New level should be 5, new scale should be 0.8
  • User on Level 4 scales to 0.6. New level should be 4, new scale should be 0.6 [1]

[1] probably obvious, but anything less than 1 but greater than 0.5 would stay the same

TYIA

解决方案

Your "levels" can be defined by the following exponential function (with your levels starting at 1):

For simplicity, let's assume you have (scale) and and you're trying to find .

Seeing how is defined, you can see that

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):

Which means that and

Now that we have the new level, we have the following equation:



/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.

这篇关于数学从级别堆栈获得相对比例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆