In other words each new arc is effectively "underneath" all of the
previous arcs?
You could use intermediate images for this.
Create 2 INT_ARGB images the size of your drawing (or the portion with
this waterfall-ish effect). On each frame you have "the one that holds
all of the previous arcs" and "the one that you will draw the new arcs
into". Then you simply do:
BufferedImage oldframe;
BufferedImage newframe;
...
loop {
Graphics2D g = newframe.createGraphics();
if (need to clear new frame) {
g.setComposite(AlphaComposite.Clear);
g.fillRect(0, 0, w, h);
g.setComposite(AlphaComposite.SrcOver);
}
g.setColor(...);
g.fillOval(...); /* or g.fill(Ellipse2D); */
g.drawImage(oldframe, 0, 0, null);
g.dispose();
... render newframe to destination ...
BufferedImage tmp = newframe;
newframe = oldframe;
oldframe = tmp;
}
If your arcs are all opaque and each one is bigger than all of the
previous ones then you don't need the "clear" part, but if drawing the
new arc on each frame doesn't obliterate all of the old stuff drawn
there, then you should clear it for good measure...
...jim
[EMAIL PROTECTED] wrote:
In an animation component that I am writing I have to draw colored concentric
arcs. In each frame I draw a new outer arc, and the inner arc is what in the
previous frame was the outer one and so on. (To help you understand, if I was
drawing straight lines, instead of arcs, this would give a waterfall effect).
In the attached program, I am drawing as many concentric arcs so as to complete
a circle.
The problem is that with each successive frame the rendering time increases to
such an extent that this algorithm is unusable. Is there any way to improve
the performance without reducing the diameter of the whole circle (1000px)
and/or the angle of each segment (1 degree). (Note that if the segment angle
is 90 degrees the performance is pretty bad too.)
If I were drawing lines instead of arcs the optimisation is easy, I’d just copy
the previous image down one pixel and then paint the new top line. But with
arcs I’m have to issue a drawArc() for every arc that has to appear.
I hope that somebody has some idea on how to optimize this.
[code]
package waterfall;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Arc2D;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;
public class WaterfallArc01 extends javax.swing.JPanel {
private final int diameter = 1000; // pixels
private final int sectorExtent = 1; // degree;
private final int numberSectors = 360/sectorExtent;
Random seed = new Random();
LinkedList<Color[]> list = new LinkedList();
public WaterfallArc01() {
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
generateNewData();
repaint();
}
};
javax.swing.Timer t = new javax.swing.Timer(500, taskPerformer);
t.start();
}
private void generateNewData()
{
Color[] sectors = new Color[numberSectors];
for(int i=0; i<numberSectors; i++)
{
sectors[i] = getColor();
}
list.addLast(sectors);
if (list.size()>diameter/2)
{
list.removeFirst();
}
}
private Color getColor()
{
return new Color(seed.nextInt(0x1000000));
}
@Override
protected void paintComponent(Graphics g)
{
render(g);
}
private void render(Graphics g)
{
Graphics2D g2d = (Graphics2D)g;
long startTime = System.nanoTime();
int size = diameter;
int x=0;
int y = x;
double startAngle=0;
double oldX=x;
// Erase background to white
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, diameter, diameter);
Color[] sectors;
Iterator<Color[]> it = list.descendingIterator();
while(it.hasNext()) // each update
{
sectors = it.next();
for(int i=0; i< sectors.length; i++) // all sectors
{
g2d.setColor(sectors[i]);
g2d.draw(new Arc2D.Double(x, y, size, size, startAngle,
sectorExtent, Arc2D.OPEN));
startAngle += sectorExtent;
}
oldX = x;
do{
size = size - 1;
x = (diameter - size)/2;
} while(x == oldX);
y = x;
startAngle=0d;
}
long estimatedTime = System.nanoTime() - startTime;
System.out.println(list.size()+" lines, render time:
"+(double)estimatedTime/1e9);
}
}
---------------------------------------------------------------------------------------------------------------------------
package waterfall;
import java.awt.BorderLayout;
public class TestWaterfallArc01 extends javax.swing.JFrame {
public TestWaterfallArc01() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new java.awt.Dimension(1000, 1000));
WaterfallArc01 waterfallArc011 = new WaterfallArc01();
getContentPane().setLayout( new BorderLayout());
add(waterfallArc011, BorderLayout.CENTER);
pack();
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new TestWaterfallArc01().setVisible(true);
}
});
}
}
[/code]
[Message sent by forum member 'ser207' (ser207)]
http://forums.java.net/jive/thread.jspa?messageID=300771
===========================================================================
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".