2008-10-25 26 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; 
}