Graphics2D和java.awt.geom.Area中的1个像素的问题

时间:2014-04-03 17:18:37

标签: java pixel graphics2d

我有2个坐标数组,基于它构造一个多边形。稍后如果我绘制这个多边形,我会得到5x5像素(应该是这样)。但是当我使用多边形作为参数构造java.awt.geom.Area时,结果区域是4x4像素。由于某种原因,所得区域的高度和宽度小1个像素

为什么会这样?如何解决这个问题?我不能只为一些多边形顶点添加1个像素'坐标。再一次,我需要的是从现有的Polygon创建一个Area对象,包括多边形的所有顶点

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区域。我显然遗漏了一些东西。非常感谢你的帮助

2 个答案:

答案 0 :(得分:1)

您提到您绘制多边形。在这种情况下,您必须考虑使用(!)像素之间的线绘制。如果该行的宽度为1.0(使用默认笔划),则会触发5x5像素。与此相反,当你真正填充多边形时,它应该只占用4x4像素。

在任何情况下,Area计算的结果都应与definition of "insideness" in the Shape class一致。

下图显示"像素"放大:中心的红色像素是包含在矩形多边形中的像素(位置(2,2),大小(4,4))。蓝色像素是包含在Area中的像素,从中减去多边形。如果两个形状中都包含任何像素,那么这些像素将用洋红色绘制。

绿色,半透明"叠加"显示多边形实际会产生的绘图(如果显示能够显示):这些线位于像素之间的边界,但宽度为1.0。

enter image description here

代码:

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);

    }
}

如果你只想处理矩形中的像素,可能会有一个&#34;手册&#34;您希望实现的解决方案。

答案 1 :(得分:0)

也许这篇文章会有所帮助 Why doesn't the Graphics' draw method respect stroke attributes?

或者如果你只是在寻找关于图形的理论,也许这篇文章会有所帮助 http://www.antigrain.com/tips/line_alignment/line_alignment.agdoc.html

经验法则不是使用具有AntiAliasing的单像素行lol

希望这有帮助