thedarklord47 thedarklord47 - 1 year ago 157
Java Question

Java Graphics2D floating point accurate drawOval alternative?

So I am trying to draw an arc and put a circle around its round endpoint, but I am having issues due to rounding to the nearest pixel. This is visible in some but not all cases.

Is there a way to draw circles using floating points and anti-aliasing to eliminate this rounding error?

You can run this code to see the problem. I have drawn arcs of 0 length (appearing as large dots) instead of full arcs for clarity.

import java.awt.*;
import javax.swing.*;

public class Example extends JFrame {

private int CENTER = 200;
private static int WINDOW = 400;

private int LEFT = 50;
private int TOP = 50;
private int DIM = 300;
private int DIAMETER = 26;

public Example () {

public void paint (Graphics g) {
Graphics2D g2 = (Graphics2D) g;

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

g2.setStroke(new BasicStroke(16, BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER));
g2.setColor(new Color(0, 0, 255));

g2.drawArc(LEFT, TOP, DIM, DIM, 0, 0);
g2.drawArc(LEFT, TOP, DIM, DIM, 32, 0);
g2.drawArc(LEFT, TOP, DIM, DIM, 115, 0);
g2.drawArc(LEFT, TOP, DIM, DIM, 200, 0);
g2.drawArc(LEFT, TOP, DIM, DIM, 331, 0);

this.drawCircle(g2, 0);
this.drawCircle(g2, 32);
this.drawCircle(g2, 115);
this.drawCircle(g2, 200);
this.drawCircle(g2, 331);

g2.setStroke(new BasicStroke(1));
g2.setColor(new Color(0, 0, 0));
g2.drawLine(0, CENTER, DIM * 2, CENTER);
g2.drawLine(CENTER, 0, CENTER, DIM * 2);

private void drawCircle(Graphics2D g, int angle) {
g.setStroke(new BasicStroke(3));
g.setColor(new Color(0, 0, 255));
Math.round(CENTER + (float)(Math.cos(Math.toRadians(angle)) * (DIM/2)) - DIAMETER/2),
Math.round(CENTER - (float)(Math.sin(Math.toRadians(angle)) * (DIM/2)) - DIAMETER/2),

public static void main (String args[]) {
Example e = new Example();
e.setSize(WINDOW, WINDOW);

Answer Source

Thank you trashgod for pointing out the use of Ellipse2D. For others, the only code modifications required for float precision Ovals/Circles is below:

import java.awt.*;


g2.drawOval(x, y, width, height);


import java.awt.*;
import java.awt.geom.Ellipse2D;


g2.draw(new Ellipse2D.Float(x, y, width, height));

Also, add these to make them pretty:

g2.setRenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHints(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download