How to Draw a Decent Looking Circle in Java

How to draw a decent looking Circle in Java

As it turns out, Java2D (which I'm assuming is what you're using) is already pretty good at this! There's a decent tutorial here: http://www.javaworld.com/javaworld/jw-08-1998/jw-08-media.html

The important line is:

graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

Drawing a nice circle in Java

EDIT: Please see Code Guy's answer below for a solution. This is marked correct because it was Joey Rohan who figured it out initially!


I got smooth edge when i tried out same thing:

  g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,    RenderingHints.VALUE_ANTIALIAS_ON);

Sample Image

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;

public class DrawSmoothCircle {
public static void main(String[] argv) throws Exception {
BufferedImage bufferedImage = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bufferedImage.createGraphics();

g2d.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.green);
g2d.fillOval(10, 10, 50, 50);
g2d.dispose();

ImageIO.write(bufferedImage, "png", new File("e:\\newimage.png"));
}
}

UPDATE:

After searching alot:

There is nothing wrong with the code but,

Well, unfortunately Java 2D (or at least Sun's current implementation) does not support "soft clipping."

But Also got a trick for the clips:
Follow This link,you can achieve what you are asking for.

(Also, i got a smooth edge, cause i din't use clip stuff,in my above image)

draw smooth thin circle in java 2d graphics

According to How to draw a decent looking Circle in Java:

Turning on antialiasing helps make things look better:

graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

See also: Antialiasing, images, and alpha compositing in Java 2D

Is there any easy way to draw a circle onto a JPanel?

A simple solution, if you have the width/height declared in advance, would be to use the drawOval method as follows:

drawOval( x - (width/2), y - (height/2), width, height);

This will ensure that (x, y) is at the center of the oval.

Why?

Let's say (x, y) is (10, 10) and you want to draw an oval of (height, width) = (10, 10).

drawOval(x, y, height width);

would then draw the top-right of the oval at (10, 10), and the bottom-left would be at (10 + 10, 10 + 10) = (20, 20).

On the other hand, if you use

drawOval( x - (width/2), y - (height/2), height, width);

the top-right of the oval would be drawn at ( 10 - (10/2), 10 - (10/2) ) = (5, 5) and the bottom would be drawn at (5 + 10, 5 + 10) = (15, 15). The center would then be (10, 10) :)

How to draw a circle, positioning it at a double value instead of a int?

The only valid way of doing this is to use an Ellipse2D.Double shape and pass it to the draw(Shape) method of a Graphics2D instance. For the best results, enable anti-aliasing:

public void yourDrawingMethod(Graphics gg)
{
/* Cast it to Graphics2D */
Graphics2D g = (Graphics2D) gg;

/* Enable anti-aliasing and pure stroke */
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

/* Construct a shape and draw it */
Ellipse2D.Double shape = new Ellipse2D.Double(0.5, 0.5, 50, 50);
g.draw(shape);
}

You can use Graphics2D.fill(Shape) as well.

How to draw a circle with given X and Y coordinates as the middle spot of the circle?

The fillOval fits an oval inside a rectangle, with width=r, height = r you get a circle.
If you want fillOval(x,y,r,r) to draw a circle with the center at (x,y) you will have to displace the rectangle by half its width and half its height.

public void drawCenteredCircle(Graphics2D g, int x, int y, int r) {
x = x-(r/2);
y = y-(r/2);
g.fillOval(x,y,r,r);
}

This will draw a circle with center at x,y

Draw a circle with a radius and points around the edge

Points on a circle may be specified as a function of the angle θ:

x = a + r cos(θ)
y = b + r sin(θ)

Here, increments of 2π/8 are shown.

Addendum: As suggested in a comment by @Christoffer Hammarström, this revised example reduces the number of magic numbers in the original. The desired number of points becomes a parameter to the constructor. It also adapts the rendering to the container's size.

alt text

/** @see https://stackoverflow.com/questions/2508704 */
public class CircleTest extends JPanel {

private static final int SIZE = 256;
private int a = SIZE / 2;
private int b = a;
private int r = 4 * SIZE / 5;
private int n;

/** @param n the desired number of circles. */
public CircleTest(int n) {
super(true);
this.setPreferredSize(new Dimension(SIZE, SIZE));
this.n = n;
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.black);
a = getWidth() / 2;
b = getHeight() / 2;
int m = Math.min(a, b);
r = 4 * m / 5;
int r2 = Math.abs(m - r) / 2;
g2d.drawOval(a - r, b - r, 2 * r, 2 * r);
g2d.setColor(Color.blue);
for (int i = 0; i < n; i++) {
double t = 2 * Math.PI * i / n;
int x = (int) Math.round(a + r * Math.cos(t));
int y = (int) Math.round(b + r * Math.sin(t));
g2d.fillOval(x - r2, y - r2, 2 * r2, 2 * r2);
}
}

private static void create() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new CircleTest(9));
f.pack();
f.setVisible(true);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
create();
}
});
}
}

Java awt draw elements around a circle

So, your basic problem comes down to "find a point on a circle based on a given angle"

A quick google will find resources like Find the coordinates of a point on a circle, now, to be frank, I'm an idiot, so I'd narrow my search to include Java, which would give us something like How to calculate the coordinates of points in a circle using Java? - sweet.

So the basic calculation might look something like

double xPosy = Math.cos(rads) * radius);
double yPosy = Math.sin(rads) * radius);

Now, this solves the core aspect of your problem. The rest comes down to simply painting the results. See Performing Custom Painting and Painting in AWT and Swing as a starting point and 2D Graphics for a more detailed look into the API.

Now, taking all of the above, you might end up with a solution looking something like...

Sample Image

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test {

public static void main(String[] args) {
new Test();
}

public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}

public class TestPane extends JPanel {

public TestPane() {
}

@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int midX = getWidth() / 2;
int midY = getHeight() / 2;
Dimension size = new Dimension(4, 4);
g2d.setColor(Color.BLACK);
for (int index = 0; index < 64; index++) {
double angle = (360d / 64d) * index;
Point2D poc = getPointOnCircle(angle, 100 - 4);
Rectangle2D box = new Rectangle2D.Double(midX + poc.getX() - 2, midY + poc.getY() - 2, size.width, size.height);
g2d.draw(box);
}
g2d.dispose();
}

protected Point2D getPointOnCircle(double degress, double radius) {
double rads = Math.toRadians(degress - 90); // 0 becomes the top

return new Point2D.Double(Math.cos(rads) * radius, Math.sin(rads) * radius);
}
}
}

So, about now, you should realise that my "squares" are, well, square, not "dimond" shaped like yours. This is where you're going to have to start doing some work.

If I was approaching this problem I might be tempted, to create a custom shape or, apply a 45 degree transformation to the box and the translate it's position to render it or just rotate the whole result by 45 degrees, but this brings a whole bag of other issues depending on what you want to do with it



Related Topics



Leave a reply



Submit