Java 不能画圆,尽管用逻辑的方法
我试着用JavaAWT绘制一个圆,我在输出中得到的只是几个小的圆,它们之间相隔很远,看起来不像一个圆。代码如下: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 =
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++;
}
}
}