面板的绘制组件不会绘制双点值

时间:2018-06-13 17:14:40

标签: java graphics double coordinates draw

我有一些坐标点,我试图相对于彼此绘制,并且无法获得要显示的点数。我和我一起工作。这些要点不起作用:

double[][] subjPoints = {{38.81904602050781,-71.00624084472656}, 
{38.81904602050781,-70.29379272460938}, {37.95466232299805,-
70.35797882080078}, {37.9495735168457,-71.03191375732422}};

double[][] clipPoints = {{38.62575820040764,-70.84753473092672}, {38.418853759765625,-71.02689361572266},
{38.21194931912361,-71.2057395294625}, {37.931301169971185,-70.67791159484983},
{38.1382056106132,-70.49975311140243}, {38.34511005125521,-70.32108875708619}};

这些观点确实有效:

double[][] subjPoints = {{50, 150}, {200, 50}, {350, 150}, {350, 300},
    {250, 300}, {200, 250}, {150, 350}, {100, 250}, {100, 200}};

double[][] clipPoints = {{100, 100}, {300, 100}, {300, 300}, {100, 300}};

_

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.translate(30, 60);
    g2.setStroke(new BasicStroke(3));
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);


    drawPolygon(g2, subjPoints, Color.blue);
    drawPolygon(g2, clipPoints, Color.red);


}

private void drawPolygon(Graphics2D g2, List<PointA> points, Color color) {
    g2.setColor(color);
    int len = points.size();
    Line2D line = new Line2D.Double();
    for (int i = 0; i < len; i++) {
        PointA p1 = points.get(i);
        PointA p2 = points.get((i + 1) % len);
        line.setLine(p1.getX(), p1.getY(), 
                p2.getX(), p2.getY());
        g2.draw(line);
    }
}

1 个答案:

答案 0 :(得分:0)

您在2D中有一组点,并希望将它们绘制成JPanel。目标是确保提供点集合#34;正确&#34;在小组中。在这里,我假设&#34;正确&#34;意味着所有的点都应该是可见的,并且它们应该被渲染,以便它们基本上填满可用空间。

有不同的方法。

最基本的方法将涉及以下步骤(暂时忽略一些实现细节):

  • 您必须计算点的边界框
  • 您必须计算必须应用于点的变换,以便它们填满屏幕。可以从边界框
  • 计算此变换
  • 你必须改变点
  • 您必须绘制转换后的点

在下面的示例代码中,这些步骤在{{1}的convertToPointscomputeBoundingBoxcomputeTransformtransformPointsdrawPolygon方法中实施}。class。

在您的情况下,点实际上是多边形的点 - 也就是说,它们与线连接。这可以使事情变得更简单:您可以将点转换为ScaledPaintingPlainPanel,这样您就不必手动计算边界框。形状也可以更容易地转换和绘制。这显示在java.awt.Shape类中。

两种情况下的结果相同:

ScaledPainting

代码在这里:

ScaledPaintingPlainPanelSimpler

仅为了完整性:以下是使用我的Viewer library

的类似示例

ScaledPainting2

在这种情况下,您还可以使用鼠标平移和缩放渲染的表示。

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class ScaledPaintingPlain
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        f.getContentPane().setLayout(new GridLayout(1,2));

        ScaledPaintingPlainPanel p0 = 
            new ScaledPaintingPlainPanel();
        f.getContentPane().add(p0);

        ScaledPaintingPlainPanelSimpler p1 = 
            new ScaledPaintingPlainPanelSimpler();
        f.getContentPane().add(p1);

        f.setSize(1200, 800);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

class ScaledPaintingPlainPanel extends JPanel
{
    double[][] subjPoints =
    {
        { 38.81904602050781, -71.00624084472656 },
        { 38.81904602050781, -70.29379272460938 },
        { 37.95466232299805, -70.35797882080078 },
        { 37.9495735168457, -71.03191375732422 } 
    };

