【问题标题】:Math and Java - find an available index from a scale value数学和 Java - 从比例值中查找可用索引
【发布时间】:2012-02-28 20:44:21
【问题描述】:

再次为这个糟糕的标题道歉 - 很难描述。

我使用了 Java 标记,因为这是我在这个项目中使用的语言,但这确实适用于任何语言。

为了清楚起见,我将使用一个简化的示例。

假设我正在显示一个可以“缩放”的图形,并且我可以访问代表比例的 0 到 1 之间的浮点数。

现在假设同一张图有不同的版本,越“特写”的版本显示的细节越精细,而距离越远的版本只显示重要的特征。

每个版本的大小都是下一个较大版本的一半。最特写相当于缩放级别 1。

可能有任意数量的版本,每个版本代表的视图是上一个的二分之一。

因此,当用户缩放图形时,我需要检查他们是否已达到最好显示不同版本的程度。如果他们还没有达到那个点,我只会显示上一个级别的缩小(缩小)版本。

例如,假设有 5 个不同的版本(尽管可能有任何数字),在一个数组中,从最小到最大(尽管如果更容易我可以颠倒这个),所以版本 [4] 是最大的并且版本[0] 是最小的。

例如,

  • 放大 1 倍时,显示版本[4]
  • 以 0.5 倍缩放,显示版本[3]
  • 在 0.25 时,显示版本[2]
  • 在 0.125 时,显示版本[1]
  • 在 0.0625,显示版本[0]

由于没有可用于一半版本 [0] 的版本,我仍会显示版本 [0],但大小只有一半。如果添加了另一个版本,它将显示整体比例(缩放)为 0.03125 或更小的时间。

对于之间的比例,我应该显示下一个最大的图像,但尺寸会缩小。

例如,

  • 缩放为 1 时,我会显示最大的(版本 [4]),未缩放。
  • 在 0.8 的缩放比例下,仍然显示最大的但以 0.8 比例缩放
  • 以 0.5 的缩放比例显示未缩放的版本 [3]
  • 以 0.3 的缩放比例,以 0.6 的比例显示版本 [3]
  • 以 0.2 的缩放比例,以 0.8 的比例显示版本 [2]
  • 以 0.1 的缩放比例,以 0.8 的比例显示版本 [1]

我可能可以将它与条件句、链接和 Math.abs 等一起破解,但我敢打赌,有一种非常优雅、有效的方法可以用纯数学来处理这个问题——这简直让我难以想象。如果没有,任何关于使用干净、可预测的代码的方法的建议也将受到欢迎。

重申 - 目标是找到要显示的版本的版本(数组索引),以及它应该显示的相对比例,完全基于“全局”比例。

TYIA。

【问题讨论】:

    标签: java math


    【解决方案1】:
    int indexToUse = 0-Math.round(Math.log(zoom)/Math.log(2));
    double zoomToUse = zoom/Math.pow(2, -indexToUse);
    

    这使用的信息是每张图像都恰好是前一张图像的 2 倍。这是一个指数尺度,所以它的倒数 log 用于查找要使用的索引。

    之后,您将 2 乘以索引的幂以获得它实际所处的缩放级别,然后将所需的缩放级别除以实际值以获得您的系数。

    (由于您使用的缩放始终介于 0 和 1 之间,因此日志将始终为负数,因此我继续否定它。重新排序图像以适应它可能更容易,或者您可能只想减去从长度来获取您要使用的实际索引。)

    BigMoMo 指出 Java 的 Math.log 是自然日志。此外,正如他所指出的,您可以通过将自然对数除以 2 的自然对数来获得 log2。我在示例代码中反映了这一点。

    为了解决您的第二个问题,

    double getZoom(int index, double zoomOnImage){
        return Math.pow(2, -index) * zoomOnImage;
    }
    

    【讨论】:

    • @bdares 感谢您的回复 - 如果我犯了一个简单的错误,请原谅,但 Math.log 只接受一个参数,对吗?
    • @bdares - 会是 Math.log(zoom) / Math.log(2) 吗?
    • @BigMoMo 你是对的.. 我懒得检查 API,只是敲出一些看起来正确但可能无法编译的代码,就像在中被否定的 indexToUse第二行。
    • @bdares 是的 - 我刚刚运行它并且效果很好 - 就像你说的,它运行相反(从最小到最大),但这没问题 - 就像约翰说的那样,非常令人印象深刻,尤其是在 11从发布时间开始的分钟。非常感谢
    • @bdares 希望我不会在这里碰运气,但是您知道如何倒退(从索引和缩放到缩放)吗?如果您愿意,我可以提出另一个问题
    【解决方案2】:

    如果您尝试使用Google Maps 之类的界面,您会发现它不会连续扩展。相反,它会逐步移动。

    因此,一种方法是只允许用户逐步缩放,并将这些步骤直接映射到各种真实比例的图形版本。您仍然可以以不同的比例显示每组图块,例如

      Zoom  Tileset  Scale
       1       1       0.5
       2       1       1
       3       2       0.25
       4       2       0.5
       5       2       1
       ...
    

    【讨论】:

    • 感谢您的回复,但我必须提供状态之间的平滑插值 - 用户缩放的主要模式是通过捏合手势
    【解决方案3】:

    如果把顺序倒过来像:

    在缩放 1 时,显示版本[0](最大);放大 0.5 倍,显示版本[1];在 0.25,显示版本[2];在 0.125,显示版本[3];在 0.0625,显示版本 [4]; ...

    我们可以清楚地看到索引 i = log(zoom)/log(0.5);或 zoom=pow(0.5, i)。 对于缩放不完全是 0.5 次方的情况,我们只取 ceil 或 integar 部分,例如当zoom=0.4, log(0.4)/log(0.5)=1.32192,那么index应该是1。所以,简单的index就是log(zoom)/log(0.5)的整数部分。

    实际缩放为:zoom/z[i](i为索引,z为缩放数组{1, 0.5, 0.25, 0.125, 0.0625})

    继续上面的例子,对于给定的缩放 0.4,索引 = 1(从上面),最终缩放为:0.4/z[i] = 0.4/z[1] = 0.4/0.5 = 0.8。

    为了在实践/实现中获得索引,您不需要计算 log(x),只需比较缩放值以查看它适合哪个槽/索引(使用某种二进制搜索策略)。找到索引后,通过 zoom/z[i] 计算最终缩放。

    【讨论】:

    • 感谢您的回复。与纯数学解决方案相比,您认为使用您提到的方法有什么优势吗?
    • 首先我只是用数学的方式解释了它。我知道数学方法并且我不反对它:-) 我的意思是为了获得数组的索引,如果我们实现它不需要'log'类型的数学方法,特别是如果有很多级别的缩放。搜索它的位置(比较)应该比在浮动上“记录”操作更有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-30
    • 2014-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    相关资源
    最近更新 更多