java - 使用 Arc2D 创建的 java.awt.Shape 中负边界坐标的含义

标签 java swing java-2d

我在 Graphics 上下文中绘制 java.awt.Shape 并将其显示给用户。为了定位图形上下文并调整其大小,我使用了我创建的库中的形状边界。这对于我生成的大多数形状都很有效。

问题是我的定位算法不适用于使用 Arc2D.Float 生成的形状。当使用此类生成形状时,我得到的形状在其边界中具有负 y 坐标。

我进行了很多研究,但找不到任何有关此负 y 坐标含义的信息。如果我忽略坐标,我可以正确定位这个特定形状,但仍然存在以下问题:

  • 负 y 坐标意味着什么以及一般应如何处理?
  • 负坐标与边界高度有何关系?

下面是一段演示该问题的源代码。尝试使用形状的 y 坐标进行平移的未修改代码会生成以下显示: Bad positioning, using negative y-bounds information, note the gap at the top of the image display 如果使用零 y 翻译在源代码中的 g.translate() 行中进行注释,则会显示以下内容: Gap shown now at the bottom, bounds information silently ignored 似乎需要从边界的高度中减去负 y 。这只是强调我似乎错过了一些基本的理解......

我发现的唯一其他信息是,当对开始这一切的弧使用其他开始和结束角度时,这根本不是问题。起始角度为 0,弧度为 45 度,一切正常。所以这也有可能是某个数学问题。

希望有人能给个解释...

public class ShapeAnomaly
{
    public static void main( String[] argv ) throws Exception
    {
        //
        // Create the shape.
        //
        Shape shape = null;
        {
            Rectangle arcBounds = new Rectangle( 0, 0, 500, 500 );

            Path2D gp = new Path2D.Float();
            gp.append( new Arc2D.Float( arcBounds,
                        22.5f,
                        90.0f,
                        Arc2D.OPEN ), true );
            gp.closePath();

            shape = gp;
        }

        //
        // Create an image and paint the shape.
        //
        final Image image;
        {
            Rectangle2D bounds = shape.getBounds2D();
            System.err.println( "Bounds: " + bounds );

            BufferedImage bImage = new BufferedImage(
                    (int)bounds.getWidth(),
                    (int)bounds.getHeight(),
                    BufferedImage.TYPE_INT_ARGB );

            Graphics2D g = bImage.createGraphics();

            if ( bounds.getY() < 0 )
                System.err.println( "Anomaly..." );

            //
            // What is the correct handling of the bounds y-coordinate when
            // drawing the shape?
            // Should work, thought I know why, but doesn't.
            g.translate( -bounds.getX(), -bounds.getY() );
            // Works, but dunno why?
            //g.translate( -bounds.getX(), 0 ); 

            g.fill( shape );
            g.dispose();
            image = bImage;
        }

        //
        // Show the image in a window.
        //
        SwingUtilities.invokeLater( new Runnable()
        {
            @Override
            public void run()
            {
                JFrame frame = new JFrame( "Shape anomaly..." );
                frame.getContentPane().add( new JLabel( new ImageIcon( image ) ) );
                frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                frame.pack();

                frame.setVisible( true );
            }
        } );
    }
}

最佳答案

来自documentation for the getBounds2D() method of Path2D.Float :

Note that there is no guarantee that the returned Rectangle2D is the smallest bounding box that encloses the Shape, only that the Shape lies entirely within the indicated Rectangle2D.

这实际上只是 general contract of Shape.getBounds2D() 的副本.

我不知道是否有正确的方法来获取任意形状的真实边界。我的直觉是使用扁平化的 PathIterator,它保证只包含 moveTo、lineTo 和 close 操作:

Rectangle2D bounds = null;
float[] coords = new float[6];
for (PathIterator i = shape.getPathIterator(null, 1);
     !i.isDone();
     i.next()) {

    if (i.currentSegment(coords) != PathIterator.SEG_CLOSE) {
        float x = coords[0];
        float y = coords[1];
        if (bounds == null) {
            bounds = new Rectangle2D.Float(x, y, 0, 0);
        } else {
            bounds.add(x, y);
        }
    }
}
System.err.println( "Bounds: " + bounds );

关于java - 使用 Arc2D 创建的 java.awt.Shape 中负边界坐标的含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35301839/

相关文章:

java - 如何在Java中高性能地显示多个SVG

java - 逐行绘制矩形

java - 绘制大麻曲线

java - 使用 Executors.newCachedThreadPool() 时在线程池中创建的线程数

java - 如何将 RESTEasy 客户端代理与 MultipartFile 结合使用

java - 如果我已经有了自己的 Timer 类,如何开始使用 javax.swing.Timer?

java - java.awt.Robot.waitForIdle() 是否等待事件被分派(dispatch)?

java.io 和 socket.getInputStream()

java - Vaadin Layout - 如何让面板展开以填满大部分屏幕

java - 如何将重复背景图像设置为 JPanel?