首页 > 解决方案 > gnuplot:圆圈之间的箭头

问题描述

如何在圆圈之间绘制箭头

  1. 箭头指向圆心,
  2. 但缩短了长度,使其仅接触圆周,
  3. 与终端尺寸比例无关?

听起来很简单,但我没有找到比下面的示例更短的解决方案。您需要在轴坐标和终端坐标之间进行一些坐标转换。为此,您需要知道绘图的终端大小,并且只有绘图后您必须先做一个虚拟绘图,然后再将这些值放入GPVAL_...变量中。如果我忽略了一些明显且更简单的程序,请告诉我。replot

代码:

### arrows touching circles
reset session

# Factor between axes and terminal coordinates
FactorX(n) = real(GPVAL_X_MAX-GPVAL_X_MIN)/(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)
FactorY(n) = real(GPVAL_Y_MAX-GPVAL_Y_MIN)/(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)

# Axis coordinates to terminal coordinates
AxisToTermX(x) = (x-GPVAL_X_MIN)/FactorX(0)+GPVAL_TERM_XMIN
AxisToTermY(y) = (y-GPVAL_Y_MIN)/FactorY(0)+GPVAL_TERM_YMIN

xt(x) = AxisToTermX(x)
yt(y) = AxisToTermY(y)
rt(r) = r/FactorX(0)
Lt(x1,y1,x2,y2) = sqrt((xt(x2)-xt(x1))**2 + (yt(y2)-yt(y1))**2)

# terminal coordinates reduced by radii
x1tr(x1,y1,r1,x2,y2,r2) = rt(r1)*(xt(x2)-xt(x1))/Lt(x1,y1,x2,y2)+xt(x1)
y1tr(x1,y1,r1,x2,y2,r2) = rt(r1)*(yt(y2)-yt(y1))/Lt(x1,y1,x2,y2)+yt(y1)
x2tr(x1,y1,r1,x2,y2,r2) = (Lt(x1,y1,x2,y2)-rt(r2))*(xt(x2)-xt(x1))/Lt(x1,y1,x2,y2) + xt(x1)
y2tr(x1,y1,r1,x2,y2,r2) = (Lt(x1,y1,x2,y2)-rt(r2))*(yt(y2)-yt(y1))/Lt(x1,y1,x2,y2) + yt(y1)

# Terminal coordinates to axis coordinates
TermToAxisX(xt) = real(xt-GPVAL_TERM_XMIN)*FactorX(0)+GPVAL_X_MIN
TermToAxisY(yt) = real(yt-GPVAL_TERM_YMIN)*FactorY(0)+GPVAL_Y_MIN

# axis coordinates reduced by radii
x1r(x1,y1,r1,x2,y2,r2) = TermToAxisX(x1tr(x1,y1,r1,x2,y2,r2))
y1r(x1,y1,r1,x2,y2,r2) = TermToAxisY(y1tr(x1,y1,r1,x2,y2,r2))
x2r(x1,y1,r1,x2,y2,r2) = TermToAxisX(x2tr(x1,y1,r1,x2,y2,r2))
y2r(x1,y1,r1,x2,y2,r2) = TermToAxisY(y2tr(x1,y1,r1,x2,y2,r2))

# dummy plot
set xrange [-10:10]
set yrange [-10:10]
plot NaN notitle

$Data <<EOD
0   0   1.0
-6  2   3.0
0   5   0.75
7   -8  2.0
5    8  1.5
EOD

N = |$Data|   # length of datablock

# draw N circles
do for [i=0:N-1] {
    set obj i+1 circle at word($Data[i+1],1),word($Data[i+1],2) size word($Data[i+1],3) fc "blue"
}

# draw N arrows
do for [i=0:N-1] {
    x1 = word($Data[i+1],1)
    y1 = word($Data[i+1],2)
    r1 = word($Data[i+1],3)
    x2 = word($Data[(i+1)%N+1],1)
    y2 = word($Data[(i+1)%N+1],2)
    r2 = word($Data[(i+1)%N+1],3)
    set arrow i+1 from x1r(x1,y1,r1,x2,y2,r2), y1r(x1,y1,r1,x2,y2,r2) \
                  to x2r(x1,y1,r1,x2,y2,r2), y2r(x1,y1,r1,x2,y2,r2) heads lc "red"
}

replot
### end of code

结果:(wxt 大小 600,600)

在此处输入图像描述

与 (wxt size 700,300) 相同的代码

在此处输入图像描述

标签: gnuplot

解决方案


推荐阅读