Skip to main content

Converting between winding modes

4 replies [Last post]
Anonymous

I need to be able to convert a Shape described by a WIND_NON_ZERO
PathIterator into WIND_EVEN_ODD. Obviously some Java code that does this
would be great, but a pointer to a nice algorithm would be appreciated
too. So far I have found this:
http://www.n-n-a.com/topic.php?p=1900-913-1

Not as important, but I'm also interested in PathIterator-based Java
code for converting cubic beziers to quadratic beziers via subdivision.

Thanks,
Chris

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Chris Nokleberg

On Wed, Feb 22, 2006 at 06:30:25PM -0800, Chris Nokleberg wrote:
> I need to be able to convert a Shape described by a WIND_NON_ZERO
> PathIterator into WIND_EVEN_ODD. Obviously some Java code that does this
> would be great, but a pointer to a nice algorithm would be appreciated
> too. So far I have found this:
> http://www.n-n-a.com/topic.php?p=1900-913-1

For the archives, I finally figured this out. There is a comment in
java/awt/geom/Area.java:

public int getWindingRule() {
// REMIND: Which is better, EVEN_ODD or NON_ZERO?
// The paths calculated could be classified either way.
//return WIND_EVEN_ODD;
return WIND_NON_ZERO;
}

So if you need to convert from non-zero to even-odd, the trick is to
create an Area, and then proxy the shape in order to override the
getWindingRule on any returned PathIterators. You can do this with
Dynamic Proxies or explicit FilterShape and FilterPathIterator classes.

It would be nice if there was a setWindingRule on Area so that you could
choose what the PathIterator will return, but I'm just happy it works.

Chris

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Chris Nokleberg

I just stumbled on my question in the forums on java.net and noticed
that someone gave me the correct answer about a month ago(*). I am only
subscribed to the mailing list and apparently the forum posts do not get
mirrored to the list? Or at least there was a problem with this
particular message. Hopefully this will same somebody some time in the
future...

Chris

(*) http://forums.java.net/jive/thread.jspa?threadID=13363&tstart=0

On Sun, Apr 16, 2006 at 06:11:55PM -0700, Chris Nokleberg wrote:
> For the archives, I finally figured this out. There is a comment in
> java/awt/geom/Area.java:

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Dmitri Trembovetski

Hi Chris,

there were some issues with forwarding between forum and the list,
which were resolved recenlty. May be you were lucky to run into
those just before they got fixed.

Thanks,
Dmitri

On Sun, Apr 16, 2006 at 07:08:40PM -0700, Chris Nokleberg wrote:
> I just stumbled on my question in the forums on java.net and noticed
> that someone gave me the correct answer about a month ago(*). I am only
> subscribed to the mailing list and apparently the forum posts do not get
> mirrored to the list? Or at least there was a problem with this
> particular message. Hopefully this will same somebody some time in the
> future...
>
> Chris
>
> (*) http://forums.java.net/jive/thread.jspa?threadID=13363&tstart=0
>
> On Sun, Apr 16, 2006 at 06:11:55PM -0700, Chris Nokleberg wrote:
> > For the archives, I finally figured this out. There is a comment in
> > java/awt/geom/Area.java:
>
> ===========================================================================
> To unsubscribe, send email to listserv@java.sun.com and include in the body
> of the message "signoff JAVA2D-INTEREST". For general help, send email to
> listserv@java.sun.com and include in the body of the message "help".

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

sunflar
Offline
Joined: 2005-10-28
Points: 0

An algorithm to do this is very hard, as the article you reference demonstrates. It's even harder with curves as opposed to a polygon because determining intersection of Cubic Bezier curves has no closed solution unlike the intersection of lines which is a simple slope calculation.

I'm not sure if this satisfies your purposes, but the built-in java.awt.geom.Area object simplifies shapes as part of its construction process to make its job easier for doing the add/subtract/intersect/xor calculations you may ask it to do. The simplification involves getting rid of all places where the outline of the shape intersects itself. An interesting property of a non-self-intersecting shape is that it has the same interior regardless of which winding rule it uses.

So, new Area(shape).getPathIterator(null) will return a PathIterator that describes the same shape in a "winding rule neutral" way. The Area's PathIterator will claim a particular winding rule because it has to in order to implement the PathIterator interface, but you can extract the geometry and use it with your own winding rule to claim it either way.

That doesn't give you an algorithm you can tweak or optimize to your particular case, though.

And I don't have any answers for your cubic->quad conversion question...