[英]Issues with drawing multiple circles (drawOval / Java)
我的問題如下:我的實際項目(下面的代碼是簡化版本)涉及許多同心圓(每個都有不同的顏色)和利用Timer的動畫。 使用drawOval方法繪制圓圈。
我的問題是,當繪制這些同心圓時,這些圓的輪廓中似乎存在大量的間隙,我猜這與圓形由像素和線組成的事實有關,就像任何形狀一樣所以圓度的出現是一種幻覺。 我這樣說是因為當我為drawRect交換drawOval方法時,繪畫看起來就像你期望的那樣。
當弄亂其他人的代碼時,我看到使用RenderingHints以某種方式解決了這個問題,但是動畫速度超出了我覺得可以接受的程度。
下面是繪制內容的屏幕截圖。 我們看到的不是看到一個堅固的不透明圓圈(因為在這個例子中繪制的所有圓圈都具有相同的顏色),
這是我的簡化代碼:
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);
}
}
}
圈
import java.awt.Graphics;
public class Circle {
int topLeft;
int diameter;
public Circle(int topLeft, int diameter) {
this.topLeft = topLeft;
this.diameter = diameter;
}
void draw(Graphics g) {
g.drawOval(topLeft, topLeft, diameter, diameter);
}
}
任何人都可以向我解釋a) 為什么會發生這種情況和b) 如何克服這個問題。
UPDATE
嘗試了各種方法,包括從最外圈開始並使用fillOval而不是drawOval ,並使用更高的筆畫值,我仍然發現我遇到的問題與某些人工制品的出現類似於Pavel發布的截圖。 這是我運行動畫的完整應用程序的截圖,如果你仔細觀察,你會發現大多數給定圓圈的顏色不一致,導致這些奇怪的結果。 它們的分布實際上遵循與上面發布的屏幕截圖相同的模式,因此這些選項無法解決基本問題。 這是我的屏幕截圖:
畫出完美的圓圈是不可能的。
嘗試使用以下方法
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);
}
}
你說你試過RenderingHints
,它減慢了你的動畫,但是你還沒有給我們帶動畫的代碼,所以也許試試我的代碼(看動畫實現會很好)。 它看起來更好,但仍然不是你想要的。 將筆划設置為另一個值將解決此問題(設置為至少2)。 另一個是使用.fill()
而不是.draw()
。 我知道它並不完美,但你可以嘗試一下。
另一個想法
我想,也許你可以為你的圖像添加一些模糊,所以這些文物是不可見的? 我之前沒有這樣做過,但我找到了這個( 在這里找到 ):
private class BlurGlass extends JComponent {
private JFrame f;
public BlurGlass(JFrame f) {
this.f = f;
setOpaque(false);
setFocusable(false);
}
public void paintComponent(Graphics g) {
int w = f.getWidth();
int h = f.getHeight();
setLocation(0, 0);
setSize(w, h);
g.setColor(new Color(0, 0, 0, 0.3f));
g.fillRect(0, 0, w, h);
}
}
現在在go()
方法中的somwhere:
frame.setGlassPane(new BlurGlass(frame));
frame.getGlassPane().setVisible(true);
對我來說看起來好多了。 使用此GlassPane顏色播放一下(嘗試將.3f更改為其他值)。
你可能想讓Stroke更大。 在類似於你的情況下,我很幸運
您可以嘗試在Circle類中的draw類中添加此行:
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);
你能不能試試fillOval方法而不是drawOval。
g.fillOval(topLeft, topLeft, diameter, diameter);
扭轉你的想法。 從最外面的圓開始,然后繪制內圓等,以最小的圓圈結束。 您應該在此過程中使用fillOval
。
另一個通常對圓/橢圓有用的渲染提示是
g.setRenderingHint( RenderingHints. KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
請參閱我的其他答案,了解更多細節和示例 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.