gpt4 book ai didi

java - java中有没有一种方法可以绘制一个以双变量为中心的圆?

转载 作者:行者123 更新时间:2023-12-01 19:43:43 25 4
gpt4 key购买 nike

这里我尝试使用drawOval方法绘制一个圆,并且我想以特定的速度在屏幕上移动它。但我对速度的双变量有疑问。例如,当 vx=0.25 且 vy=0 时,圆就卡在其位置上。不过,抱歉我的英语不好。

这是我正在使用的java代码

 int x=0 , y=0;
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
move();
g.drawOval(x, y, 10, 10);
repaint();
}
public void move() {
x+=0.25;
y+=0.25;
}

最佳答案

  • 您不应该从 paintComponent 方法中调用 move!你永远不知道这个方法什么时候会被调用,因此你无法正确控制移动速度。
  • 您不应该从 paintComponent 方法中调用 repaint! 从不。这将使绘画系统陷入重绘操作的​​无限循环!
<小时/>

关于问题:

有一种基于双坐标绘制任意形状的方法。 2D Graphics Tutorial 中也对此进行了广泛的介绍和解释。 。关键是使用 Shape 接口(interface)。对于您的特定示例,代码的相关部分是这样的:

private double x = 0;
private double y = 0;

@Override
public void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;

double radius = 5;
g.draw(new Ellipse2D.Double(
x - radius, y - radius, radius * 2, radius * 2));
}

也就是说,您创建一个 Ellipse2D 实例,然后绘制它。

这是一个 MVCE,显示了您可能想要完成的任务:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;

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

public class PaintWithDouble
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGui());
}

private static void createAndShowGui()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

PaintWithDoublePanel p = new PaintWithDoublePanel();
f.getContentPane().add(p);
startMoveThread(p);

f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}

private static void startMoveThread(PaintWithDoublePanel p)
{
Thread t = new Thread(() -> {
while (true)
{
p.move();
p.repaint();
try
{
Thread.sleep(20);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
return;
}
}
});
t.setDaemon(true);
t.start();
}
}

class PaintWithDoublePanel extends JPanel
{
private double x = 0;
private double y = 0;

@Override
public void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);

double radius = 5;
g.draw(new Ellipse2D.Double(
x - radius, y - radius, radius * 2, radius * 2));

g.drawString("At " + x + ", " + y, 10, 30);
}

public void move()
{
x += 0.05;
y += 0.05;
}

}
<小时/>

针对评论进行编辑(并澄清其他答案中已说过的一些事情):

虽然技术上说“只有整个像素”并且“没有坐标为(0.3,1.8)的像素”是正确的,但这并不意味着分数坐标不会影响渲染的最终外观输出。当你研究足够长的时间时,每个主题都会成为一门科学。特别是,大量研究涉及如何改善渲染输出的视觉外观的问题,超出了通过简单的 Bresenham 所能实现的目标。或者。进一步研究的切入点可能是关于 subpixel rendering 的文章.

在许多情况下,像往常一样,外观和绘图性能之间存在权衡。对于 Java 及其 2D 绘图功能,这些权衡主要通过 RenderingHints 类来控制。例如,有 RenderingHints#VALUE_STROKE_PURE启用子像素渲染。效果如以下屏幕截图所示:

Subpixel

slider 用于将水平线最右点的 y 偏移量更改 -3 到 +3 像素。在左上角,您会看到一条按原样渲染的线。在中间,您会看到该线放大了 8 倍,以更好地显示效果:像素填充有不同的不透明度,具体取决于理想化的 1 像素宽线覆盖了多少像素.

虽然这确实与大多数应用案例无关,但这里可能值得注意。

以下是用于屏幕捕获的 MCVE:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;

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

public class PaintWithDoubleMagnified
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGui());
}

private static void createAndShowGui()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());

PaintWithDoubleMagnifiedPanel p = new PaintWithDoubleMagnifiedPanel();
f.getContentPane().add(p, BorderLayout.CENTER);

JSlider slider = new JSlider(0, 100, 50);
slider.addChangeListener(e -> {
int value = slider.getValue();
double relative = -0.5 + value / 100.0;
p.setY(relative * 6);
});
f.getContentPane().add(slider, BorderLayout.SOUTH);

f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}

class PaintWithDoubleMagnifiedPanel extends JPanel
{
private double y = 0;

@Override
public void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;

g.drawString("At " + y, 10, 20);
paintLine(g);

BufferedImage image = paintIntoImage();
g.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
g.scale(8.0, 8.0);
g.drawImage(image, 0, 0, null);

}

public void setY(double y)
{
this.y = y;
repaint();
}

private void paintLine(Graphics2D g)
{
g.setColor(Color.BLACK);
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(
RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);

Line2D line = new Line2D.Double(
10, 30, 50, 30 + y);
g.draw(line);

}

private BufferedImage paintIntoImage()
{
BufferedImage image = new BufferedImage(
100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
paintLine(g);
g.dispose();
return image;
}

}

关于java - java中有没有一种方法可以绘制一个以双变量为中心的圆?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54369506/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com