1

我正在开发一个程序,我想在其中画一条从圆心到它的参数点的线。但它在圆周外和内圆周上画线。我想根据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));
}
4

1 回答 1

2

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

  1. 您正在使用 2 个角度来计算XY坐标,因此会给您带来奇怪的结果。根据此维基百科图像,机器人坐标的角度 theta 相同。

    在此处输入图像描述

  2. 您正在使用以度为单位的角度,但Math.cos(angle)要求Math.sin(angle)angle弧度为单位,因此,您必须将角度转换为弧度Math.roRadians(angle),如以下问题所示:如何使用 Math.cos() & Math.sin( )?

  3. 不是真正的错误,而是@MadProgrammer 在我的另一个答案中的建议,即使用 Shape API 而不是.drawOval像您在画线时所做的那样纯,更改drawOvaldraw(new Ellipse2D.Double(...)).

  4. 您正在覆盖paint(Graphics g)方法而不是paintComponent(Graphics g)此方法可能会在绘画时导致一些问题。使用JPanels并覆盖他们的paintComponent方法并将那些JPanels 添加到您的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 度输出的一些屏幕截图。

在此处输入图像描述 在此处输入图像描述 在此处输入图像描述

于 2018-01-31T18:12:44.637 回答