[英]NotSerializableException with java.awt.geom.Area
[英]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.