Reputation: 823
A program that animates circles is not drawing them fluidly once several hundred are drawn at once. It was suggested to use affine transformation to copy the shapes. This code, refactored to use graphics2D, works, but doesn't cause any performance boost since it is still filling hundreds of ovals. How to use affinetransformation properly to fill a shape once and then copy/move it?
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.WHITE);
for (int i = 0; i < gameLogic.getParticleArrSize(); i++) {
Graphics2D g2 = (Graphics2D) g;
Color color = new Color(6,6,6);
Ellipse2D oval = new Ellipse2D.Double(
gameLogic.getParticleXCoor(i),
gameLogic.getParticleYCoor(i),
gameLogic.getParticleSize(i),
gameLogic.getParticleSize(i));
g2.setPaint(color);
g2.fill(oval);
g2.translate(15, 15);
g2.fill(oval);
}
}
Upvotes: 1
Views: 787
Reputation: 324207
Doubt it will make a big difference but:
I've also seen an example that uses 5000 balls without a problem. It uses the fillOval(...) method. Don't know if that will make a difference.
Upvotes: 1
Reputation: 205875
The only way to know which is faster is to profile two or more implementations. As a concrete example, this kinetic model shows a slight advantage for Gradient mode, using drawImage()
, over Color mode, using fill()
, as seen in the paintComponent()
method of DisplayPanel
. In this context, AffineTransform
is beneficial in pre-rendering the more complex gradient image.
Addendum:
I don't know how to properly implement
AffineTransform
to move/copy ovals…
I doubt that AffineTransform
is the cure. Instead, move the object creation out of the loop, as @camickr suggests. In the example, note how an Ensemble
only needs one Ellipse2D
; it uses setFrame()
repeatedly. Also, each Particle
already knows its Color
. Finally, observe how the example measures paint time.
Upvotes: 1