> this thing is called midpoint circle algoyrthm.
Yes after my previous post I found this:
http://en.wikipedia.org/wiki/Midpoint_circle_algorithm
Which led me to hack your version of the waterfall code to do arcs.
Unfortunately I don't think it is accurate for small angles, for example less
than 10 degrees. Any idea where I'm going wrong?
> A better optimized solution would be to look up for the right color in setRGB
> depending on the angle of the currently drawn pixel - this way you draw the
> circle only once, altering the color is bascially free
This is a cool idea!
[code]
package waterfall;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Point2D;
import java.awt.image.*;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Random;
public class WaterfallCircle01_LH_Arc 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();
BufferedImage bimg = new BufferedImage(1000, 1000,
BufferedImage.TYPE_INT_RGB);
int[] data=((DataBufferInt)bimg.getRaster().getDataBuffer()).getData();
LinkedList<Color[]> list = new LinkedList();
public WaterfallCircle01_LH_Arc() {
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
generateNewData();
repaint();
}
};
javax.swing.Timer t = new javax.swing.Timer(50, 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);
}
void setRGB(int x, int y, Color[] colors, Rectangle bounds)
{
int rgb = colors[0].getRGB();
if (bounds.contains(x, y))
{
int index = y * bimg.getWidth() + x;
if (index < data.length)
{
data[index] = rgb;
}
}
}
private Rectangle arcBoundingRectangle(Point startPoint, Point endPoint)
{
Rectangle r = new Rectangle(Math.min(startPoint.x, endPoint.x),
Math.min(startPoint.y, endPoint.y),
Math.abs(startPoint.x-endPoint.x),
Math.abs(startPoint.y-endPoint.y));
return r;
}
private Rectangle arcBoundingRectangle(Point2D startPoint, Point2D endPoint)
{
Rectangle r = new Rectangle((int)Math.round(Math.min(startPoint.getX(),
endPoint.getX())),
(int)Math.round(Math.min(startPoint.getY(), endPoint.getY())),
(int)Math.round(Math.abs(startPoint.getX()-endPoint.getX())),
(int)Math.round(Math.abs(startPoint.getY()-endPoint.getY())));
return r;
}
private void rasterCircle(int x0, int y0, int radius, Color[] colors,
Rectangle arcBounds)
{
int f = 1 - radius;
int ddF_x = 1;
int ddF_y = -2 * radius;
int x = 0;
int y = radius;
setRGB(x0, y0 + radius, colors, arcBounds);
setRGB(x0, y0 - radius, colors, arcBounds);
setRGB(x0 + radius, y0, colors, arcBounds);
setRGB(x0 - radius, y0, colors, arcBounds);
while (x < y)
{
if (f >= 0)
{
y--;
ddF_y += 2;
f += ddF_y;
}
x++;
ddF_x += 2;
f += ddF_x;
setRGB(x0 + x, y0 + y, colors, arcBounds);
setRGB(x0 - x, y0 + y, colors, arcBounds);
setRGB(x0 + x, y0 - y, colors, arcBounds);
setRGB(x0 - x, y0 - y, colors, arcBounds);
setRGB(x0 + y, y0 + x, colors, arcBounds);
setRGB(x0 - y, y0 + x, colors, arcBounds);
setRGB(x0 + y, y0 - x, colors, arcBounds);
setRGB(x0 - y, y0 - x, colors, arcBounds);
}
}
Point calcEndPoint(int anchorX, int anchorY, double radius, double
angleRadians)
{
return new Point((int)Math.round(anchorX+(radius *
Math.cos(angleRadians))), (int)Math.round(anchorY+(radius *
Math.sin(angleRadians))));
}
Point2D calcEndPoint2D(int anchorX, int anchorY, double radius, double
angleRadians)
{
return new Point2D.Double(anchorX+(radius * Math.cos(angleRadians)),
anchorY+(radius * Math.sin(angleRadians)));
}
private void render(Graphics g)
{
Graphics2D g2d = (Graphics2D) bimg.getGraphics();
long startTime = System.nanoTime();
int size = diameter;
int radius = size/2;
int x=500;
int y = x;
double startAngle= Math.toRadians(0);
double endAngle = Math.toRadians(45);
double oldX=x;
int cx=500;
int cy=500;
// 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;
}*/
radius = size/2;
Point2D startPoint = calcEndPoint2D(cx, cy, radius, startAngle);
Point2D endPoint = calcEndPoint2D(cx, cy, radius, endAngle);
Rectangle bounds = arcBoundingRectangle(startPoint, endPoint);
rasterCircle(cx, cy, radius, sectors, bounds);
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);
g.drawImage(bimg, 0, 0, null);
}
}
[/code]
[Message sent by forum member 'ser207' (ser207)]
http://forums.java.net/jive/thread.jspa?messageID=301317
===========================================================================
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".