-
Enhancement
-
Resolution: Fixed
-
P3
-
1.2.0, 1.2.1, 1.2.2, 1.4.0
-
b77
-
generic, x86, sparc
-
generic, linux, solaris_2.6
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 ...]
- duplicates
-
JDK-4558900 Pathiterator is inconsistent between GeneralPath and Area objects
-
- Closed
-
-
JDK-4718569 GenralPath rounds coordinates when using Shape with Double.
-
- Closed
-
-
JDK-6297129 AffineTransform.createTransformedShape returns a single precision Shape object
-
- Closed
-
-
JDK-4270230 RFE: insufficient precision in general paths
-
- Closed
-
- relates to
-
JDK-6404847 REGRESSION: GeneralPath.createTransformedShape no longer returns a GeneralPath object
-
- Resolved
-
-
JDK-4632108 Area.transform and Area.createTransformedArea should maintain double precision
-
- Resolved
-