# Drawing an arc

• 12-07-2010, 11:48 PM
berkeleybross
Drawing an arc
Hi all,
I suppose this is more of a mathsy theoretical question than java implementation, but I hope someone can help me!

I'm trying to work out how to draw a curve in java. I know three things about the curve i need to draw - its start and end coordinates, and how many degrees of a circle it represents (i think the technical term is the angle subtended - not 100% sure)

Im having trouble drawing a curve to fit the data properly. I've played around a bit with arc2d, where i can set the angle, but i cant get the start and end points correct. I also tried the quadratic curve, but i have no idea where to put the middle point.

Can anyone point me in the right direction? I realise its not a very good explanation so please ask if you need more info

berkeleybross
• 12-08-2010, 12:06 AM
Fubarable
You may wish to create and post an SSCCE so we can better understand your problem.
• 12-08-2010, 12:16 AM
berkeleybross
Thanks for the quick reply, although unfortunately its kinda hard to explain, but i dont think an SSCCE would help.

I've found this diagram which may be helpful though -
http://www.mathsteacher.com.au/year1.../Image4077.gif

I know point A and B, and I know the angle at the centre (in this case 105).

I need to draw arc AB.

Thanks,
berkeleybross
• 12-08-2010, 12:20 AM
Fubarable
Quote:

Originally Posted by berkeleybross
Thanks for the quick reply, although unfortunately its kinda hard to explain, but i dont think an SSCCE would help.

I would beg to differ. You state here:

Quote:

