4

I have been trying to write the code for generating random triangles and drawing arcs between the adjacent edges of the trianglefor describing the angle between them. It almost works. But it seems my math failed somewhere and arcs are not drawn correctly in some runs.

Please tell me where I'm going wrong. Perhaps these lines are the factors:

            g.draw(new Arc2D.Double(x1-r,y1-r,2*r,2*r,0,a,Arc2D.OPEN));
            g.draw(new Arc2D.Double(x2-r,y2-r,2*r,2*r,(180-b),b,Arc2D.OPEN));
            g.draw(new Arc2D.Double(x3-r,y3-r,2*r,2*r,-180+a,c,Arc2D.OPEN));

Here is SSCCE:

            import javax.swing.JComponent;
        import javax.swing.JFrame;
        import java.awt.geom.*;
        import java.awt.*;
        import java.util.*;
        class MyCanvas extends JComponent {
            int a,supb,b,c,length,r;
            double x1,y1,x2,y2,x3,y3;
            Random random=new Random();
            public MyCanvas(){
                a=random.nextInt(80-30)+30;
                supb=random.nextInt(120-70)+100;
                b=180-supb;
                c=180-a-b;
                length=random.nextInt(150-100)+100;
                x1=0;
                y1=0;
                r=20;
                x2=x1+length;
                y2=y1;
                x3=(x1+Math.cos(Math.toRadians(-a))*length);
                y3=(y1+Math.sin(Math.toRadians(-a))*length);
            }
         public void paintComponent(Graphics g2){

                Graphics2D g=(Graphics2D) g2;
                Random random=new Random();
                AffineTransform oldt=g.getTransform();
                Shape shape=getTriangle(x1,y1,x2,y2,x3,y3);
                Rectangle2D bounds=shape.getBounds2D();
                double height=bounds.getHeight();
                double width=bounds.getWidth();
                g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                g.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
                g.translate((this.getWidth() - width) / 2,(this.getHeight() - height) / 2);
                g.translate(-bounds.getX(),-bounds.getY());
                g.draw(shape);
                g.draw(new Arc2D.Double(x1-r,y1-r,2*r,2*r,0,a,Arc2D.OPEN));
                g.draw(new Arc2D.Double(x2-r,y2-r,2*r,2*r,(180-b),b,Arc2D.OPEN));
                g.draw(new Arc2D.Double(x3-r,y3-r,2*r,2*r,-180+a,c,Arc2D.OPEN));
                g.setTransform(oldt);
          }
          private Shape getTriangle(double length,double a,double b,double c){
                double x1=0,y1=0,x2,y2,x3,y3;
                x2=x1+length;
                y2=y1;
                x3=(x1+Math.cos(Math.toRadians(-a))*length);
                y3=(y1+Math.sin(Math.toRadians(-a))*length);
                return getTriangle(x1,y1,x2,y2,x3,y3);
            }
            private Shape getTriangle(double x1,double y1,double x2,double y2,double x3,double y3){
                GeneralPath gp=new GeneralPath();
                gp.moveTo(x1,y1);
                gp.lineTo(x2,y2);
                gp.lineTo(x3,y3);
                gp.closePath();
                return gp;
            }

        private void drawArc(Graphics2D g,int x0,int y0,int x1,int y1,int x2,int y2){
                int r = (int)Math.sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
                int x = x0-r;
                int y = y0-r;
                int width = 2*r;
                int height = 2*r;
                int startAngle = (int) (180/Math.PI*Math.atan2(y1-y0, x1-x0));
                int endAngle = -(int) (180/Math.PI*Math.atan2(y2-y0, x2-x0));
                g.drawArc(x, y, width, height, startAngle, endAngle);
        }
        }
        public class TrianglePanel {
          public static void main(String[] a) {
            JFrame window = new JFrame();
            window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            window.setBounds(30, 30, 300, 300);
            window.getContentPane().add(new MyCanvas());
            window.setVisible(true); 
          }
        }

These images show the result in two different runs of the SSCCE: enter image description here

enter image description here

Any help would be appreciated.

user1118321
  • 25,567
  • 4
  • 55
  • 86
