在Line2D的末端绘制一个带有Polygon的钻石

时间:2014-11-12 23:42:51

标签: java swing java-2d shapes

我正在尝试绘制一个钻石(用于合成UML关系)。现在,我正在制作一个这样的三角形:

enter image description here

但我想做这样的事情:

enter image description here

我用这段代码做了三角形:

private void drawArrowHead(Graphics2D g2, Point tip, Point tail,
            Color color) {
    g2.setPaint(color);
    double dy = tip.y - tail.y;
    double dx = tip.x - tail.x;
    double theta = Math.atan2(dy, dx);
    double x, y, rho = theta + phi;
    Point p1 = new Point();
    Point p2 = new Point();

    p1.setLocation(tip.x - barb * Math.cos(rho), tip.y - barb * Math.sin(rho));
    rho = theta - phi;
    p2.setLocation(tip.x - barb * Math.cos(rho), tip.y - barb * Math.sin(rho));

    int[] xPoints = new int[5];
    int[] yPoints = new int[5];

    xPoints[0] = tip.x;
    xPoints[1] = p1.x;
    xPoints[2] = p2.x;

    yPoints[0] = tip.y;
    yPoints[1] = p1.y;
    yPoints[2] = p2.y;

    g2.setPaint(Color.BLACK);
    Shape shape = new Polygon(xPoints, yPoints, 3);
    g2.fill(shape);

    //tip.x - barb * Math.cos(rho);
    //y = tip.y - barb * Math.sin(rho);
}

有没有人知道如何制作钻石?谢谢:))

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Line2D;
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.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DrawArrows {

    public static void main(String[] args) {
        new DrawArrows();
    }

    public DrawArrows() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager
                            .getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException
                        | IllegalAccessException
                        | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new UMLWindow();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setBounds(30, 30, 1000, 700);
                frame.getContentPane().setBackground(Color.white);
                frame.setVisible(true);
                frame.setLocationRelativeTo(null);
            }
        });
    }

    public static class UMLWindow extends JFrame {

        Shapes shapeList = new Shapes();
        Panel panel;

        private static final long serialVersionUID = 1L;

        public UMLWindow() {
            addMenus();
            panel = new Panel();
        }

        public void addMenus() {

            getContentPane().add(shapeList);

            setSize(300, 200);
            setLocationRelativeTo(null);
            setDefaultCloseOperation(EXIT_ON_CLOSE);

            JMenuItem lineMenuItem = new JMenuItem("New Line");
            lineMenuItem.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent event) {
                    System.out.println("adding line");
                    shapeList.addLine();
                }
            });

            JMenuBar menubar = new JMenuBar();

            menubar.add(lineMenuItem);

            setJMenuBar(menubar);

        }
    }

    public static class Shapes extends JPanel {

        private static final long serialVersionUID = 1L;

        private List<Line2D.Double> lines = new ArrayList<Line2D.Double>();
        private Boolean drawing = false;
        private Point lineStartingPoint = new Point();
        private Point lineEndingPoint = new Point();
        private Line2D.Double linePath;

        double phi = Math.toRadians(40);
        int barb = 20;

        public Shapes() {
            MyMouseAdapter myMouseAdapter = new MyMouseAdapter();
            addMouseListener(myMouseAdapter);
            addMouseMotionListener(myMouseAdapter);
            this.setOpaque(true);
            this.setBackground(Color.WHITE); // set canvas color
        }

        public void addLine() {
            drawing = true;
            repaint();
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            Graphics2D g2 = (Graphics2D) g;
            g2.setStroke(new BasicStroke(2));
            if (drawing) {
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setStroke(new BasicStroke(2));
                g2.drawLine(lineStartingPoint.x, lineStartingPoint.y,
                        lineEndingPoint.x, lineEndingPoint.y);
                drawArrowHead(g2, lineEndingPoint, lineStartingPoint,
                        Color.BLACK);
            }
            for (Line2D line : lines) {
                g2.setColor(Color.BLACK);
                Point sw = new Point((int) line.getX1(), (int) line.getY1());
                Point ne = new Point((int) line.getX2(), (int) line.getY2());
                g2.draw(line);
                drawArrowHead(g2, ne, sw, Color.BLACK);
            }
        }

        public Rectangle2D drawRect(int x, int y) {
            return new Rectangle2D.Double(x - 4, y - 4, 8, 8);
        }

        private void drawArrowHead(Graphics2D g2, Point tip, Point tail,
                Color color) {
            g2.setPaint(color);
            double dy = tip.y - tail.y;
            double dx = tip.x - tail.x;
            double theta = Math.atan2(dy, dx);
            double x, y, rho = theta + phi;
            Point p1 = new Point();
            Point p2 = new Point();

            p1.setLocation(tip.x - barb * Math.cos(rho), tip.y - barb * Math.sin(rho));
            rho = theta - phi;
            p2.setLocation(tip.x - barb * Math.cos(rho), tip.y - barb * Math.sin(rho));

            int[] xPoints = new int[5];
            int[] yPoints = new int[5];

            xPoints[0] = tip.x;
            xPoints[1] = p1.x;
            xPoints[2] = p2.x;

            yPoints[0] = tip.y;
            yPoints[1] = p1.y;
            yPoints[2] = p2.y;

            g2.setPaint(Color.BLACK);
            Shape shape = new Polygon(xPoints, yPoints, 3);
            g2.fill(shape);

            //tip.x - barb * Math.cos(rho);
            //y = tip.y - barb * Math.sin(rho);
        }

        class MyMouseAdapter extends MouseAdapter {
            int currentIndex;
            Point2D.Double startPoint = new Point2D.Double();
            Point2D.Double endPoint = new Point2D.Double();
            Boolean resizing = false;

            @Override
            public void mousePressed(MouseEvent e) {
                if (drawing) {
                    lineStartingPoint = e.getPoint();
                    lineEndingPoint = lineStartingPoint;
                }
            }

            @Override
            public void mouseDragged(MouseEvent e) {
                if (drawing) {
                    lineEndingPoint = e.getPoint();
                    repaint();
                    System.out.println(lines.size());
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (drawing) {
                    drawLine(e);
                }
                drawing = false;

            }

            @Override
            public void mouseMoved(MouseEvent e) {

            }

            public void drawLine(MouseEvent e) {
                drawing = false;
                lineEndingPoint = e.getPoint();
                linePath = new Line2D.Double(lineStartingPoint.getX(),
                        lineStartingPoint.getY(), lineEndingPoint.getX(),
                        lineEndingPoint.getY());
                lines.add(linePath);
                repaint();
            }
        }

    }
}

