繁体   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