Java - 计算和放置几何形状的角度

Java - Calculating and placing the angle of a geometric shape

我目前正在开发一个能让用户绘制各种几何形状的程序。但是,我在计算角度对象并将其准确放置到我的 Canvas 面板上时遇到了一些问题。角度对象基本上是 Arc2D 对象的扩展,它提供了一个名为 computeStartAndExtent() 的附加方法。在我的 Angle class 中,此方法计算并找到必要的起始角和扩展角值:

private void computeStartAndExtent()
    {
        double ang1 = Math.toDegrees(Math.atan2(b1.getY2() - b1.getY1(), b1.getX2() - b1.getX1()));
        double ang2 = Math.toDegrees(Math.atan2(b2.getY2() - b2.getY1(), b2.getX2() - b2.getX1()));

        if(ang2 < ang1)
        {
            start = Math.abs(180 - ang2);
            extent = ang1 - ang2;
        }
        else
        {
            start = Math.abs(180 - ang1);
            extent = ang2 - ang1;
        }
        start -= extent;
    }

这是一个有点错误的代码,只有当我将两条线相互连接时才有效,但是,当我连接第三条线形成三角形时,结果如下所示,

如您所见,ADB 角是唯一放置正确的角。我不知道如何克服这个问题。如果您需要一些额外的 info/code 请告诉我。

编辑: b1 和 b2 是 computeStartAndExtent() 方法中的 Line2D 对象。

谢谢。

可以做一些事情来简化计算:

  • 保持顶点有序,以便始终清楚如何计算远离角的顶点角度
  • 此外,始终将多边形绘制到同一方向;那么你总是可以把角度画到同一个方向。下面的示例假定多边形是顺时针绘制的。给定逆时针绘制的多边形,相同的角度计算将导致绘制在外侧的弧。

示例代码;与你的不太一样,因为我没有你的代码,但具有相似的功能:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.Arc2D;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Polygon extends JPanel {
    private static final int RADIUS = 20;

    private final int[] xpoints = {
            10, 150, 80, 60
    };
    private final int[] ypoints = {
            10, 10, 150, 60
    };
    final Arc2D[] arcs;

    Polygon() {
        arcs = new Arc2D[xpoints.length];
        for (int i = 0; i < arcs.length; i++) {
            // Indices of previous and next corners
            int prev = (i + arcs.length - 1) % arcs.length;
            int next = (i + arcs.length + 1) % arcs.length;
            // angles of sides, pointing outwards from the corner
            double ang1 = Math.toDegrees(Math.atan2(-(ypoints[prev] - ypoints[i]), xpoints[prev] - xpoints[i]));
            double ang2 = Math.toDegrees(Math.atan2(-(ypoints[next] - ypoints[i]), xpoints[next] - xpoints[i]));
            int start = (int) ang1;
            int extent = (int) (ang2 - ang1);
            // always draw to positive direction, limit the angle <= 360
            extent = (extent + 360) % 360;
            arcs[i] = new Arc2D.Float(xpoints[i] - RADIUS, ypoints[i] - RADIUS, 2 * RADIUS, 2 * RADIUS, start, extent, Arc2D.OPEN);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(160, 160);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.drawPolygon(xpoints, ypoints, xpoints.length);
        Graphics2D g2d = (Graphics2D) g;
        for (Shape s : arcs) {
            g2d.draw(s);
        }
    }

    public static void main(String args[]){
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Polygon");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new Polygon());
                frame.pack();
                frame.setVisible(true);
            }
        });
    }
}

结果: