From 5f722a9c5b701589fb204a00dc798037589d82bd Mon Sep 17 00:00:00 2001 From: Mark Taylor Date: Thu, 29 Jan 2015 15:54:02 +0000 Subject: [PATCH] ttools: report SliderSpecifier value without spurious precision --- .../uk/ac/starlink/ttools/plot2/PlotUtil.java | 35 +++++++++++++++++++ .../ttools/plot2/config/SliderSpecifier.java | 29 ++++++++++++++- .../ttools/plot2/geom/PlaneSurface.java | 28 ++------------- 3 files changed, 65 insertions(+), 27 deletions(-) diff --git a/ttools/src/main/uk/ac/starlink/ttools/plot2/PlotUtil.java b/ttools/src/main/uk/ac/starlink/ttools/plot2/PlotUtil.java index dbc0c476c6..c96db70942 100644 --- a/ttools/src/main/uk/ac/starlink/ttools/plot2/PlotUtil.java +++ b/ttools/src/main/uk/ac/starlink/ttools/plot2/PlotUtil.java @@ -658,6 +658,41 @@ public static String formatNumber( double value, String baseFmt, return fmt.format( value ); } + /** + * Formats a number so that it presents a number of significant figures + * corresponding to a supplied small difference. + * The idea is that the output should be compact, but that applying + * this function to value and value+epsilon should give visibly + * different results. The number of significant figures is determined + * by epsilon, not further rounded (trailing zeroes are not truncated). + * + * @param value value to format + * @param epsilon small value + * @return formatted value + */ + public static String formatNumber( double value, double epsilon ) { + epsilon = Math.abs( epsilon ); + + /* Work out the number of significant figures. */ + double aval = Math.abs( value ); + int nsf = + Math.max( 0, (int) Math.round( -Math.log10( epsilon / aval ) ) ); + + /* Return a formatted string on this basis. */ + if ( aval >= 1e6 || aval <= 1e-4 ) { + return formatNumber( value, "0.#E0", nsf ); + } + else if ( epsilon >= 0.9 ) { + return Long.toString( (long) Math.round( value ) ); + } + else { + int ndp = (int) Math.round( Math.max( 0, -Math.log10( epsilon ) ) ); + return ndp == 0 + ? Long.toString( (long) Math.round( value ) ) + : formatNumber( value, "0.0", ndp ); + } + } + /** * Returns the rectangle that results from removing the insets from * a given rectangle. diff --git a/ttools/src/main/uk/ac/starlink/ttools/plot2/config/SliderSpecifier.java b/ttools/src/main/uk/ac/starlink/ttools/plot2/config/SliderSpecifier.java index ee0a562045..08785bdf1e 100644 --- a/ttools/src/main/uk/ac/starlink/ttools/plot2/config/SliderSpecifier.java +++ b/ttools/src/main/uk/ac/starlink/ttools/plot2/config/SliderSpecifier.java @@ -16,6 +16,7 @@ import javax.swing.JTextField; import javax.swing.event.ChangeListener; import uk.ac.starlink.ttools.gui.ResourceIcon; +import uk.ac.starlink.ttools.plot2.PlotUtil; /** * Double value specifier that uses a slider to choose a value in the @@ -197,7 +198,33 @@ public double getTextValue() { * @return slider value */ public double getSliderValue() { - return scale( slider_.getValue() ); + int i0 = slider_.getValue(); + double d0 = scale( i0 ); + + /* For cosmetic reasons, try to round the value to a round number + * corresponding to the nearest pixel so that reporting the + * value as text does not include spurious (and ugly) precision. + * We do it by formatting the value using a pixel-sized value delta, + * and turning that formatted value back into a number. */ + int npix = slider_.getOrientation() == JSlider.HORIZONTAL + ? slider_.getWidth() + : slider_.getHeight(); + if ( npix > 10 ) { + int iPixStep = ( slider_.getMaximum() - slider_.getMinimum() ) + / npix; + double dPixStep = Math.abs( scale( i0 + iPixStep ) - d0 ); + if ( dPixStep > 0 ) { + String numstr = PlotUtil.formatNumber( d0, dPixStep ); + try { + return Double.parseDouble( numstr ); + } + catch ( NumberFormatException e ) { + } + } + } + + /* If something went wrong, it's OK to use the exact value. */ + return d0; } /** diff --git a/ttools/src/main/uk/ac/starlink/ttools/plot2/geom/PlaneSurface.java b/ttools/src/main/uk/ac/starlink/ttools/plot2/geom/PlaneSurface.java index ba005893a8..39426c1d42 100644 --- a/ttools/src/main/uk/ac/starlink/ttools/plot2/geom/PlaneSurface.java +++ b/ttools/src/main/uk/ac/starlink/ttools/plot2/geom/PlaneSurface.java @@ -500,31 +500,7 @@ public static String formatPosition( Axis axis, double dpos ) { /* Work out pixel size in data coordinates by looking at the * data position of a point two pixels away. */ - double dp2 = - axis.graphicsToData( (int) axis.dataToGraphics( dpos ) + 2 ); - double prec = Math.abs( dp2 - dpos ) / 2.; - - /* Work out the number of significant figures. */ - double aval = Math.abs( dpos ); - int nsf = - Math.max( 0, (int) Math.round( -Math.log10( prec / aval ) ) ); - - /* Return a formatted string on this basis. */ - if ( aval >= 1e6 || aval <= 1e-4 ) { - return PlotUtil.formatNumber( dpos, "0.#E0", nsf ); - } - else if ( prec >= 0.9 ) { - return Long.toString( (long) Math.round( dpos ) ); - } - else { - int ndp = - (int) Math.round( Math.max( 0, -Math.log10( prec ) ) ); - if ( ndp == 0 ) { - return Long.toString( (long) Math.round( dpos ) ); - } - else { - return PlotUtil.formatNumber( dpos, "0.0", ndp ); - } - } + double dp2 = axis.graphicsToData( axis.dataToGraphics( dpos ) + 2 ); + return PlotUtil.formatNumber( dpos, Math.abs( dp2 - dpos ) / 2. ); } }