pinkpanther
  • 4,770
  • 2
  • 38
  • 62
  • 1
    I have the same problem. I've been working on something similar where I'm drawing arcs given 3 points, and it's bugging out on some of the angles where I use arcTan to find the distance of the arc. It sometimes comes up too short, and sometimes too long. I'll let you know if I solve it. – Clark Kent May 20 '13 at 15:07
  • @SaviourSelf +1 for that – pinkpanther May 20 '13 at 15:12
  • I've only been working on it as a part of a much larger project for the last couple of days. If I can get your code to work, then I can get mine to work. – Clark Kent May 20 '13 at 15:15
  • @SaviourSelf thanks...i'm too working on a project where I need these kind of geometric ideas...i'm on deadline that's why not able to spend time on rectifying it.....tried a lot but couldn't make it any better – pinkpanther May 20 '13 at 15:17
  • 1
    Well, I got yours working, but it didn't really give me a hint at solving my problem. Give me a couple minutes to clean up the source, and I'll post it. – Clark Kent May 20 '13 at 16:05
  • @SaviourSelf thanks for that, why don't you post yours in stackoverflow as a question? – pinkpanther May 20 '13 at 16:08

1 Answers1

3

The problem was that you were incorrectly calculating the length of the arcs, which would make the second and third angle not get drawn the way you wanted all of the time.

import javax.swing.JComponent;
import javax.swing.JFrame;
import java.awt.geom.*;
import java.awt.*;
import java.util.*;

class MyCanvas extends JComponent {
    int a, supb, b, c, length, r;
    double x1, y1, x2, y2, x3, y3;
    Random random = new Random();

    public MyCanvas() {
            a = random.nextInt(80 - 30) + 30;
            supb = random.nextInt(120 - 70) + 100;
            b = 180 - supb;
            c = 180 - a - b;
            length = random.nextInt(150 - 100) + 100;
            x1 = 0;
            y1 = 0;
            r = 20;
            x2 = x1 + length;
            y2 = y1;
            x3 = (x1 + Math.cos(Math.toRadians(-a)) * length);
            y3 = (y1 + Math.sin(Math.toRadians(-a)) * length);
    }

    public void paintComponent(Graphics g2) {
            float dx1, dy1, ang1, dx2, dy2, ang2, ang3;
            Graphics2D g = (Graphics2D) g2;
            AffineTransform oldt = g.getTransform();

            Shape shape = getTriangle(x1, y1, x2, y2, x3, y3);

            Rectangle2D bounds = shape.getBounds2D();

            double height = bounds.getHeight();
            double width = bounds.getWidth();
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
            g.setStroke(new BasicStroke(2.0f, BasicStroke.CAP_BUTT,
                            BasicStroke.JOIN_BEVEL));
            g.translate((this.getWidth() - width) / 2,
                            (this.getHeight() - height) / 2);
            g.translate(-bounds.getX(), -bounds.getY());

            dy1 = (float) (y3 - y1);
            dx1 = (float) (x3 - x1);
            ang1 = (float) (Math.atan((float)(dy1 / dx1)) * 180 / Math.PI);

            ang1 = (float) Math.abs(ang1);

            dy2 = (float) (y2 - y3);
            dx2 = (float) (x2 - x3);
            ang2 = (float) (Math.atan((float)(dy2 / dx2)) * 180 / Math.PI);

            ang2 = (float) Math.abs(ang2);

    ang3 = (float) (180-ang2-ang1);

            g.setColor(Color.BLACK);
            g.draw(shape);
            g.setColor(Color.RED);
            g.draw(new Arc2D.Double(x1 - r, y1 - r, 2 * r, 2 * r, 0, ang1, Arc2D.OPEN));
            g.setColor(Color.GREEN);
            g.draw(new Arc2D.Double(x2 - r, y2 - r, 2 * r, 2 * r, (180 - ang2), ang2,
                            Arc2D.OPEN));
            g.setColor(Color.RED);
            g.draw(new Arc2D.Double(x3 - r, y3 - r, 2 * r, 2 * r, -180 + a, ang3,
                            Arc2D.OPEN));
            g.setTransform(oldt);
    }

    private Shape getTriangle(double x1, double y1, double x2, double y2,
                    double x3, double y3) {
            GeneralPath gp = new GeneralPath();
            gp.moveTo(x1, y1);
            gp.lineTo(x2, y2);
            gp.lineTo(x3, y3);
            gp.closePath();
            return gp;
    }
}

public class TrianglePanel {
        public static void main(String[] a) {
                JFrame window = new JFrame();
                window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                window.setBounds(30, 30, 300, 300);
                window.getContentPane().add(new MyCanvas());
                window.setVisible(true);
        }
}
Clark Kent
  • 1,178
  • 1
  • 12
  • 26