;+ ; ;spd_ui_draw_object method: niceNum ; ;Function adapted from Graphics Gems: ;Heckbert, Paul S., Nice Numbers for Graph Labels, Graphics Gems, p. 61-63, code: p. 657-659 ;It identifies the closest "nice" number ;Nice being a number j * 10 ^ n where j = 1,2,5,10 and n = any integer ; ;Inputs: ; n(double): The number for which the nearest nicenum is being found ; ; floor(optional,boolean keyword): The routine picks the nearest nicenum below n ; ; ceil(optional,boolean keyword): The routine picks the nearest nicenum above n ; ; factors(optional, array of numeric types): rather than using 1,2,5,10, pass an array ; of alternate values. Common inputs are ; [1,2,3,4,5,6,7,8,9,10], or [1,2,3,6,10] ; ; bias(optional,long): Some sets of factors may entail looking at the first 2 or D ; digits of the nearest nicenum, rather than just the first. ; If this is the case, this argument should be set to instruct ; this algorithm to look at 2 digits. For example, if ; factors = dindgen(101), bias should be 1, if factors = dindgen(1001) ; bias should be 2. The default is 0 ; Outputs: ; factor_index(long): this returns an index into the factor_array indicating which ; factor actually got selected. For example: If nicenum = 2, then ; factor_index = 1 ; ; Returns: ; The nicenum that was found ; ;NOTES: ; Default behavior is to find the nearest nicenum above or below N, but the algorithm from ; graphics gems could only approximate this somewhat roughly. So instead, two calls one ; with /floor and one with /ceil is made by the calling routine and the called decides ; which result is closest. ; ;factor_index: The index of the factor that will be used for the result.(ie different j's) ; ;$LastChangedBy: jimm $ ;$LastChangedDate: 2014-02-11 10:54:32 -0800 (Tue, 11 Feb 2014) $ ;$LastChangedRevision: 14326 $ ;$URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/spdsoft/tags/spedas_5_0/spedas_gui/display/draw_object/spd_ui_draw_object__nicenum.pro $ ;- function spd_ui_draw_object::niceNum,n,floor=floor,ceil=ceil,factors=factors,bias=bias,factor_index=factor_index compile_opt idl2,hidden ;factors = dindgen(100)+1 ; factors = [1,2,5,10] ;this input used to determine the values that ;the leading digit(s) should snap to if ~keyword_set(factors) then begin factors = [1,2,3,4,5,6,7,8,9,10] endif ;If the algorithm should consider more than 1 digit ;This value should grow(bias = 1 => 2 digits considered) if ~keyword_set(bias) then begin bias = 0 endif exponent = floor(alog10(n)) f = n/(10D^(exponent-bias)) ;For each variant of the operation, ;it loops through and finds the "nearest" factor ;Then puts the output at the correct order of magnitude. ;This could probably be vectorized, but I don't think ;that it is taking a lot of runtime. ;this version performs a floored operation if keyword_set(floor) then begin for i = 0,n_elements(factors)-1 do begin if i eq n_elements(factors)-1 || $ f lt factors[i+1] then begin nf = factors[i] break endif endfor endif else if keyword_set(ceil) then begin for i = 0,n_elements(factors)-1 do begin if i eq n_elements(factors)-1 || $ f le factors[i] then begin nf = factors[i] break endif endfor endif else begin for i = 0,n_elements(factors)-1 do begin if i eq n_elements(factors)-1 || $ f lt (factors[i] + factors[i+1])/2D then begin nf = factors[i] break endif endfor endelse factor_index = i return, nf*(10D^(exponent-bias)) end