Efficient method for drawing many rectangles.

C

Chuck Dillon

If you have an array of N Rectangle2D.Double objects, (where N is
potentially tens of thousands), what's the most efficient way to render
them in a single color?

My application needs to render many rectangles (i.e. thousands). My
graphics experience tells me that in general the most efficient way to
render graphics is the case where you "batch" as much of the operation
as possible. That's probably biased by my X experience where you want
to a few drawlines() calls rather than do a lot of drawline() calls
since there's a commuications channel between your client and the X
server. But IMHO batching primitive calls is a good thing.

Applying this to Java, first I looked for a drawLines or drawShapes
method in Graphics2D and did't see any. So next I thought it should be
more efficient to shove a bunch of Rectangle shapes into a GeneralShape
object and draw(path) in one call than to draw(Rectangle) many times.
But I'm not seeing that to be true. In fact, I seem to be seeing a
pathalogical case where it can take a looong time to render a
GeneralPath with on the order of 32k rectangles in it. (JRE/JDK 1.4.1_01)

Thanks for any advice,

-- ced
 
A

Andrew Hobbs

Chuck Dillon said:
If you have an array of N Rectangle2D.Double objects, (where N is
potentially tens of thousands), what's the most efficient way to render
them in a single color?

My application needs to render many rectangles (i.e. thousands). My
graphics experience tells me that in general the most efficient way to
render graphics is the case where you "batch" as much of the operation
as possible. That's probably biased by my X experience where you want
to a few drawlines() calls rather than do a lot of drawline() calls
since there's a commuications channel between your client and the X
server. But IMHO batching primitive calls is a good thing.

Applying this to Java, first I looked for a drawLines or drawShapes
method in Graphics2D and did't see any. So next I thought it should be

However Graphics 2D does have drawLines() etc. They are inherited from
Graphics. (see docs).
more efficient to shove a bunch of Rectangle shapes into a GeneralShape
object and draw(path) in one call than to draw(Rectangle) many times.
But I'm not seeing that to be true. In fact, I seem to be seeing a
pathalogical case where it can take a looong time to render a
GeneralPath with on the order of 32k rectangles in it. (JRE/JDK 1.4.1_01)

What do you mean by a long time to render?

I am not sure what exactly you are doing. As a test I just produced a
Rectangle class with its own draw method. Then I tried rendering Rectangle
objects onto a JPanel. Simply instantiating 1 million rectangle objects
with four randomly generated values for x1, y1, x2, y2 coordinates and then
getting each one to draw itself onto a Jpanel took 16 seconds. So 32,000
Rectangles shouldn't take more than about five hundred milliseconds.

Using the Graphics2D method 'draw(new Rectangle())' method as suggested in
the docs took 11 seconds to produce the 4 million random numbers and then
draw the rectangles on the Jpanel which is about 40% faster.

Of course if the rectangles require much processing then that will slow
things down a bit.

Cheers

Andrew
 
C

Chuck Dillon

Andrew said:
However Graphics 2D does have drawLines() etc. They are inherited from
Graphics. (see docs).

Sorry, I'm not seeing any such method(s) at
http://java.sun.com/j2se/1.4.2/docs/api/index.html. My IDE (Eclipse)
doesn't seem to be aware of any such methods either?
What do you mean by a long time to render?

What I'm seeing is that if I push on the order of 40k rectangles into a
GeneralPath, unconnected, I sometimes get a rendering time of about 3
minutes or sometimes my development machine (Win2K PIV) locks up
requiring a cold boot. I suppose I'm running into a JVM bug, or
somewhere below. The problem doesn't seem to be determined by the
number of segments in the path. It can also draw 40+k rectangles
pretty quickly (I don't have my timing notes available) when it works.

Regardless of the apparent bug, what I'm looking for is advice on the
most efficient method. I'm guessing that the GeneralPath approach is it.
I am not sure what exactly you are doing.

I'm annotating features in an image with graphical rectangles. In the
paintComponent method of a JPanel I'm rendering rectangles derived from
a large set of feature objects aligned to the image.

The features, and their annotation rectangles, "live" in floating point
image coordinates. I'm using Rectangle2D.Double objects.

I realize that I can simply g2D.draw(feature.getRectangle()).

Performance is important. This is an interactive image display. So
I'm looking for the most efficient approach to render the information
since the user might be dragging the field of view as I'm doing it.

Thanks for the response,

-- ced
 
S

Steve W. Jackson

Dario said:
:>> However Graphics 2D does have drawLines() etc. They are inherited from
:>> Graphics. (see docs).
:>
:> Sorry, I'm not seeing any such method(s) at
:> http://java.sun.com/j2se/1.4.2/docs/api/index.html.
:
:Confirmed: drawLines does *not* exist.

No, but drawLine (singular) does. Still, I'm curious why the use of
drawShape (since Rectangle implements Shape) or drawRect can't work
here. I didn't see any clear indication in the thread that it'd been
tried with bad performance.

= Steve =
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top