JDK-4718569 : GenralPath rounds coordinates when using Shape with Double.
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.4.0
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2002-07-22
  • Updated: 2006-02-24
  • Resolved: 2006-02-24
Related Reports
Duplicate :  
Description
Name: jk109818			Date: 07/22/2002


FULL PRODUCT VERSION :

robo@zwergstern:~/src/java$ java -version
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)


FULL OPERATING SYSTEM VERSION :
Debian linux. linux kernel 2.4.18
glibc Version: 2.2.5-6

Problem seems to be the same on windows 2000 with jdk/1.4


A DESCRIPTION OF THE PROBLEM :
I create a GeneralPath with 4 Line2D.Double (I create a
rectangle). After this I call getBounds2D on the GeneralPath
and check that the bounds are what I expect. As it is now
the bounds is different from the coordinates entered.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.
Create a file TestGeneralPath.java as given below.

2.
compile the file

3.
run the resulting class.



EXPECTED VERSUS ACTUAL BEHAVIOR :
xmin should be equal to r.xmin.(which is the result of
calling r.getMinX ())
ymin should be equal to r.ymin
xmax should be equal to r.xmax
ymax should be equal to r.ymax

/*********** ACTUAL RESULTS ******************/

robo@zwergstern:~/src/java$ java TestGeneralPath
xmin: 1274316.949063871
ymin: 6397151.433723609
xmax: 1274317.0137960138
ymax: 6397151.517216891
r.xmin: 1274317.0 diff: -0.050936128944158554
r.ymin: 6397151.5 diff: -0.06627639103680849
r.xmax: 1274317.0 diff: 0.013796013779938221
r.ymax: 6397151.5 diff: 0.017216891050338745


Using other values of xmin, ymin, xmax and ymax also seems
to round the r.(x|y)(min|max) the resulting value seems to
be rounded to nearest (?) 0.5.



This bug can be reproduced always.

---------- BEGIN SOURCE ----------
/********* begin file *****************/
import java.awt.geom.*;

public class TestGeneralPath {
    
    public static void main (String[] args) {
	double xmin = 1274316.949063871;
	double ymin = 6397151.433723609;
	double xmax = 1274317.0137960138;
	double ymax = 6397151.517216891;
	
	System.out.println ("xmin: " + xmin);
	System.out.println ("ymin: " + ymin);
	System.out.println ("xmax: " + xmax);
	System.out.println ("ymax: " + ymax);

	// Create a rectangle..
	GeneralPath poly = new GeneralPath ();
	Line2D.Double l = new Line2D.Double (xmin, ymin, xmax, ymin);
	poly.append (l, true);
	l = new Line2D.Double (xmax, ymin, xmax, ymax);
	poly.append (l, true);
	l = new Line2D.Double (xmax, ymax, xmin, ymax);
	poly.append (l, true);
	l = new Line2D.Double (xmin, ymax, xmin, ymin);
	poly.append (l, true);
	
	Rectangle2D r = poly.getBounds2D ();
	System.out.println ("r.xmin: " + r.getMinX () + " diff: " + (xmin - r.getMinX ()));
	System.out.println ("r.ymin: " + r.getMinY () + " diff: " + (ymin - r.getMinY ()));
	System.out.println ("r.xmax: " + r.getMaxX () + " diff: " + (xmax - r.getMaxX ()));
	System.out.println ("r.ymax: " + r.getMaxY () + " diff: " + (ymax - r.getMaxY ()));
    }
    
}
/******************** end file ************/
---------- END SOURCE ----------
(Review ID: 153563) 
======================================================================

Comments
EVALUATION GeneralPath only stores its coordinates with "float" precision. The values used in the test case are near the top of the range in which a float value can maintain sub-pixel precision. As all of the coordinates are rounded to either a .0 or .5 it looks like there is only 1 more bit of mantissa left after the decimal point. GeneralPath cannot do better than this due to its floating point internal representation. A new class that provided double precision would need to be used. There is a request to add a double version of GeneralPath. I am closing this bug as a duplicate of that bug since there is no solution to fix this within the context of the current GeneralPath implementation which only has floating point external API and floating point internal representation.
24-02-2006