在Line2D的末端绘制带有多边形的菱形 [英] Drawing a diamond with Polygon on the end of a Line2D

查看:64
本文介绍了在Line2D的末端绘制带有多边形的菱形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to draw a diamond (for a composition UML relationship). Right now, I am making a triangle like this:

但是我想做这样的事情:

but I want to make something like this:

然后用此代码绘制三角形:

And I do the triangle with this code:

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

有人对如何用这种钻石制造钻石有想法吗?谢谢:)

Does anyone have an idea on how to make a diamond out of this? Thanks :)

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

    }
}

推荐答案

我个人将重点放在生成形状以及使用Graphics2D API进行翻译和转换...

Personally, I would focus on generating the shape and the using the Graphics2D API to perform the translation and transformation...

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

The Shape API makes it really easy to generate complex shapes, for example, this is the diamond shape used in the following example...

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

}

它简短,简单,并且(在大多数情况下)易于理解...

It's short, simple and (for the most part), easy to understand...

但是它需要旋转",我听到您说过,但是,当然,Graphics API提供了强大而简单的功能来实现这一目标,让它承担繁重的工作.但是,如果您只需要变形形状,则Shape API可以执行此操作以(变形形状本身)

"But it needs to rotate" I hear you say, but of course, the Graphics API provides awesome and simple functionality to achieve that, let it do the heavy lifting. However, if you need to only transform the shape, the Shape API can do that to (transform the shape itself)

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

    }

}

这篇关于在Line2D的末端绘制带有多边形的菱形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