2008-10-25 32 views
19

我正在寻找一种算法,它在轴上放置刻度标记,给定要显示的范围,要显示的宽度以及测量刻度标记的字符串宽度的函数。例如,假设我需要在1e-6和5e-6之间显示一个宽度并以像素为单位显示,那么该算法将确定我应该将tickmarks(例如)放在1e-6,2e-6 ,3e-6,4e-6和5e-6。考虑到较小的宽度,它可能决定最佳位置仅在偶数位置,即2e-6和4e-6(因为放置更多的标记会导致它们重叠)。图形轴的Tickmark算法

智能算法会优先选择10,5和2倍数的刻度标记。此外,智能算法将在零周围对称。

回答

15

检查Paul Heckbert的文章图形宝石上的图形标签的好数字。

Google book preview

+0

这看起来不错,我可以买这本书。 – Nick 2008-10-28 23:17:49

1

取最接近零的分段(或整个图表,如果零不在该范围内) - 例如,如果您有某个范围[-5,1],取[-5,0 ]。

找出该段的大概时间,以蜱为单位。这只是将长度除以勾号的宽度。所以假设该方法说我们可以在-5到0之间插入11个滴答。这是我们的上限。对于较短的一面,我们只是将结果反映在较长的一面。

现在尝试放入尽可能多的(最多11个)刻度,以便每个刻度的标记形式为i * 10 * 10^n,i * 5 * 10^n,i * 2 * 10^n,其中n是一个整数,i是刻度的索引。现在,这是一个优化问题 - 我们希望最大限度地增加可以放入的刻度数量,同时最小化最后一个刻度与结果之间的距离。因此,为得到尽可能多的滴答声而设定一个分数,小于我们的上限,并为最后滴答滴答接近n分配一个分数 - 您必须在这里进行实验。

在上例中,尝试n = 1。我们得到1个刻度(在i = 0时)。 n = 2给我们1滴答,我们离下限越远,所以我们知道我们必须走另一条路。在每个整数点处,n = 0给我们6个滴答声。 n = -1给我们12个刻度(0,-0.5,...,-5.0)。 n = -2给我们24个滴答声,依此类推。评分算法会给他们每个分数 - 更高意味着更好的方法。

再次为i * 5 * 10^n和i * 2 * 10^n做这个,并拿出最好的分数。 (作为一个计分算法的例子,说分数是最后一次滴答时间到滴答的最大数量减去所需数量的距离,这可能是不好的,但它可以作为一个体面的起点) 。

0

我一直在使用jQuery flot图库。它是开源的,轴/刻度生成得很好。我建议看看它的代码,并从那里收集一些想法。

-3

你的开发语言是什么?我在C++中有一个图形控件,它可以很容易地使用对数,celings等组合来解决这个问题。如果你想为你解释代码。

+0

我的开发语言是C#,但我不会介意看到一个C++实现 - 我可以翻译。 – Nick 2008-10-27 17:16:24

0

这个简单的算法产生的间隔是1,2或5倍的10功率和轴范围在至少5周的时间间隔被划分的多个。该代码示例是用Java语言:

protected double calculateInterval(double range) { 
    double x = Math.pow(10.0, Math.floor(Math.log10(range))); 
    if (range/x >= 5) 
     return x; 
    else if (range/(x/2.0) >= 5) 
     return x/2.0; 
    else 
     return x/5.0; 
} 

这是一个另类,最小间隔10:

protected double calculateInterval(double range) { 
    double x = Math.pow(10.0, Math.floor(Math.log10(range))); 
    if (range/(x/2.0) >= 10) 
     return x/2.0; 
    else if (range/(x/5.0) >= 10) 
     return x/5.0; 
    else 
     return x/10.0; 
}