三角形相邻边之间绘制弧线出现问题

4

我一直在尝试编写代码来生成随机三角形,并在相邻边之间绘制弧线,以描述它们之间的角度。它几乎可以工作。但似乎我的数学出了问题,在某些运行中弧线没有正确绘制。

请告诉我我哪里出错了。 也许这些行是问题所在:

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

这些图片展示了两次SSCCE运行的结果: enter image description here enter image description here 需要帮助,谢谢。

1
我有同样的问题。我正在做类似的事情,即根据3个点绘制弧线,在使用arcTan查找弧线距离的某些角度上出现了问题。它有时会变得太短,有时又太长。如果我解决了这个问题,我会告诉你的。 - Clark Kent
@SaviourSelf +1 鼓励一下 - pinkpanther
我只是在过去几天里作为一个更大项目的一部分来处理它。如果我能让你的代码运行起来,那么我也能让我的代码运行起来。 - Clark Kent
@SaviourSelf 谢谢...我也在做一个需要这些几何概念的项目...但由于期限的关系,我无法花时间去纠正它...尝试了很多次,但是没能让它变得更好。 - pinkpanther
1
好的,我已经让你的代码运行了,但它并没有给我解决问题的提示。请给我几分钟时间整理一下源代码,我会把它发布出来。 - Clark Kent
@SaviourSelf,谢谢你的回复,为什么不把你的问题发布到StackOverflow上呢? - pinkpanther
1个回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接