简体   繁体   English

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

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

I have 2 arrays of coordinates, basing on which i construct a polygon.我有 2 个坐标数组,基于这些坐标我构造了一个多边形。 Later if I draw this polygon, i get drawing 5x5 pixels (as it should be).稍后如果我绘制这个多边形,我会绘制 5x5 像素(应该是)。 BUT when i construct java.awt.geom.Area using the polygon as an argument, resulting area is 4x4 pixels.但是当我使用多边形作为参数构造 java.awt.geom.Area 时,结果区域是 4x4 像素。 For some reason height and width of resulting area are 1 pixel smaller由于某种原因,结果区域的高度和宽度小 1 个像素

Why does it happen?为什么会发生? How to fix this?如何解决这个问题? And I can't just add 1 pixel to some of polygon vertices' coordinates.而且我不能只向某些多边形顶点的坐标添加 1 个像素。 Once more, what do i need is to create from an existing Polygon an Area object that INCLUDES ALL vertices of the polygon再一次,我需要从现有的多边形创建一个包含多边形所有顶点的区域对象

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

Moreover, if i am not mistaking, if i create and draw a Rectangle2D.Float 5x5 then it will take 6x6 area.此外,如果我没有记错的话,如果我创建并绘制一个 Rectangle2D.Float 5x5 那么它将占用 6x6 区域。 I am clearly missing something.我显然错过了一些东西。 Thank you sooo much for any help非常感谢您的帮助

You mentioned that you draw the polygon. 您提到了绘制多边形。 In this case, you have to take into account that you are drawing with the line just between (!) the pixels. 在这种情况下,必须考虑到您所绘制的线正好位于像素(!)之间。 And if the line has a width of 1.0 (with the default stroke), this will cause 5x5 pixels to be touched. 并且,如果线条的宽度为1.0(使用默认笔触),则将导致触摸5x5像素。 In contrast to that, when you really fill the polygon, then it should really occupy only 4x4 pixels. 与此相反,当您真正填充多边形时,它实际上应该仅占据4x4像素。

In any case, the result computed by the Area should be in line with the definition of "insideness" in the Shape class . 无论如何,由Area计算的结果应与Shape类中“内部”定义一致

The following image shows the "pixels" enlarged: The red pixels in the center are the pixels that are contained in a rectangular polygon (position (2,2), size (4,4)). 下图显示了放大的“像素”:中间的红色像素是矩形多边形(位置(2,2),大小(4,4))中包含的像素。 The blue pixels are the pixels that are contained in the Area from which the polygon was subtracted. 蓝色像素是包含在其中减去了多边形的Area中的像素。 IF there were any pixels contained in both shapes, then these would be painted in magenta. 如果两种形状中都包含任何像素,则这些像素将被涂成洋红色。

The green, semi-transparent "overlay" shows what drawing the polygon actually would produce (if the display was capable to show this): The lines are at the border between the pixels, but with a width of 1.0. 绿色,半透明的“叠加层”显示多边形实际生成的图形 (如果显示器能够显示出来的话):线条在像素之间的边界处,但宽度为1.0。

在此处输入图片说明

The code: 编码:

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

    }
}

If you only want to handle pixels in rectangles, there might be a "manual" solution for what you want to achieve. 如果只想处理矩形中的像素,则可能需要一种“手动”解决方案。

Maybe this post will help Why doesn't the Graphics' draw method respect stroke attributes? 也许这篇文章会有所帮助。 为什么Graphics的draw方法不尊重笔触属性?

Or if you are just looking for theory on Graphics maybe this article will help http://www.antigrain.com/tips/line_alignment/line_alignment.agdoc.html 或者,如果您只是在寻找图形学的理论,那么这篇文章可能会对http://www.antigrain.com/tips/line_alignment/line_alignment.agdoc.html有所帮助

Rule of thumb is not to use single pixel lines with AntiAliasing lol 经验法则是不要在AntiAliasing大声笑中使用单像素线

Hope this helps 希望这可以帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM