Re: [JAVA2D] Connecting two semi-transparent shapes by a line

2004-09-07 Thread Andrei Kouznetsov
 Graphics2D g2d = (Graphics2D) g;

 // draw the foreground layer
 //
 Area clipArea = new Area( this.getBounds() );

 Iterator nodeIterator = widgets.iterator();
 while (nodeIterator.hasNext())
 {
 WidgetIF widget = (WidgetIF) nodeIterator.next();

 widget.draw( g2d );

 clipArea.subtract( new Area( widget.getBounds() ) );
 }


 g2d.setClip( clipArea );


 // draw all of the links
 Iterator linkIterator = links.iterator();
 while (linkIterator.hasNext())
 {
 WidgetIF widget = (WidgetIF) linkIterator.next();

 widget.draw( g2d );
 }


I think that you can optimize this if you don't create your clipping area
every paint.

Why you use widget.getBounds ? is your widget rectangular? if not then
widget.getShape would be better.

===
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] Connecting two semi-transparent shapes by a line

2004-09-07 Thread Jim Graham
--On 09/03/04 09:52:59 PM -0400 Gregory Pierce wrote:
Okay here is the scenario (and I'm hoping there is something in the
API that permits this because at this point I haven't found anything).
What I have are two RoundRectangle2Ds that have an alpha of 50
percent. I want to draw a line connecting the centers of both of these
RoundRectangle2Ds.
AB
If the RR2Ds were opaque I wouldn't have a problem, I would just draw
all of the links first and then draw all of the RR2Ds. Piece of cake.
However since the RR2Ds allow you to see through them, this clearly
won't work.
Are the connectors translucent as well?  You could use a separate
buffer to render them.  It gets a little more intensive if you have
items of different translucencies, though.  Layers may be the easiest
and most flexible solution:
Solution 1 - everthing at the same translucency:
   Create intermediate INT_ARGB buffer.
   Fill it with transparency (it is created that way)
   Render all objects to it opaquely.
   Render it to the screen using a translucent
   AlphaComposite object.
Solution 2 - things at different translucencies:
   Create intermediate INT_ARGB buffer.
   Fill it with transparency (it is created that way)
   Get a graphics from intermediate buffer.
   Set SRC mode on that graphics.
   Render all objects to it with their respective
   alphas in SRC mode
   Render the intermediate buffer to the screen in
   regular SRC_OVER mode (the default
   rendering mode).
I've looked at using Graphics2D.setClip()
Clipping can be used here, but you need to worry about the difference
between calculating a clip shape from geometry and then expecting it to
clip out the exact same pixels as were drawn from those shapes.  But,
rendering shapes involves lots of tradeoffs and calculations which
produce roundoffs in different ways that may not be reflected in your
clip calculations.
If you are going to go the clip route then you need to either:
   - Accept some amount of off by 1 problems
   - Do absolutely all rendering using the clip mechanism.
 No calls to draw() or fill() on a shape, just clip to a
 shape and then call fill(largerect) and rely on clipping.
   - Understand the specifics of the implementation well enough
 to know where the pitfalls are and adjust for them.  But,
 there is enough leeway in the specs to make this impossible
 to work for all implementations.
Also, this kind of a system would not be very compatible with
Antialiasing.  The layers approach above would be compatible.
but this will only allow me
to clip the line against one of the shapes. I also looked into solving
the problem using CAG, but Area doesn't work with lines (though I will
try to adapt my pathing algorithms to use rectangles if that solves my
drawing problem (here's hoping).
Area works with fillable geometry.  If you want to use it with
lines then they enclose no area.  If you want to use it with what
would be drawn when I use the draw() method on a line, then you need
to turn it into a fillable shape using the Stroke.createStrokedShape()
method.
It would be nice if there was a way to do a Graphics2D.addClip(Shape)
so that I could clip the graphics region by a near infinite number of
shapes. Same for intersect() and the like.
The workaround, as others have suggested is to construct your big union
first and then call clip() once with the entire shape.
   ...jim
===
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] Connecting two semi-transparent shapes by a line

2004-09-07 Thread Jim Graham
2) Do a CAG adding all of the rounded rectangles together into one
gigantic clipping shape. This is probably Er definitely the
easiest to code since I'm already iterating through the RR2Ds anyways
and can make this master shape. I'll probably do that one before I go
to sleep. Since I'm at a loss as to how Java handles Areas and the
documentation just isn't 'there' enough this one is difficult to
judge. I'm assuming that Java will have to do the same clipping logic
in 'java code' that I would have to do so this one is likely going to
be close to 1 in overall work and scalability.
Some info that may help you to make some judgment calls on
implementation here.
Area works on double precision geometry.  Also, it has no cutoff for
how much precision is required.  This, it must hunt down the exact
intersection point of every piece of geometry.  This can take a while
as the number of objects increases.
If you perform an operation on an Area, it must dice up the geometry to
do its tests.  When it is done testing and putting the pieces back
together into something that can yeild a path, it tries to keep the
original geometries that it was given as whole as it can, but if it
must slice some of them up then it needs to create a new geometry at
the appropriate slice point.  Due to double precision ideosyncracies,
it may not be possible to exactly represent the needed slice and so now
it ends up with slightly different geometry.  Now when you do the next
operation it must compare all the pieces to each other again, but this
time they've been perturbed.  This has the potential to cause yet
another piece of geometry to be created in the final extraction stages.
There are a couple of things we could do to improve this in the
implementation, but we don't have the resources at this point,
unfortunately.
   ...jim
