Re: [JAVA2D] area.subtract and antialias problem

2008-11-19 Thread Jim Graham
Since the 2f stroke straddles the path it only contributes 1f on every 
side so the 96pixel ellipse should be 98 pixels.


It should be reliable on all platforms, but there may be +/- half a 
pixel slop depending on rounding directions, stroke normalization hints 
and algorithm choices.


Yes, translucency does ruin the drawing shapes on top of each other 
approach.  At that point the only choices are to let the background leak 
through or use a downsampling approach in place of the built-in AA.


BTW, have you tried setting the STROKE_PURE hint?  That may at least 
make the gaps a little more symmetric than the default STROKE_NORMALIZE 
hint...


...jim

davood wrote:

Thanks for your helps.
The problem with drawing the border is that it will make the size of shape
bigger than what it actually is, specially if I use stroke 2f. Can I be sure
that if I draw a say 96pixel ellipse and a 2f stroke around it, it will take
100pixel on all platforms?
On other side the shapes will be translucent so its not possible to just
draw shapes on top of each other. Beside that I need to measure shapes area
and there will be user interactions, It's why I'm trying to find a solution
having the exact shape. 



===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.


Re: [JAVA2D] area.subtract and antialias problem

2008-11-17 Thread Jim Graham
Since both shapes are being rendered with an opaque color, why not just 
render shape1 followed by shape3?


The problem you are running into with antialiasing is a common one and 
it is due to the fact that the two operations work independently to fill 
C (for fraction of coverage) of the pixel and then again to fill (1.0-C) 
of the pixel.  Geometrically you can see that the two operations should 
be filling wholly separate parts of the pixel and so the new coverage 
should be a full 1.0, but the operations are done in isolation and so 
filling C of the pixel in the first operation leaves it C filled and 
(1.0-C) remaining from the original background color.  The second 
operation then comes along and fills against the blended color and ends 
up leaving some of the background still showing:


bg = original background color
c1 = color of first fill operation
ci = intermediate color after first fill operation
c2 = color of second fill operation
cf = final color
C = coverage of first shape
1-C = coverage of second, subtracted shape

First operation (fills the pixel with coverage C):

ci = C * c1 + (1-C) * bg

Second operation (fills again with coverage 1-C):

cf = (1-C) * c2 + (1-(1-C)) * ci
   = (1-C) * c2 + C * ci
   = (1-C) * c2 + C * C * c1 + C * (1-C) * bg

If the coverage was 0.5 then the background should still be contributing 
to 0.25 of the color of the pixel.  Note also that the first color is 
also only contributing to 0.25 of the pixel and the second color is the 
only one with a proper contribution at 0.5 of the pixel.


The only workarounds are:

- Render the entire scene non-antialiased at a higher resolution and 
then use image subsampling in stages on the fully rendered image to 
downsample while blending to create a full scene antialiasing technique


- Render a fringe around the second operation so that it fully bleeds 
into its border pixels and then render the first operation on top of it 
so that it correctly replaces exactly the C portion of the pixel and 
leaves the remaining 1-C portion set to the second color.  (Someone 
already suggested this technique here, but I am adding a little to it by 
saying that it works better if you perform the second fill first with 
its fringe and then have the first fill done in AA mode on top of it.)


Hope that helps!

...jim

davood wrote:

Hi,

In my application I'm creating new shape (Area) by subtracting a shape from
another one but when I turn on the antialias in rendering I face with a
white border around inner object. I'm not using composite because I need to
create the shape by subtracting. Is there any solution for this problem?
Here is a sample code,

private void drawTest(Graphics2D g2) {
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, getWidth(), getHeight());

Ellipse2D shape1 = new Ellipse2D.Double(150, 185, 150, 60);

Shape shape3 = new Rectangle2D.Double(100, 100, 250, 250);
Area area = new Area(shape3);
area.subtract(new Area(shape1));

g2.setColor(new Color(86 / 256f, 114 / 256f, 142 / 256f, 1f));
g2.fill(area);

g2.setColor(new Color(86 / 256f, 144 / 256f, 182 / 256f, 1f));
g2.fill(shape1);
}




===
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message signoff JAVA2D-INTEREST.  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message help.