Results 1 to 11 of 11

Thread: Drawing an arc

  1. #1
    berkeleybross's Avatar
    berkeleybross is offline Senior Member
    Join Date
    Feb 2010
    Location
    England
    Posts
    187
    Rep Power
    5

    Default 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

    Thanks for reading,
    berkeleybross

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

  3. #3
    berkeleybross's Avatar
    berkeleybross is offline Senior Member
    Join Date
    Feb 2010
    Location
    England
    Posts
    187
    Rep Power
    5

    Default

    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

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by berkeleybross View Post
    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 :()

  5. #5
    berkeleybross's Avatar
    berkeleybross is offline Senior Member
    Join Date
    Feb 2010
    Location
    England
    Posts
    187
    Rep Power
    5

    Default

    Ok, Ill knock one up now.

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Best of luck!

  7. #7
    berkeleybross's Avatar
    berkeleybross is offline Senior Member
    Join Date
    Feb 2010
    Location
    England
    Posts
    187
    Rep Power
    5

    Default

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

  8. #8
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    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.

  9. #9
    berkeleybross's Avatar
    berkeleybross is offline Senior Member
    Join Date
    Feb 2010
    Location
    England
    Posts
    187
    Rep Power
    5

    Default

    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

  10. #10
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    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.

  11. #11
    berkeleybross's Avatar
    berkeleybross is offline Senior Member
    Join Date
    Feb 2010
    Location
    England
    Posts
    187
    Rep Power
    5

    Default

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

Similar Threads

  1. Using Piccolo for Drawing
    By rstepler in forum Java 2D
    Replies: 2
    Last Post: 08-20-2013, 11:03 AM
  2. PaintComponant Drawing help?
    By Jcbconway in forum New To Java
    Replies: 14
    Last Post: 11-28-2010, 02:24 AM
  3. Drawing dots.
    By hellolleh in forum NetBeans
    Replies: 0
    Last Post: 03-16-2010, 09:09 PM
  4. Drawing a map
    By Karp in forum AWT / Swing
    Replies: 4
    Last Post: 11-07-2008, 01:26 PM
  5. Help with 2-D Drawing
    By Deathmonger in forum New To Java
    Replies: 4
    Last Post: 06-18-2008, 03:23 AM

Posting Permissions

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