===
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] Connecting two semi-transparent shapes by a line

2004-09-07 Thread Jim Graham
2) Do a CAG adding all of the rounded rectangles together into one
gigantic clipping shape. This is probably Er definitely the
BTW, Area is great for doing lots of complex CAG operations on
arbitrary geometry, but for a specific subset of its capabilities:
   - All geometry is known to have the same winding direction
   (whether it is clockwise or counter-clockwise)
   - No single element of the geometry is self-intersecting
   (or if it does self-intersect, it doesn't reverse
its direction to do so)
   - You want to do an Area add operation
then the fastest way to get a union of all of those pieces is just to
append them to a GeneralPath created with a Nonzero Winding Direction
rule.  The Nonzero rule naturally unions all geometry that winds the
same way...
   ...jim
===
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] Connecting two semi-transparent shapes by a line

2004-09-07 Thread Jim Graham
g2d.setClip( clipArea );
// draw all of the links
Iterator linkIterator = links.iterator();
while (linkIterator.hasNext())
{
WidgetIF widget = (WidgetIF) linkIterator.next();
widget.draw( g2d );
}
One minor optimization here.  Rather than draw all of the links
individually clipped, draw them all to an intermediate buffer and then
render that buffer to the screen clipped.  That will only work, of
course, if your background is simple as that last clipped drawImage
will obliterate everything outside of the rectangles.
   ...jim
===
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] Connecting two semi-transparent shapes by a line

