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

}

}

}

2020-09-16

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值