    double[][] clipPoints =
    {
        { 38.62575820040764, -70.84753473092672 },
        { 38.418853759765625, -71.02689361572266 },
        { 38.21194931912361, -71.2057395294625 },
        { 37.931301169971185, -70.67791159484983 },
        { 38.1382056106132, -70.49975311140243 },
        { 38.34511005125521, -70.32108875708619 } 
    };

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(3));
        g2.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

        // Convert the arrays into lists of points
        List<Point2D> sPoints = convertToPoints(subjPoints);
        List<Point2D> cPoints = convertToPoints(clipPoints);

        // Compute the bounding boxes of the point lists
        Rectangle2D sBounds = computeBoundingBox(sPoints);
        Rectangle2D cBounds = computeBoundingBox(cPoints);
        Rectangle2D bounds = new Rectangle2D.Double();
        Rectangle2D.union(sBounds, cBounds, bounds);

        AffineTransform affineTransform = computeTransform(bounds);

        // Transform the points
        transformPoints(sPoints, affineTransform);
        transformPoints(cPoints, affineTransform);

        // Draw the point lists as polygons
        drawPolygon(g2, sPoints, Color.BLUE);
        drawPolygon(g2, cPoints, Color.RED);
    }


    private static List<Point2D> convertToPoints(double array[][])
    {
        List<Point2D> points = new ArrayList<Point2D>();
        for (double a[] : array)
        {
            points.add(new Point2D.Double(a[0], a[1]));
        }
        return points;
    }

    private static Rectangle2D computeBoundingBox(
        Iterable<? extends Point2D> points)
    {
        double minX = Double.MAX_VALUE;
        double minY = Double.MAX_VALUE;
        double maxX = -Double.MAX_VALUE;
        double maxY = -Double.MAX_VALUE;
        for (Point2D p : points)
        {
            minX = Math.min(minX, p.getX());
            minY = Math.min(minY, p.getY());
            maxX = Math.max(maxX, p.getX());
            maxY = Math.max(maxY, p.getY());
        }
        return new Rectangle2D.Double(minX, minY, maxX - minX,  maxY - minY);
    }

    private AffineTransform computeTransform(Rectangle2D bounds)
    {
        // Compute the scaling factor that has to be applied to the
        // points so that the painting fills the screen
        double scaleX = getWidth() / bounds.getWidth();
        double scaleY = getHeight() / bounds.getHeight();
        double scale = Math.min(scaleX, scaleY);

        // Compute the transform that has to be applied to the
        // points so that they fill the screen
        AffineTransform affineTransform = new AffineTransform();
        affineTransform.scale(scale, scale);
        affineTransform.translate(-bounds.getX(), -bounds.getY());

        return affineTransform;
    }

    private static void transformPoints(
        Iterable<? extends Point2D> points, AffineTransform affineTransform)
    {
        for (Point2D point : points)
        {
            affineTransform.transform(point, point);
        }
    }


    private void drawPolygon(Graphics2D g2, List<Point2D> points, Color color)
    {
        g2.setColor(color);
        int len = points.size();
        Line2D line = new Line2D.Double();
        for (int i = 0; i < len; i++)
        {
            Point2D p1 = points.get(i);
            Point2D p2 = points.get((i + 1) % len);
            line.setLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
            g2.draw(line);
        }
    }
}



class ScaledPaintingPlainPanelSimpler extends JPanel
{
    double[][] subjPoints =
    {
        { 38.81904602050781, -71.00624084472656 },
        { 38.81904602050781, -70.29379272460938 },
        { 37.95466232299805, -70.35797882080078 },
        { 37.9495735168457, -71.03191375732422 } 
    };

    double[][] clipPoints =
    {
        { 38.62575820040764, -70.84753473092672 },
        { 38.418853759765625, -71.02689361572266 },
        { 38.21194931912361, -71.2057395294625 },
        { 37.931301169971185, -70.67791159484983 },
        { 38.1382056106132, -70.49975311140243 },
        { 38.34511005125521, -70.32108875708619 } 
    };

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(3));
        g2.setRenderingHint(
            RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

        // Convert the arrays into shapes
        Shape sShape = convertToShape(subjPoints);
        Shape cShape = convertToShape(clipPoints);

        // Compute the bounding boxes of the shapes
        Rectangle2D sBounds = sShape.getBounds2D();
        Rectangle2D cBounds = cShape.getBounds2D();
        Rectangle2D bounds = new Rectangle2D.Double();
        Rectangle2D.union(sBounds, cBounds, bounds);

        AffineTransform affineTransform = computeTransform(bounds);

        g2.setColor(Color.BLUE);
        g2.draw(affineTransform.createTransformedShape(sShape));
        g2.setColor(Color.RED);
        g2.draw(affineTransform.createTransformedShape(cShape));
    }

    private static Shape convertToShape(double array[][])
    {
        Path2D path = new Path2D.Double();
        for (int i=0; i<array.length; i++)
        {
            double a[] = array[i];
            double x = a[0];
            double y = a[1];
            if (i == 0)
            {
                path.moveTo(x, y);
            }
            else
            {
                path.lineTo(x, y);
            }
        }
        path.closePath();
        return path;
    }

    private AffineTransform computeTransform(Rectangle2D bounds)
    {
        // Compute the scaling factor that has to be applied to the
        // points so that the painting fills the screen
        double scaleX = getWidth() / bounds.getWidth();
        double scaleY = getHeight() / bounds.getHeight();
        double scale = Math.min(scaleX, scaleY);

        // Compute the transform that has to be applied to the
        // points so that they fill the screen
        AffineTransform affineTransform = new AffineTransform();
        affineTransform.scale(scale, scale);
        affineTransform.translate(-bounds.getX(), -bounds.getY());

        return affineTransform;
    }
}