Java 在线条2D的末端绘制具有多边形的菱形

Java 在线条2D的末端绘制具有多边形的菱形,java,swing,java-2d,shapes,Java,Swing,Java 2d,Shapes,我正试图画一颗钻石(用于组合关系)。现在,我正在做一个三角形,像这样: 但我想做这样的事情: 我用这个代码做三角形: 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; doubl

我正试图画一颗钻石(用于组合关系)。现在,我正在做一个三角形,像这样:

但我想做这样的事情:

我用这个代码做三角形:

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;
导入java.awt.Color;
导入java.awt.Cursor;
导入java.awt.EventQueue;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Panel;
导入java.awt.Point;
导入java.awt.Polygon;
导入java.awt.RenderingHints;
导入java.awt.Shape;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.geom.Line2D;
导入java.awt.geom.Point2D;
导入java.awt.geom.Rectangle2D;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JFrame;
导入javax.swing.JMenuBar;
导入javax.swing.JMenuItem;
导入javax.swing.JPanel;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
公共类箭头{
公共静态void main(字符串[]args){
新的绘图箭头();
}
公众支取箭头(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化异常
|非法访问例外
|不受支持的LookandFeelEx){
例如printStackTrace();
}
JFrame=new-UMLWindow();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
框架.立根(30,30,1000,700);
frame.getContentPane().setBackground(颜色:白色);
frame.setVisible(true);
frame.setLocationRelativeTo(空);
}
});
}
公共静态类UMLWindow扩展了JFrame{
形状shapeList=新形状();
专家组;
私有静态最终长serialVersionUID=1L;
公共UMLWindow(){
添加菜单();
面板=新面板();
}
公共无效添加菜单(){
getContentPane().add(shapeList);
设置大小(300200);
setLocationRelativeTo(空);
setDefaultCloseOperation(关闭时退出);
JMenuItem lineMenuItem=新JMenuItem(“新行”);
lineMenuItem.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件){
System.out.println(“添加行”);
shapeList.addLine();
}
});
JMenuBar menubar=新的JMenuBar();
菜单栏。添加(lineMenuItem);
setJMenuBar(菜单栏);
}
}
公共静态类形状扩展了JPanel{
私有静态最终长serialVersionUID=1L;
私有列表行=新的ArrayList();
私有布尔图形=false;
专用点lineStartingPoint=新点();
专用点lineEndingPoint=新点();
专用Line2D。双线路径;
双φ=数学环面(40);
int倒钩=20;
公共形状(){
MyMouseAdapter MyMouseAdapter=新的MyMouseAdapter();
addMouseListener(myMouseAdapter);
addMouseMotionListener(myMouseAdapter);
此.set不透明(true);
this.setBackground(Color.WHITE);//设置画布颜色
}
公共void addLine(){
绘图=真;
重新油漆();
}
@凌驾
受保护组件(图形g){
超级组件(g);
图形2d g2=(图形2d)g;
g2.设定行程(新基本行程(2));
if(图纸){
g2.setRenderingHint(RenderingHints.KEY_抗锯齿,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.设定行程(新基本行程(2));
g2.绘制线(lineStartingPoint.x、lineStartingPoint.y、,
lineEndingPoint.x,lineEndingPoint.y);
绘图箭头(g2、lineEndingPoint、lineStartingPoint、,
颜色(黑色);
}
用于(线条2D线条:线条){
g2.设置颜色(颜色为黑色);
点sw=新点((int)line.getX1(),(int)line.getY1());
点ne=新点((int)line.getX2(),(int)line.getY2());
g2.画(线);
牵引箭头(g2,东北,西南,彩色。黑色);
}
}
公共矩形2D drawRect(整数x,整数y){
返回新的矩形2d.Double(x-4,y-4,8,8);
}
专用空心图纸箭头(图形2D g2、点尖、点尾、,
颜色(颜色){
g2.设置油漆(颜色);
双dy=尖端.y-尾部.y;
双dx=尖端x-尾部x;
双θ=Math.atan2(dy,dx);
双x,y,ρ=θ+φ;
点p1=新点();
点p2=新点();
p1.设置位置(tip.x-barb*Math.cos(rho),tip.y-barb*Math.sin(rho));
ρ=θ-φ;
p2.设置位置(tip.x-barb*Math.cos(rho),tip.y-barb*Math.sin(rho));
int[]xPoints=新的int[5];
int[]yPoints=新的int[5];
xPoints[0]=tip.x;
xPoints[1]=p1.x;
xPoints[2]=p2.x;
y点[0]=尖端y;
yPoints[1]=p1.y;
yPoints[2]=p2.y;
g2.setPaint(颜色为黑色);
形状=新多边形(X点,Y点,3);
g2.填充(形状);
//tip.x-barb*Math.cos(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();
            }
        }

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

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

    }

}