您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

如何在Java中绘制有向箭头线?

如何在Java中绘制有向箭头线?

如果折角处于特定角度,则在折线的线段之间绘制斜角。如果您绘制的线恰巧是在某些具有某种特定颜色的其他像素附近绘制的,则没有任何关系- 绘制矩形后,Graphics对象将不知道该矩形,(实际上)仅保留像素。(或更确切地说,图像或OS窗口包含像素)。

要绘制简单的箭头,请在执行操作时为茎杆画一条线,然后为vee画一条折线。看起来更漂亮的箭头具有弯曲的侧面并被填充。

您可能不希望对箭头使用斜角,因为斜角是平坦的。而是使用斜接选项:

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;

public class BevelArrows
{
    public static void main ( String...args )
    {
        SwingUtilities.invokelater ( new Runnable () {
            BevelArrows arrows = new BevelArrows();

            @Override
            public void run () {
                JFrame frame = new JFrame ( "Bevel Arrows" );

                frame.add ( new JPanel() {
                    public void paintComponent ( Graphics g ) {
                        arrows.draw ( ( Graphics2D ) g, getWidth(), getHeight() );
                    }
                }
                , BorderLayout.CENTER );

                frame.setSize ( 800, 400 );
                frame.setDefaultCloSEOperation ( JFrame.EXIT_ON_CLOSE );
                frame.setVisible ( true );
            }
        } );
    }

    interface Arrow {
        void draw ( Graphics2D g );
    }

    Arrow[] arrows = { new LineArrow(), new CurvedArrow() };

    void draw ( Graphics2D g, int width, int height )
    {
        g.setRenderingHint ( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );

        g.setColor ( Color.WHITE );
        g.fillRect ( 0, 0, width, height );

        for ( Arrow arrow : arrows ) {
            g.setColor ( Color.ORANGE );
            g.fillRect ( 350, 20, 20, 280 );

            g.setstroke ( new Basicstroke ( 20.0f, Basicstroke.CAP_BUTT, Basicstroke.JOIN_BEVEL ) );
            g.translate ( 0, 60 );
            arrow.draw ( g );

            g.setstroke ( new Basicstroke ( 20.0f, Basicstroke.CAP_BUTT, Basicstroke.JOIN_MITER ) );
            g.translate ( 0, 100 );
            arrow.draw ( g );

            g.setstroke ( new Basicstroke ( 20.0f, Basicstroke.CAP_BUTT, Basicstroke.JOIN_ROUND ) );
            g.translate ( 0, 100 );
            arrow.draw ( g );

            g.translate ( 400, -260 );
        }
    }

    static class LineArrow  implements Arrow
    {
        public void draw ( Graphics2D g )
        {
            // where the control point for the intersection of the V needs calculating
            // by projecting where the ends meet

            float arrowRatio = 0.5f;
            float arrowLength = 80.0f;

            Basicstroke stroke = ( Basicstroke ) g.getstroke();

            float endX = 350.0f;

            float veeX;

            switch ( stroke.getLineJoin() ) {
                case Basicstroke.JOIN_BEVEL:
                    // IIRC, bevel varies system to system, this is approximate
                    veeX = endX - stroke.getLineWidth() * 0.25f;
                    break;
                default:
                case Basicstroke.JOIN_MITER:
                    veeX = endX - stroke.getLineWidth() * 0.5f / arrowRatio;
                    break;
                case Basicstroke.JOIN_ROUND:
                    veeX = endX - stroke.getLineWidth() * 0.5f;
                    break;
            }

            // vee
            Path2D.Float path = new Path2D.Float();

            path.moveTo ( veeX - arrowLength, -arrowRatio*arrowLength );
            path.lineTo ( veeX, 0.0f );
            path.lineTo ( veeX - arrowLength, arrowRatio*arrowLength );

            g.setColor ( Color.BLUE );
            g.draw ( path );

            // stem for exposition only
            g.setColor ( Color.YELLOW );
            g.draw ( new Line2D.Float ( 50.0f, 0.0f, veeX, 0.0f ) );

            // in practice, move stem back a bit as rounding errors
            // can make it poke through the sides of the Vee
            g.setColor ( Color.RED );
            g.draw ( new Line2D.Float ( 50.0f, 0.0f, veeX - stroke.getLineWidth() * 0.25f, 0.0f ) );
        }
    }

    static class CurvedArrow  implements Arrow
    {
        // to draw a nice curved arrow, fill a V shape rather than stroking it with lines
        public void draw ( Graphics2D g )
        {
            // as we're filling rather than stroking, control point is at the apex,

            float arrowRatio = 0.5f;
            float arrowLength = 80.0f;

            Basicstroke stroke = ( Basicstroke ) g.getstroke();

            float endX = 350.0f;

            float veeX = endX - stroke.getLineWidth() * 0.5f / arrowRatio;

            // vee
            Path2D.Float path = new Path2D.Float();

            float waisting = 0.5f;

            float waistX = endX - arrowLength * 0.5f;
            float waistY = arrowRatio * arrowLength * 0.5f * waisting;
            float arrowWidth = arrowRatio * arrowLength;

            path.moveTo ( veeX - arrowLength, -arrowWidth );
            path.quadTo ( waistX, -waistY, endX, 0.0f );
            path.quadTo ( waistX, waistY, veeX - arrowLength, arrowWidth );

            // end of arrow is pinched in
            path.lineTo ( veeX - arrowLength * 0.75f, 0.0f );
            path.lineTo ( veeX - arrowLength, -arrowWidth );

            g.setColor ( Color.BLUE );
            g.fill ( path );

            // move stem back a bit
            g.setColor ( Color.RED );
            g.draw ( new Line2D.Float ( 50.0f, 0.0f, veeX - arrowLength * 0.5f, 0.0f ) );
        }
    }
}
java 2022/1/1 18:17:18 有611人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