Re: [JAVA2D] Connecting two semi-transparent shapes by a line
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
--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
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
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
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
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
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.