簡體   English   中英

Graphics2D 和 java.awt.geom.Area 中 1 個像素的問題

[英]issues with 1 pixel in Graphics2D and java.awt.geom.Area

我有 2 個坐標數組,基於這些坐標我構造了一個多邊形。 稍后如果我繪制這個多邊形,我會繪制 5x5 像素(應該是)。 但是當我使用多邊形作為參數構造 java.awt.geom.Area 時,結果區域是 4x4 像素。 由於某種原因,結果區域的高度和寬度小 1 個像素

為什么會發生? 如何解決這個問題? 而且我不能只向某些多邊形頂點的坐標添加 1 個像素。 再一次,我需要從現有的多邊形創建一個包含多邊形所有頂點的區域對象

int[] xpoints={50,54,54,50};
int[] ypoints={50,50,54,54};
int npoints=4;
Polygon p=new Polygon(xpoints,ypoints,npoints);
visible= new Area(p);
blackArea.subtract(visible);

此外,如果我沒有記錯的話,如果我創建並繪制一個 Rectangle2D.Float 5x5 那么它將占用 6x6 區域。 我顯然錯過了一些東西。 非常感謝您的幫助

您提到了繪制多邊形。 在這種情況下,必須考慮到您所繪制的線正好位於像素(!)之間。 並且,如果線條的寬度為1.0(使用默認筆觸),則將導致觸摸5x5像素。 與此相反,當您真正填充多邊形時,它實際上應該僅占據4x4像素。

無論如何,由Area計算的結果應與Shape類中“內部”定義一致

下圖顯示了放大的“像素”:中間的紅色像素是矩形多邊形(位置(2,2),大小(4,4))中包含的像素。 藍色像素是包含在其中減去了多邊形的Area中的像素。 如果兩種形狀中都包含任何像素,則這些像素將被塗成洋紅色。

綠色,半透明的“疊加層”顯示多邊形實際生成的圖形 (如果顯示器能夠顯示出來的話):線條在像素之間的邊界處,但寬度為1.0。

在此處輸入圖片說明

編碼:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Point2D;

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

public class ContainsTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(new ContainsTestPanel());
        f.setSize(500, 500);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

}

class ContainsTestPanel extends JPanel
{
    @Override
    protected void paintComponent(Graphics gr)
    {
        super.paintComponent(gr);
        Graphics2D g = (Graphics2D)gr;
        g.setColor(Color.WHITE);
        g.fillRect(0,0,getWidth(), getHeight());

        int[] xpoints={2,6,6,2};
        int[] ypoints={2,2,6,6};
        int npoints=4;
        Polygon p=new Polygon(xpoints,ypoints,npoints);
        Area visible = new Area(p);
        Area blackArea = new Area(new Rectangle(0,0,8,8));
        blackArea.subtract(visible);

        int size = 50;
        for (int x=0; x<8; x++)
        {
            for (int y=0; y<8; y++)
            {
                Point2D point = new Point(x,y);
                boolean inPoly = p.contains(point);
                boolean inArea = blackArea.contains(point);
                System.out.println(x+" "+y+" inPoly: "+inPoly+" inArea "+inArea);

                if (!inPoly && !inArea)
                {
                    g.setColor(Color.GRAY);
                }
                if (inPoly && !inArea)
                {
                    g.setColor(Color.RED);
                }
                if (!inPoly && inArea)
                {
                    g.setColor(Color.BLUE);
                }
                if (inPoly && inArea)
                {
                    g.setColor(Color.MAGENTA);
                }
                int rx = x * size;
                int ry = y * size;
                g.fillRect(rx, ry, size, size);
                g.setColor(Color.BLACK);
                g.drawString(x+","+y, rx, ry);
                g.drawRect(rx, ry, size, size);
            }
        }

        //g.setStroke(new BasicStroke(1.0f/size));
        AffineTransform at = g.getTransform();
        g.scale(size, size);
        g.setColor(new Color(0,255,0,128));
        g.draw(p);
        g.setTransform(at);

    }
}

如果只想處理矩形中的像素,則可能需要一種“手動”解決方案。

也許這篇文章會有所幫助。 為什么Graphics的draw方法不尊重筆觸屬性?

或者,如果您只是在尋找圖形學的理論,那么這篇文章可能會對http://www.antigrain.com/tips/line_alignment/line_alignment.agdoc.html有所幫助

經驗法則是不要在AntiAliasing大聲笑中使用單像素線

希望這可以幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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