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);
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.
/** @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...
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
JPA & Criteria API - Select Only Specific Columns
Can't Make Jackson and Lombok Work Together
Stringbuilder/Stringbuffer VS. "+" Operator
How to Shutdown an Executorservice
Why Are New Java.Util.Arrays Methods in Java 8 Not Overloaded for All the Primitive Types
Attach the Source in Eclipse of a Jar
How to Create a Process in Java
Execute Jsp Directly from Java
Jtable + Sorting Specific Field
How to Escape Reserved Words in Hibernate's Hql
Spring 4 - Addresourcehandlers Not Resolving the Static Resources
Stax Xmlstreamreader Check for the Next Event Without Moving Ahead
Should Methods in a Java Interface Be Declared with or Without a Public Access Modifier
What Are the Advantages of Using an Executorservice
How to Use Urlclassloader to Load a *.Class File