2004-09-06 Thread Gregory Pierce
Hi Dmitri, I did indeed look into this (sorry the main discussion
ended up in the java-dev list at Apple but I will CC the relevant
portions here. The problem is that with a large number of objects
(i.e. 1000) the time to draw is well over 2 seconds. With a number of
objects close to what I anticipate (100) the drawing is on average 257
miliseconds per frame. Only in the 10 object case was the time to draw
a reasonable 37ms. Since I have to update the clipping area every
frame as multiple RR2Ds can be moving at a time, this approach quickly
becomes to slow.


On Sun, 5 Sep 2004 21:40:37 -0700, Dmitri Trembovetski
[EMAIL PROTECTED] wrote:

   Hi Gregory,

   please see my comments below.

 On Fri, Sep 03, 2004 at 09:52:59PM -0400, Gregory Pierce wrote:
   Okay here is the scenario (and I'm hoping there is something in the
   API that permits this because at this point I haven't found anything).
  
   What I have are two RoundRectangle2Ds that have an alpha of 50
   percent. I want to draw a line connecting the centers of both of these
   RoundRectangle2Ds.
  
   AB
  
   If the RR2Ds were opaque I wouldn't have a problem, I would just draw
   all of the links first and then draw all of the RR2Ds. Piece of cake.
   However since the RR2Ds allow you to see through them, this clearly
   won't work.
  
   I've looked at using Graphics2D.setClip(), but this will only allow me
   to clip the line against one of the shapes. I also looked into solving
   the problem using CAG, but Area doesn't work with lines (though I will
   try to adapt my pathing algorithms to use rectangles if that solves my
   drawing problem (here's hoping).
  
   It would be nice if there was a way to do a Graphics2D.addClip(Shape)
   so that I could clip the graphics region by a near infinite number of
   shapes. Same for intersect() and the like.

   I may be missing something, but why can't you construct a clip Area
   by subtracting (Area.subtract) the two RR2Ds you have from a rectangular
   clip, and set that area as the clip?

   Something along the lines of
   Area clipA = new Area(new Rectangle2D.Float(0, 0, winWidth, winHeight));
   clipA.subtract(new Area(rr2d_1)); // cut out rr2d_1, which is the first RoundRect2D
   clipA.subtract(new Area(rr2d_2)); // ... the second ...
   g2d.setClip(clipA);

   g2d.drawLine(...)

   Or take a look at demo/jfc/Java2D/src/java2d/demos/Clipping..

   Thanks,
 Dmitri




  
   Would be nice to see the OpenGL statemachine style of rendering start
   bubbling up to Java2D. Now that you're accelerating it via OpenGL,
   expect to see a lot of requests :)
  
   ===
   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.


===
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] Connecting two semi-transparent shapes by a line

2004-09-06 Thread Dmitri Trembovetski
On Mon, Sep 06, 2004 at 01:10:02PM -0400, Gregory Pierce wrote:
  Note: What is attached below is a copy from the Apple java-dev mailing
  list to provide additional insight into the problem:
 
  I have started looking at solving this problem 3 ways:
 
  1) Cheat and get a point on the bounding box and draw the line from that
  point. It will look funky, but quite possibly no one but me will notice
  since the arcs are only 10 pixels in width and height. I have a sneaking
  suspicion this will be the fastest way until the number of shapes and links
  being drawn gets large. Since this is something I expect it will be an
  interesting control for the others.

  Speaking of cheating. How about this: render the lines first, then
  render RR2Ds with the background color to remove the unneeded parts
  of the lines, and then render the translucent RR2Ds..
  (and if you want to get the most benefit, it may be better to render
  all of the lines first, then all of the opaque RR2Ds, and then all of
  the translucent ones).

  Of course, this works only if you have a single-colored background.

  Thanks,
Dmitri


 
  2) Do a CAG adding all of the rounded rectangles together into one gigantic
  clipping shape. This is probably Er definitely the easiest to code since
  I'm already iterating through the RR2Ds anyways and can make this master
  shape. I'll probably do that one before I go to sleep. Since I'm at a loss
  as to how Java handles Areas and the documentation just isn't 'there' enough
  this one is difficult to judge. I'm assuming that Java will have to do the
  same clipping logic in 'java code' that I would have to do so this one is
  likely going to be close to 1 in overall work and scalability.
 
  3) A little more involved render of the lines to one buffered image, then
  rendering a knockout pass to perform clipping in the frame buffer, then
  blending that image with the buffered image that just has the buffered
  images rendered. This will probably give a more constant performance over
  large numbers of objects since the work is really being done by the graphics
  hardware and there isn't any 'per object' computation being done.
 
  ===
  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.

===
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.