绘制多个圆的问题(drawOval/Java)
我的问题如下:我的实际项目(下面的代码是的简化版本)涉及许多同心圆(每个同心圆都有不同的颜色)和使用计时器的动画。使用Draw椭圆形方法绘制圆 我的问题是,当绘制这些同心圆时,这些圆的轮廓上似乎有大量的间隙,我猜这与一个事实有关,即一个圆和任何形状一样由像素和线组成,因此圆的外观是一种错觉。我这样说是因为当我将drawOval方法替换为drawRect时,这幅画看起来就像你所期望的那样 当与其他人的代码混在一起时,我看到使用渲染提示以某种方式解决了这个问题,但却使动画速度减慢,超出了我认为可以接受的程度 下面是所画内容的屏幕截图。我们看到的不是实心不透明圆(因为在本例中绘制的所有圆都具有相同的颜色),而是: 这是我的简化代码:绘制多个圆的问题(drawOval/Java),java,graphics,paintcomponent,Java,Graphics,Paintcomponent,我的问题如下:我的实际项目(下面的代码是的简化版本)涉及许多同心圆(每个同心圆都有不同的颜色)和使用计时器的动画。使用Draw椭圆形方法绘制圆 我的问题是,当绘制这些同心圆时,这些圆的轮廓上似乎有大量的间隙,我猜这与一个事实有关,即一个圆和任何形状一样由像素和线组成,因此圆的外观是一种错觉。我这样说是因为当我将drawOval方法替换为drawRect时,这幅画看起来就像你所期望的那样 当与其他人的代码混在一起时,我看到使用渲染提示以某种方式解决了这个问题,但却使动画速度减慢,超出了我认为可以接
Test10
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Test10 extends JPanel {
Circle[] circles;
public static void main(String[] args) {
new Test10().go();
}
void go() {
JFrame frame = new JFrame("Circle Test");
frame.getContentPane().add(this);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
circles = new Circle[200];
for (int i = 0; i < 200; i++) {
circles[i] = new Circle(i, ((2 * ( 200 - i) + 1)));
}
repaint();
frame.setPreferredSize(new Dimension(500,500));
frame.pack();
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
for (Circle circle : circles ) {
circle.draw(g);
}
}
}
谁能给我解释一下a)为什么会发生这种情况,b)如何克服这个问题。更新
尝试了各种方法,包括从最外面的圆开始,使用fillOval而不是drawOval,使用更高的笔划值,我仍然发现某些人工制品与Pavel发布的屏幕截图相似,存在问题。这是我运行动画的完整应用程序的一个屏幕截图,如果你仔细看,你可以看到大部分给定圆的颜色不一致,导致这些奇怪的结果。它们的分布实际上遵循与上面发布的屏幕截图相同的模式,因此很明显,这些选项没有解决一些基本问题。这是我的屏幕截图:
您可以尝试在Circle类的内部绘制函数中添加这条线:
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//and draw the Oval on g2
另一种解决方案可能是填充圆圈:
Ellipse2D.Double circle = new Ellipse2D.Double(x, y, diameter, diameter);
g2.fill(circle);
你可能想做得更大一些。在类似于你的情况下,我很幸运地做到了这一点,因为计算机无法画出一个完美的圆 计算机使用正方形像素来近似真实的圆,但不可能达到完美,这会导致某些像素无法显示 画一个圆会对你有帮助
你能试一下倒圆法而不是倒圆法吗
g.fillOval(topLeft, topLeft, diameter, diameter);
画完美的圆是不可能的 尝试使用以下方法
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(2));
int i = 0;
for (Circle circle : circles ) {
Shape circle2 = new Ellipse2D.Double(i++, i, circle.diameter, circle.diameter);
g2d.draw(circle2);
}
}
你说你尝试了渲染提示
,这减慢了你的动画速度,但你没有给我们任何动画代码,所以也许可以试试我的代码(最好看看动画实现)。看起来好多了,但仍然不是你想要的。将笔划设置为另一个值将解决此问题(至少设置为2)。另一种方法是使用.fill()
而不是.draw()
。我知道它并不完美,但你可以试试
另一个想法
我想,也许你可以给你的图像添加一些模糊,这样那些伪影就看不见了?
我以前没有做过,但我发现了这个():
现在,在go()
方法中:
frame.setGlassPane(new BlurGlass(frame));
frame.getGlassPane().setVisible(true);
对我来说好多了。使用此玻璃窗格颜色玩一玩(尝试将.3f更改为其他值)
改变你的想法。从最外面的圆开始,然后画内圈,以此类推,最后画最小的圆。在此过程中,您应该使用
fillOval
。对于圆/椭圆通常有用的另一个渲染提示是
g.setRenderingHint( RenderingHints. KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
看看我的。画一个填充圆或两个同心填充圆不就行了吗?看看我的文章的顶部,在完整的应用程序中,每个圆都有不同的颜色,创建了一系列漂亮的同心圆。这就是我不使用Fillova的原因,不管怎样,谢谢:你是否从Futurama实现了hypnotoad?;-)我的比你的好。我在你的丝网印刷上看到的那些对称的手工艺品是不可取的。谢谢你的回答,虽然到目前为止似乎是最有用的。是的,我也得到了这些人工制品,关于如何去除它们的任何线索?谢谢稍后会有一个游戏,看起来很有希望。尝试一下,我对我的原始帖子进行了更新,以显示这会带来什么样的结果,因为它们并不理想。这种方法当然有帮助,但它仍然存在一个问题。谢谢你的帮助,如果你能看一下更新,我将不胜感激:)嗨,谢谢,我实际上已经尝试过这种方法,虽然它在小范围内工作,但当涉及到大量不同的颜色时,它会产生有趣的人工制品。我已经编辑了我的问题,将此信息与另一个屏幕截图一起包括在内。再次感谢,这是因为填充椭圆填充圆,并且圆的半径之间存在很大差异。如果你想画一个有厚边框的空圆(有一个完美的圆),那么你可以在圆角内画一个半径几乎相同的椭圆。谢谢你的回复。两个圆的半径相差很大?相邻圆的半径相差1,所以我不太明白你的意思…哦,我没听清楚。不过,试试我改进后的想法,可能会有帮助。正如我所怀疑的,非常感谢。我的问题还没有解决,我已经为我的问题添加了详细信息,如果您仍然有兴趣帮助,非常感谢该链接,稍后将有一个很好的阅读!感谢您的帮助,有关问题持续存在的原因的详细信息,请参阅更新。非常好的建议,尽管我需要熟悉渲染提示。另一种方法是预先确定一些同心圆的图像,并逐渐显示这些图像。可惜这不是一个程序化的解决方案,它可能会给你更好的图形。嗯,完整的应用程序是一个动画
frame.setGlassPane(new BlurGlass(frame));
frame.getGlassPane().setVisible(true);
g.setRenderingHint( RenderingHints. KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);