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.