Im having trouble drawing a curve to fit the data properly. I've played around a bit with arc2d, where i can set the angle, but i cant get the start and end points correct. ...
If you created an SSCCE based on this attempt, then we could see what you're doing wrong. Otherwise I have to create an SSCCE myself, and I'm too lazy to do that :) (and still at work and will be here for hours :()
• 12-08-2010, 12:22 AM
berkeleybross
Ok, Ill knock one up now.
• 12-08-2010, 12:25 AM
Fubarable
Best of luck!
• 12-08-2010, 04:46 AM
berkeleybross
Hi again, I've finally managed to clean up my code so its just about readable.

My stumbling block at the moment is working out where the centre of the circle is - i just dont really know the math.

I've included the sourcecode which displays where the start and end points of the arc should be, and where the arc actually is. Unfortunately, they dont match :P

Just a little housekeeping: i have cross posted the question on a math forum (here). Im hoping someone knows the answer there.

Thanks,

berkeleybross

Main.java:
Code:

```package arcsscce; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.SwingUtilities; /**  *  * @author Berkeleybross  */ public class Main {     /**     * @param args the command line arguments     */     public static void main(String[] args) {         SwingUtilities.invokeLater(new Runnable() {             public void run() {                 new Main().initComponents();             }         });     }     private void initComponents() {         JFrame mainFrame = new JFrame ("Arc SSCCE");                 DrawPanel drawPanel = new DrawPanel();         mainFrame.add(drawPanel);         drawPanel.setPreferredSize(new Dimension(800, 600));         mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         mainFrame.pack();         mainFrame.setLocationRelativeTo(null);         mainFrame.setVisible(true);     } }```

DrawPanel.java:
Code:

```package arcsscce; import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JPanel; /**  *  * @author Berkeleybross  */ public class DrawPanel extends JPanel {     @Override     public void paintComponent (Graphics g) {         Graphics2D g2d = (Graphics2D) g;         Coordinate a = new Coordinate(); // Required Arc start coordinates         a.x = 300;         a.y = 300;         Coordinate b = new Coordinate(); // Required Arc end coordinates         b.x = 400;         b.y = 300;         int arcAngle = 90;  // Required arc curvature (angle subtended)         g.drawLine(a.x, a.y, a.x, a.y + 1); // Draws where the start position should be         g.drawLine(b.x, b.y, b.x, b.y + 1); // draws where the end position should be         // The variables to work out, to draw the arc         Coordinate arc = new Coordinate();         arc.x = 0;         arc.y = 0;         int arcWidth = 0;         int arcHeight = 0;         int arcStartAngle = 0;         double distAB = a.dist(b); // Length of chord ab         double alpha = distAB / 2; // half chord ab         double beta = alpha / Math.tan(Math.PI*arcAngle / 360); //         double radius = alpha / Math.sin(Math.PI*arcAngle / 360);                 Coordinate v = new Coordinate(); // This should be the vector to go         v.x = (int) ((a.y - b.y) / distAB * beta);         v.y = (int) ((b.x - a.x) / distAB * beta);         Coordinate centre = new Coordinate();         centre.x = (a.x + b.x) / 2 + v.x;         centre.y = (a.y + b.y) / 2 + v.y;         Coordinate temp = centre;         System.out.println (temp.x + " " + temp.y);         arc.x = (int) (centre.x - radius);         arc.y = (int) (centre.y - radius);         arcWidth = (int)( 2*radius);         arcHeight = (int) (2*radius);         int dX = a.x - b.x;         int dY = a.y - b.y;         arcStartAngle = (int) Math.tan(dY/dX);                 g2d.drawArc(arc.x, arc.y, arcWidth, arcHeight, arcStartAngle, arcAngle);     } } class Coordinate {     int x;     int y;     public double dist (Coordinate other) {         int dX = x - other.x;         int dY = y - other.y;         return Math.sqrt((dX * dX) + (dY * dY));     } }```
• 12-08-2010, 05:10 AM
Fubarable
Are points A and B always horizontal to each other? Are their y values always the same? If so, that greatly simplifies this problem which is nothing more than two equations with two unknowns.
• 12-08-2010, 05:16 AM
berkeleybross
Sorry, no there not. The user can define them to be anywhere on screen.

I also forgot to mention that the centre of the circle should be below the screen if point b is to the right of a, or above if point b is to the left of a.

Thanks again for the quick response
• 12-08-2010, 05:23 AM
Fubarable
Then you're right, this isn't a Java problem but a math problem, but not a complex one. So if your points are A and B, I would find the midpoint between A and B and the slope to the perpendicular to the line AB. The center to your circle will pass through that perpendicular line and have a slope that is the inverse negative to the slope of AB. That's one constraint. The other is from the angle. Since you know the length of AB and of course AB/2, then the radius of the circle will be the cosecant of (theta/2) times the length AB/2.
• 12-09-2010, 02:32 AM
berkeleybross
Hi again
I think i've managed to correctly calculate the centre of the circle. However my problem is now drawing the arc to correctly match up with the points.
The arc seems to not be starting at the right angle, and i cant figure out the equation.

my current equations is this:
Code:

`int arcStartAngle = (int) Math.toDegrees(Math.acos((b.y - center.y) / b.dist(center)));`
where "b" is the end point of the arc, and "center" is the center point of the circle.

Thanks,
berkeleybross

Main.java:
Code:

``` package arcsscce; import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.SwingUtilities; /**  *  * @author Berkeleybross  */ public class Main {     /**     * @param args the command line arguments     */     public static void main(String[] args) {         SwingUtilities.invokeLater(new Runnable() {             public void run() {                 new Main().initComponents();             }         });     }     private void initComponents() {         JFrame mainFrame = new JFrame ("Arc SSCCE");                 DrawPanel drawPanel = new DrawPanel();         mainFrame.add(drawPanel);         drawPanel.setPreferredSize(new Dimension(800, 600));         mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         mainFrame.pack();         mainFrame.setLocationRelativeTo(null);         mainFrame.setVisible(true);     } }```
DrawPanel.java:
Code:

``` package arcsscce; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.util.Random; import javax.swing.JPanel; /**  *  * @author Berkeleybross  */ public class DrawPanel extends JPanel {     Coordinate a;     Coordinate b;     int arcAngle;     public DrawPanel () {         boolean generate = true;         if (!generate) {             a = new Coordinate(300, 300); // Required Arc start coordinates             b = new Coordinate(400, 400); // Required Arc end coordinates             arcAngle = 90;  // Required arc curvature (angle subtended)         } else {             Random random = new Random();             a = new Coordinate(random.nextInt(800), random.nextInt(600)); // Required Arc start coordinates             b = new Coordinate(random.nextInt(800), random.nextInt(600)); // Required Arc end coordinates             arcAngle = random.nextInt(359) + 1;  // Required arc curvature (angle subtended)       }     }     @Override     public void paintComponent (Graphics g) {         Graphics2D g2d = (Graphics2D) g;                 double theta = arcAngle * Math.PI / 180;         double radius = (a.dist(b)/ 2) / Math.sin(theta / 2);         double beta = a.dist(b) / 2 / Math.tan(theta/2);         Coordinate m = new Coordinate((int)(a.x + b.x)/2, (int) (a.y + b.y)/2);         Coordinate v = new Coordinate(a.y - b.y, b.x - a.x);                 v.x = (int) (v.x / a.dist(b) * beta);         v.y = (int) (v.y / a.dist(b) * beta);         Coordinate center = new Coordinate(m.x - v.x, m.y - v.y);         // The variables to draw the arc         Coordinate arc = new Coordinate();         arc.x = center.x - (int) radius;         arc.y = center.y - (int) radius;         int arcWidth = (int) radius * 2;         int arcHeight = (int) radius * 2;         int arcStartAngle = (int) Math.toDegrees(Math.acos((b.y - center.y) / b.dist(center)));         g2d.drawArc(arc.x, arc.y, arcWidth, arcHeight, arcStartAngle, arcAngle);         g2d.setColor(Color.red);         g.drawLine(a.x - 1, a.y - 1, a.x + 1, a.y + 1); // Draws where the start position should be         g.drawLine(a.x + 1, a.y - 1, a.x - 1, a.y + 1); // Draws where the start position should be         g2d.setColor(Color.blue);         g.drawLine(b.x - 1, b.y - 1, b.x + 1, b.y + 1); // draws where the end position should be         g.drawLine(b.x + 1, b.y - 1, b.x - 1, b.y + 1); // draws where the end position should be         g2d.drawString("start " + a, 700, 100);         g2d.drawString("end " + b, 700, 120);         g2d.drawString("angle " + arcAngle, 700, 140);         g2d.drawString("v " + v, 700, 200);         g2d.drawString("m " + m, 700, 220);         g2d.drawString("Centre " + center, 700, 240);         g2d.drawString("Radius " + radius, 700, 260);     } } class Coordinate {     int x;     int y;     public Coordinate() {     }     public Coordinate (int x, int y) {         this.x = x;         this.y = y;     }     public double dist (Coordinate other) {         int dX = x - other.x;         int dY = y - other.y;         return Math.sqrt((dX * dX) + (dY * dY));     }     public String toString () {         return x + ", " + y;     } }```