在三角形相邻边缘间绘制弧线的问题

时间:2013-05-20 14:53:39

标签: java swing geometry java-2d jcomponent

我一直在尝试编写用于生成随机三角形的代码,并在三角形的相邻边缘之间绘制弧线以描述它们之间的角度。它几乎可以工作。但似乎我的数学失败了某些地方并没有正确绘制弧线。

请告诉我哪里出错了。 也许这些因素是因素:

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

这是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); 
          }
        }

这些图像显示了两次不同的SSCCE运行结果: enter image description here

enter image description here

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:3)

问题在于你错误地计算了弧的长度,这会使第二个和第三个角度不能按照你想要的方式绘制。

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