如何绘制圆的半径而不短于或大于圆周

How to draw the radius of a circle without it being shorter or larger than the circumference

我正在开发一个程序,我想在其中绘制一条从圆心到参数点的线。但是它在圆周外和圆周内画线。我想根据 XY 角度精确地在圆周上画线。

圆心点数:

x = 200
y = 100
radius= 100

public SecondActivity(String azim,String ele) {
    initialize();
    setTitle("My WIndow");`

    angle_x = Integer.parseInt(azim);
    angle_y = Integer.parseInt(ele);

    x = 200+r*Math.cos(angle_x);
    y = 100+r*Math.sin(angle_y);      
}

public void paint(Graphics g) {
    super.paint(g);

    drawCircle(g,200,100,r);
    drawLine(g);
}

public void drawCircle(Graphics g,int x,int y,int r) {
    g.setColor(Color.BLACK);
    g.drawOval(x, y, r*2,r*2);
}
public void drawLine(Graphics g) {
    Graphics2D g2d = (Graphics2D) g;    
    g2d.setColor(Color.BLUE);
    g2d.draw(new Line2D.Double(300.0d,200.0d,x,y));
}

您的代码(和逻辑)中有几个错误:

  1. 您正在使用 2 个角度来计算 XY 坐标,因此,给您带来奇怪的结果。根据这张 Wikipedia 图片,机器人坐标的角度 theta 是相同的。

  2. 您使用的角度是度数,但是 Math.cos(angle)Math.sin(angle) 要求 angle 以弧度表示,因此,您必须将弧度的角度,如 Math.roRadians(angle),如以下问题所示:How to use Math.cos() & Math.sin()?

  3. 不是真正的错误,而是来自 中@MadProgrammer 的建议,使用形状 API 而不是像您在画线时所做的那样使用纯 .drawOval , 将 drawOval 更改为 draw(new Ellipse2D.Double(...)).

  4. 您正在覆盖 paint(Graphics g) 方法而不是 paintComponent(Graphics g) 这可能会在绘画时导致一些问题。使用 JPanels 并覆盖他们的 paintComponent 方法并将这些 JPanel 添加到您的 JFrame.

综上所述,我找到了一个很好的例子,它遵循了上述建议并解决了问题:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;

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

public class RadiusDrawer {
    private JFrame frame;
    private int centerX = 50;
    private int centerY = 50;
    private int x = 0;
    private int y = 0;
    private int r = 100;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new RadiusDrawer()::createAndShowGui);
    }

    private void createAndShowGui() {
        frame = new JFrame(getClass().getSimpleName());

        frame.add(new MyCircle());
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    @SuppressWarnings("serial")
    class MyCircle extends JPanel {
        int cx = 0;
        int cy = 0;
        public MyCircle() {
            int angle = 0;

            x = (int) (r * Math.cos(Math.toRadians(angle)));
            y = (int) (r * Math.sin(Math.toRadians(angle)));

            y *= -1; //We must inverse the Y axis since in Math Y axis starts in the bottom while in Swing it starts at the top, in order to have or angles correctly displayed, we must inverse the axis

            calculateCenter();
        }

        private void calculateCenter() {
            cx = centerX + r;
            cy = centerY + r;
        }

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

            drawCircle(g2d, centerX, centerY, r);
            drawRadius(g2d);
        }

        private void drawCircle(Graphics2D g2d, int x, int y, int r) {
            g2d.setColor(Color.BLACK);
            g2d.draw(new Ellipse2D.Double(x, y, r * 2, r * 2));
        }

        private void drawRadius(Graphics2D g2d) {
            g2d.setColor(Color.BLUE);
            g2d.draw(new Line2D.Double(cx, cy, cx + x, cy + y));
        }

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

以下是 0、60 和 90 度输出的一些屏幕截图。