JDK-4172661 : GeneralPath needs double version
  • Type: Enhancement
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 1.2.0,1.2.1,1.2.2,1.4.0
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,linux,solaris_2.6
  • CPU: generic,x86,sparc
  • Submitted: 1998-09-10
  • Updated: 2017-05-16
  • Resolved: 2006-03-22
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b77Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Description
Name: clC74495			Date: 09/10/98


The GeneralPath and Area classes offer one of the most powerful
GIS platforms available anywhere today, except for one problem:
float is not sufficiently precise to use for global coordinate models
(eg a float Longitude has a precision of about 3 meters, far too coarse
for modern GIS). GeneralPath needs a double version, just like the
float and double versions of Line2D, Rectangle2D etc.
(Review ID: 37513)
======================================================================
Suggested implementation by java.net member leouser
(Refer to attached file "4172661-Fix-Received.eml" for the entire text)

FIX DETAILS
BUG ID: 4172661 GeneralPath needs double version
FILES AFFECTED: java.awt.geom package, java.awt.geom.GeneralPath class
 JDK VERSION
 jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin


Discusion(embeded in test case as well):
/**
 * BUG ID: 4172661 GeneralPath needs double version
 * This has proven to be a vexing problem to solve.  I first looked
 * at it from a storage standpoint: maybe I can just make a Storage
 * class internal to the GeneralPath and have the GP morph its storage
 * dependant upon how the user wanted to use it.  This road proved bad.
 * There is not a good way to perform operations on a float array when
 * you are targeting a double array anc vice versa.  We could have set
 * up a flag and have the thing process differently but the code would
 * have been grotesque and repetitive.
 *
 * I thought about using generics for a solution but there is not a good way
 * to bound it to only accept Float and Double.  There are other issues to,
 * but that is the main one that I see as blocking it.
 *
 * Therefore I moved into looking at solution 3: refactoring out a superclass
 * called AbstractGeneralPath and deriving GeneralPath from it.  This wasn't
 * too difficult of a chore.  Many a method could be swapped up if a much
 * smaller utility method was implemented.  After pushing as much that seems
 * reasonable upwards I created the DoubleGeneralPath.  The DoubleGeneralPath
 * is a mirror image of the GeneralPath in terms of implementation.  The variation
 * is in swapping double for float --> and that's almost it!  Hence we have
 * 2 files with 500+ lines of quasi code duplication.  I say quasi because
 * they look the same, but when you are operating on double arrays and
 * float arrays they are different pieces of code.  Their essence is what is
 * similar.
 *
 * All of this goes back to the statement: "Unfortunately it is difficult to 
 * figure out how to integrate this new capability into the existing class
 * structure...".  Yes, as I have digged it has certainly proven difficult.
 * Then again, the mirrors are just 10 methods in each class.  On counting
 * 17 methods were able to be moved upward as well as a whole slew of fields.
 * So roughly 2/3rds of the GeneralPath could be turned into an AbstractGeneralPath.
 *
 * I have considered making the two swappable with each other.  But this would
 * entail making the AbstractGeneralPath public and adding a bunch of useless
 * mirror methods to each of the classes.  From reading the remarks in the
 * RFE report it seems the users don't want to use the GeneralPath at all
 * because of its float implementation.  The DoubleGeneralPath could be the
 * preferred solution for them.
 *
 * WHY THE NAME?  Well because I haven't come up with a better one!  We could
 * try: DBLGeneralPath, DGeneralPath, GeneralPathD, DoubleBackedGeneralPath,
 * etc... but these are worse
 * than DoubleGeneralPath.  At least with DoubleGeneralPath you think to yourself
 * hmmm Double, oh yeah double.  With the others you think what does D stand for?
 *
 * ANTI-RATIONALE:
 * This adds another public class to the awt.geom package.  The new class
 * does not mirror the structure of other Double/Float pairs in this package,
 * making it harder to remember.  It also adds 2 non-public classes to the
 * package making the file count larger.  Given these, I don't believe any
 * of this is avoidable.  Im not sure if it is even possible if we started
 * from scratch to design these things like the others.  That's something
 * I have to contemplate.
 *
 * TESTING STRATEGY:
 * 1. Create a visual test.  We compare the doodles rendered by GeneralPath
 * and DoubleGeneralPath by iterating through a cycle of these two.  The
 * doodles should appear the same.  We create the Paths by lineTo, curveTo
 * and quadTo.
 * 2. Exercise methods on the DGP and GP interface.
 * This test class is probably going to expand as time goes on.  When you
 * look at all the things that have changed it becomes apparent that doodle
 * testing isn't going to be enough.  It would be nice to the see a visual
 * test that can show off the differences between double and float.  Right
 * now the tests don't illustrate this... .
 *
 * FILES AFFECTED: java.awt.geom package, java.awt.geom.GeneralPath class
 *
 * JDK VERSION
 * jdk-6-rc-bin-b64-linux-i586-15_dec_2005.bin
 *
 * test ran succesfully on a SUSE 7.3 Linux distribution
 *
 * Brian Harry
 * ###@###.###
 * Jan 19, 2006
 *
 */

CODE(DIFFS FIRST, then new files):

--- /home/nstuff/java6/jdk1.6.0/java/awt/geom/GeneralPath.java	Thu Dec 15 02:16:27 2005
+++ /home/javarefs/java/awt/geom/GeneralPath.java	Thu Jan 19 12:21:09 2006
@@ -33,39 +33,15 @@
[... snip ...]

Comments
EVALUATION The contributed fix was reviewed and we decided to go with a slightly modified version of the contributed fix. We introduced a new parent class that more closely resembles the design of the existing classes in the java.awt.geom package: Path2D / \ Float Double | GeneralPath GeneralPath becomes a "legacy class", but maintains the same exact API as it originally had with the addition of inheriting (and implementing via its Float parent) double versions of all of its path construction methods from the base Path2D class.
09-03-2006

EVALUATION Contribution-forum:https://jdk-collaboration.dev.java.net/servlets/ProjectForumMessageView?forumID=1463&messageID=10989
23-01-2006

EVALUATION This is a frequent request. Unfortunately it is difficult to figure out how to integrate this new capability into the existing class structure since GeneralPath doesn't follow the regular 2D.{Float,Double} class design of java.awt.geom. We don't have any resources to solve this right now either, unfortunately. jim.graham@Eng 2000-09-27 Two more floating point precision issues have been identified. See 4632108 which discusses float precision issues when transforming Area objects (even though they have double precision internally they depend on other mechanisms for the transformation which do not have double precision). Also see 6297129 which discusses float precision issues in the AffineTransform class in its createTransformedShape method which uses a GeneralPath object to store the transformed geometry. That bug cannot be fixed until this bug is addressed. ###@###.### 2005-07-15 00:55:10 GMT
15-07-2005