1. ## 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

2. 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 -

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

3. 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:

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 :()

4. Ok, Ill knock one up now.

5. Best of luck!

6. 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:
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();
drawPanel.setPreferredSize(new Dimension(800, 600));

mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.pack();
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
}
}```

DrawPanel.java:
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);

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));
}
}```

7. 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.

8. 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

9. 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.

10. 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:
Java 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:
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();
drawPanel.setPreferredSize(new Dimension(800, 600));

mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.pack();
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
}
}```
DrawPanel.java:
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);
}
}

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;
}
}```

#### Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•