简体   繁体   English

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

[英]Paint component for panel doesn't draw double point values

I have coordinate points that I'm trying to draw relative to each other and cannot get the points to show up. 我有要相对于彼此绘制的坐标点,但无法使这些点显示出来。 That I'm working with. 我正在一起工作。 These points don't work: 这些点不起作用:

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

These points do work: 这些要点起作用:

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

You have a certain set of points in 2D, and want to paint them into a JPanel . 您在2D中有一组特定的点,并希望将它们绘制到JPanel And the goal is to make sure that the set of points is rendered "properly" in the panel. 目的是确保在面板中“正确”显示一组点。 Here I assume that "properly" means that all the points should be visible, and they should be rendered so that they basically fill the available space. 在这里,我认为“适当”意味着所有点都应该可见,并且应该渲染它们,以便它们基本上填充可用空间。

There are different approaches for this. 有不同的方法。

The most basic approach would involve the following steps (disregarding some implementation details for now) : 最基本的方法将涉及以下步骤(暂时不考虑某些实现细节):

  • You have to compute the bounding box of the points 您必须计算点的边界框
  • You have to compute the transform that has to be applied to the points so that they fill the screen. 您必须计算必须应用于这些点的变换,以便它们填满屏幕。 This transform can be computed from the bounding box 可以从边界框计算此变换
  • You have to transform the points 你必须改变点
  • You have to paint the transformed points 您必须绘制转换点

In the example code below, these steps are implemented in the convertToPoints , computeBoundingBox , computeTransform , transformPoints and drawPolygon methods of the ScaledPaintingPlainPanel class. 在下面的示例代码,这些步骤是在执行convertToPointscomputeBoundingBoxcomputeTransformtransformPointsdrawPolygon所述的方法ScaledPaintingPlainPanel类。

In your case, the points are actually points of a polygon - that is, they are connected with lines. 在您的情况下,这些点实际上是多边形的点-也就是说,它们与线相连。 This can make things a bit simpler: You can convert the points into a java.awt.Shape , so that you don't have to compute the bounding box manually. 这可以使事情变得简单一些:您可以将这些点转换为java.awt.Shape ,从而不必手动计算边界框。 The shape can also be transformed and painted more easily. 形状也可以更轻松地变形和绘画。 This is shown in the ScaledPaintingPlainPanelSimpler class. 这在ScaledPaintingPlainPanelSimpler类中显示。

The results are the same in both cases: 在两种情况下,结果都是相同的:

比例绘画

The code is here: 代码在这里:

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

Just for completeness: Here is a similar example, using my Viewer library 出于完整性考虑:这是使用我的Viewer的类似示例

比例绘画2

In this case, you can also translate and zoom the rendered representation using the mouse. 在这种情况下,您还可以使用鼠标平移和缩放渲染的表示。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

import de.javagl.viewer.Painter;
import de.javagl.viewer.Viewer;

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

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame("Viewer");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().setLayout(new BorderLayout());

        f.getContentPane().add(
            new JLabel("<html>"
                + "Right mouse drags: Translate<br> "
                + "Left mouse drags: Rotate<br>"
                + "Mouse wheel: Zoom uniformly<br>"
                + "&nbsp;&nbsp;&nbsp;&nbsp; +shift: zoom along x<br>"
                + "&nbsp;&nbsp;&nbsp;&nbsp; +ctrl: zoom along y<br>"
                + "</html>"),
            BorderLayout.NORTH);

        Viewer viewer = new Viewer();
        ScaledPaintingPainter painter = new ScaledPaintingPainter();
        viewer.addPainter(painter);
        viewer.setDisplayedWorldArea(painter.computeBounds());
        f.getContentPane().add(viewer, BorderLayout.CENTER);

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

class ScaledPaintingPainter implements Painter
{
    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 paint(
        Graphics2D g, AffineTransform worldToScreen, double w, double h)
    {
        // Convert the arrays into shapes
        Shape sShape = convertToShape(subjPoints);
        Shape cShape = convertToShape(clipPoints);

        g.setColor(Color.BLUE);
        g.draw(worldToScreen.createTransformedShape(sShape));
        g.setColor(Color.RED);
        g.draw(worldToScreen.createTransformedShape(cShape));
    }

    Rectangle2D computeBounds()
    {
        // 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);

        return bounds;
    }

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

}

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

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