1 个答案:

答案 0 :(得分:4)

就个人而言,我会专注于生成形状并使用Graphics2D API来执行翻译和转换......

Shape API可以很容易地生成复杂的形状,例如,这是以下示例中使用的菱形...

public class DiamondShape extends Path2D.Double {

    public DiamondShape(int width, int height) {
        moveTo(width / 2, 0);
        lineTo(width, height / 2);
        lineTo(width / 2, height);
        lineTo(0, height / 2);
        closePath();
    }

}

它简短,简单(大部分),易于理解......

&#34;但它需要旋转&#34;我听到你说,但是当然,Graphics API提供了很棒的简单功能来实现这一点,让它完成繁重的任务。但是,如果您只需要转换形状,Shape API可以执行此操作(转换形状本身)

FollowMe

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class FollowMe {

    public static void main(String[] args) {
        new FollowMe();
    }

    public FollowMe() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Point mousePoint;
        private DiamondShape head;

        public TestPane() {
            head = new DiamondShape(10, 20);
            addMouseMotionListener(new MouseAdapter() {

                @Override
                public void mouseMoved(MouseEvent e) {
                    mousePoint = e.getPoint();
                    repaint();
                }

            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();

            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);

            double rotation = 0f;

            int width = getWidth() - 1;
            int height = getHeight() - 1;

            if (mousePoint != null) {

                int x = width / 2;
                int y = height / 2;

                int deltaX = mousePoint.x - x;
                int deltaY = mousePoint.y - y;

                rotation = -Math.atan2(deltaX, deltaY);

                rotation = Math.toDegrees(rotation) + 180;

            }

            g2d.rotate(Math.toRadians(rotation), width / 2, height / 2);

            int x = width / 2;
            int y = height / 2;
            g2d.setStroke(new BasicStroke(3));
            g2d.setColor(Color.RED);
            g2d.drawLine(x, y, x, y - height / 4);

            y -= height / 4 + (head.getBounds().height);
            x -= head.getBounds().width / 2;
            g2d.fill(head.createTransformedShape(AffineTransform.getTranslateInstance(x, y)));

            g2d.dispose();
            g2d.dispose();
        }

    }

    public class DiamondShape extends Path2D.Double {

        public DiamondShape(int width, int height) {
            moveTo(width / 2, 0);
            lineTo(width, height / 2);
            lineTo(width / 2, height);
            lineTo(0, height / 2);
            closePath();
        }

    }

}