簡體   English   中英

繪制多個圓圈的問題(drawOval / Java)

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM