Java 不能画圆,尽管用逻辑的方法

Java 不能画圆,尽管用逻辑的方法,java,swing,java-2d,Java,Swing,Java 2d,我试着用JavaAWT绘制一个圆,我在输出中得到的只是几个小的圆,它们之间相隔很远,看起来不像一个圆。代码如下: class DrawFrame extends JFrame { int хс, yc, r, x, y; float p; DrawFrame(int rr, int c1, int c2) { setSize(1000, 1000); setTitle("circle drawing algo"); r =

我试着用JavaAWT绘制一个圆,我在输出中得到的只是几个小的圆,它们之间相隔很远,看起来不像一个圆。代码如下:

class DrawFrame extends JFrame {
    int хс, yc, r, x, y;
    float p;
    DrawFrame(int rr, int c1, int c2) {
        setSize(1000, 1000);
        setTitle("circle drawing algo");
        r = rr;
        xc = c1;
        yc = c2;
    }
    public void paint(Graphics g) {
        Circl(g);
    }
    public void Circl(Graphics g) {
        x = xc - r;
        while (x <= (xc + r)) {
            for (y = yc - r; y <= (yc + r); y++) {
                p = x * x + y * y - r * r;
                if (p == 0.0)
                    g.drawOval(x, y, 2, 2);
            }
            x++;
        }
    }
class DrawFrame扩展了JFrame{
intБС,yc,r,x,y;
浮动p;
牵引架(内部rr、内部c1、内部c2){
设置大小(10001000);
setTitle(“圆形绘图算法”);
r=rr;
xc=c1;
yc=c2;
}
公共空间涂料(图g){
圈(g);
}
公共无效圆圈(图g){
x=xc-r;

而(x我对您的代码进行了一些编辑,并对绘制算法进行了一些更改,以便完全绘制圆。以下是重构代码:

class DrawFrame extends JFrame {
    int xc, yc, r, x, y;
    float p;
    DrawFrame(int rr, int c1, int c2) {
        setSize(1000, 1000);
        setTitle("circle drawing algo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Handles the window being closed
        setVisible(true); // Makes the window visible
        r = rr;
        xc = c1;
        yc = c2;
    }
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;
        GradientPaint gp = new GradientPaint(0f,0f,Color.blue,0f,30f,Color.green); // Just sets a color for the paint
        g2.setPaint(gp);
        Circl(g2); 
    }
    public void Circl(Graphics g) {
        x = xc-r;
        while (x <= (xc+r)) {
            for (y = yc-r; y <= (yc+r); y++) {
                p = (x-xc)*(x-xc)+(y-yc)*(y-yc)-(r*r); // Edited this line so that it’s now the correct circle formula
                if (p <= 0.0f) // If the point is 0 or less, then the point is within the circle bounds
                    g.drawOval(x, y, 2, 2);
            }
            x++;
        }
    }
    public static void main(String[] args) {
        new DrawFrame(100, 500, 500);
    }
}

你应该先阅读并更好地理解绘画系统是如何工作的,以及你应该如何使用它

您不应该覆盖顶层组件的
绘制方法,除了没有双缓冲外,它们实际上是复合组件。这意味着它们上面有许多其他组件,这些组件提供了窗口的整体功能

这意味着,您在框架表面绘制的内容可能会被忽略,因为框架顶部的内容会在框架上绘制

您还忽略了绘制过程的复杂性,除非您准备自己承担
paint
方法的责任,否则您应该始终将其称为
super
方法

一个更好的起点是使用
JPanel
(更简单)并覆盖其
paintComponent
方法

导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共班机{
公共静态void main(字符串[]args){
新的Main();
}
公用干管(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(新的测试窗格(100100100));
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
int xc,yc,r;
公共测试窗格(内部rr、内部c1、内部c2){
r=rr;
xc=c1;
yc=c2;
}
@凌驾
公共维度getPreferredSize(){
返回新维度(r*2,r*2);
}
@凌驾
受保护组件(图形g){
超级组件(g);
圆圈(g);
}
公共空间圆圈(图g){
//算法更新归功于LAD
int x=xc-r;

而(x改变的第一件事是通过添加
setVisible(true);
到其构造函数。
建议使用具有明确含义的名称,以使代码更具可读性。尽可能限制字段的范围,在这种情况下,将其设置为私有:

private int сenterX, centerY, radius; 
(x、y和p是方法变量,不需要是字段)
避免使用。请改用常量:

private static final int W = 1000, H = 1000, DOT_SIZE =2 ;
使用正确的算法将其组合在一起:

import java.awt.Graphics; //add imports to make tour code mcve
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

class DrawFrame extends JFrame {

    private final int сenterX, centerY, radius;
    private static final int W = 1000, H = 1000, DOT_SIZE =2 ;

    DrawFrame(int radius, int centerX, int centerY) {
        setSize(W, H);
        setTitle("circle drawing algo");
        this.radius = radius;
        сenterX = centerX;
        this.centerY = centerY;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//make program stop when closing frame
        setVisible(true); //make frame visible
    }

    @Override
    public void paint(Graphics g) {
       super.paint(g); 
       circl(g);
    }

    public void circl(Graphics g) {
        int x, y;
        x = сenterX - radius;
        while (x <= сenterX + radius) {
           //calculate x 
           y = (int)Math.sqrt(radius*radius - (сenterX -x)*(сenterX -x ));
           g.drawOval(x, centerY-y, 2, 2); // 2 y values for every x 
           g.drawOval(x, centerY+y, 2, 2);
           x++;
       }
    }

    // add main to make your code mcve 
    public static void main(String[] args) {
        SwingUtilities.invokeLater(()-> new DrawFrame(100, 400, 400));
    }
}
将x的初始值设置为x=xc-r,y设置为y=yc-r。然后 将笛卡尔坐标转换为极坐标,如p=x*x+y*y-r* 假设如果xc=500,yc=500,r=50,“p”永远不会是0 我想你在画图的时候忘了计算xc,yc。我修改了你的 编码一点点并附上结果

包测试项目;
导入java.awt.*;
导入javax.swing.*;
公共类DrawFrame扩展了JPanel{
int xc=500,yc=500,r=150,x,y;
int real_x,real_y;
浮动p;
公共静态void main(字符串[]args){
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame=新的JFrame(“圆形绘图算法”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
框架.立根背景(颜色.白色);
框架。设置尺寸(10001000);
DrawFrame面板=新的DrawFrame();
框架。添加(面板);
frame.setVisible(true);
}
公共空间涂料(图g){
圈(g);
}
公共无效圆圈(图g){
x=-r;

while(x)你试过增大椭圆的大小吗?现在你正在把它们画成3像素乘3像素。顺便说一下,你知道吗?你需要使JFrame可见`setVisible(true)59
private static final int W = 1000, H = 1000, DOT_SIZE =2 ;
import java.awt.Graphics; //add imports to make tour code mcve
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

class DrawFrame extends JFrame {

    private final int сenterX, centerY, radius;
    private static final int W = 1000, H = 1000, DOT_SIZE =2 ;

    DrawFrame(int radius, int centerX, int centerY) {
        setSize(W, H);
        setTitle("circle drawing algo");
        this.radius = radius;
        сenterX = centerX;
        this.centerY = centerY;
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//make program stop when closing frame
        setVisible(true); //make frame visible
    }

    @Override
    public void paint(Graphics g) {
       super.paint(g); 
       circl(g);
    }

    public void circl(Graphics g) {
        int x, y;
        x = сenterX - radius;
        while (x <= сenterX + radius) {
           //calculate x 
           y = (int)Math.sqrt(radius*radius - (сenterX -x)*(сenterX -x ));
           g.drawOval(x, centerY-y, 2, 2); // 2 y values for every x 
           g.drawOval(x, centerY+y, 2, 2);
           x++;
       }
    }

    // add main to make your code mcve 
    public static void main(String[] args) {
        SwingUtilities.invokeLater(()-> new DrawFrame(100, 400, 400));
    }
}
class DrawFrame extends JFrame {

    DrawFrame(int radius, int centerX, int centerY) {
        setTitle("circle drawing algo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//make program stop when closing frame
        add(new DrawingPane(radius, centerX, centerY));
        pack();
        setVisible(true); //make frame visible
    }

    // add main to make your code mcve
    public static void main(String[] args) {
        SwingUtilities.invokeLater(()-> new DrawFrame(100, 400, 400));
    }
}

class DrawingPane extends JPanel{

    private final int сenterX, centerY, radius;
    private static final int W = 1000, H = 1000, DOT_SIZE =2 ;

    DrawingPane(int radius, int centerX, int centerY) {
        setPreferredSize(new Dimension(W, H));
        this.radius = radius;
        сenterX = centerX;
        this.centerY = centerY;
    }

    @Override
    public void paintComponent(Graphics g){
        super.paintComponent(g);
        g.drawOval(сenterX, centerY, radius, radius);
    }
}
package testProject;
import java.awt.*;
import javax.swing.*;

public class DrawFrame extends JPanel {
    int xc=500, yc=500, r=150, x, y;
    int real_x, real_y;
    float p;

    public static void main(String[] args) {
        JFrame.setDefaultLookAndFeelDecorated(true);
        JFrame frame = new JFrame("circle drawing algo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBackground(Color.white);
        frame.setSize(1000, 1000);
        DrawFrame panel = new DrawFrame();
        frame.add(panel);
        frame.setVisible(true);
    }



    public void paint(Graphics g) {
        Circl(g);
    }
    public void Circl(Graphics g) {
        x = -r;
        while (x <= r) {
            y = -r;
            while (y <= r) {
                p = x * x + y * y - r * r;
                // here is the change
                if (p>=0 && p<= xc) {
                    g.drawOval(x+xc, y+yc, 3, 3);
                }
                y++;
            }
            x++;
        }
    }
}