Зажим векторов по кругу в гнуплоте - PullRequest
2 голосов
/ 07 февраля 2020

Я пытаюсь нарисовать некоторые векторные поля в круговой области. Рассмотрим следующее MWE

unset grid
unset tics
unset colorbox
unset border

set size square

besselj(n, x) = n > 1 ? 2*(n-1)/x*besselj(n-1,x) - besselj(n-2,x) : (n == 1 ? besj1(x) : besj0(x))
dbesselj(n, x) = n/x*besselj(n,x) - besselj(n+1,x)

rho(x,y) = sqrt(x**2+y**2)
phi(x,y) = atan2(y,x)

d = 1.0
l = 1.0
z = l/2

q = 1

set xrange [-d/2*1.1:d/2*1.1]
set yrange [-d/2*1.1:d/2*1.1]

Erho(x,y,n,ynp) = (-1/rho(x,y)) * besselj(n, (ynp*2/d)*rho(x,y)) * (-n*sin(n*phi(x,y))) * sin(q*pi*z/l)
Ephi(x,y,n,ynp) = (ynp*2/d) * dbesselj(n, (ynp*2/d)*rho(x,y)) * (cos(n*phi(x,y))) * sin(q*pi*z/l)

Ex(x,y,n,ynp) = rho(x,y) > d/2 ? NaN : cos(phi(x,y))*Erho(x,y,n,ynp) - sin(phi(x,y))*Ephi(x,y,n,ynp)
Ey(x,y,n,ynp) = rho(x,y) > d/2 ? NaN : sin(phi(x,y))*Erho(x,y,n,ynp) + cos(phi(x,y))*Ephi(x,y,n,ynp)

mag(x,y,n,ynp) = sqrt(Ex(x,y,n,ynp)**2 + Ey(x,y,n,ynp)**2)

set object circle at 0,0 size 0.5 fc black lw 3 front

set multiplot layout 1,2

set title 'TE_{01}'
set table 'tmp.dat'
set samples 16
set isosamples 16
plot '++' u 1:2:(Ex($1,$2,0,3.832)/50):(Ey($1,$2,0,3.832)/50) w vectors
unset table
set samples 250
set isosamples 250
plot '++' u 1:2:(mag($1,$2,0,3.832)) w image notitle, \
     'tmp.dat' u 1:2:3:4 w vectors head filled lc black lw 1 notitle

set title 'TE_{11}'
set table 'tmp.dat'
set samples 16
set isosamples 16
plot '++' u 1:2:(Ex($1,$2,1,1.841)/20):(Ey($1,$2,1,1.841)/20) w vectors
unset table
set samples 250
set isosamples 250
plot '++' u 1:2:(mag($1,$2,1,1.841)) w image notitle, \
     'tmp.dat' u 1:2:3:4 w vectors head filled lc black lw 1 notitle

unset multiplot

, которое отображает векторное поле, а также его величину внутри круга с диаметром d. В результате получается

output from the above code

, что вполне подходит для левого изображения (TE01), но правое изображение (TE11) выглядит некрасиво, потому что есть некоторые векторы, которые нарисованы за пределами круга. Мой действительно желаемый результат - это

desired result

, где у меня нет векторов за пределами черного круга. Как я могу этого достичь? Я знаю, что в gnuplot есть функция clip, но это не позволяет указать форму, которая будет использоваться для отсечения.

1 Ответ

2 голосов
/ 07 февраля 2020

Вот что вы можете попробовать. Определите свою собственную функцию клипа, например, круг. Сначала вам нужно проверить, находится ли точка данных вне вашего круга или нет. Clip(x,y) возвращает NaN, если он снаружи, и 0, если он внутри. Теперь, когда вы строите график, просто добавьте значение функции клипа к вашему значению. Ваши данные будут обрезаны внутри круга, потому что что-то +0 останется неизменным, а что-то +NaN будет NaN и не будет отображаться. Достаточно сделать это только для x (начало вектора) и x + delta x (конец вектора).

Код:

### clip function in circle form
reset session
set size square

# create some test data
set samples 25
Scaling = 0.5
set table $Data
plot [-5:5] '++' u 1:2:(Scaling*$1/sqrt($1**2+$2**2)): \
         (Scaling*$2/sqrt($1**2+$2**2)) : (sqrt($1**2+$2**2)) with table
unset table

set palette rgb 33,13,10
CenterX = 0
CenterY = 0
Radius = 3.5
Clip(x,y) = sqrt((x-CenterX)**2 + (y-CenterY)**2) > Radius ? NaN : 0

set xrange[-6:6]
set yrange[-6:6]

set multiplot layout 1,3

    plot $Data u 1:2:3:4:5 w vec lc pal not

    plot $Data u ($1+Clip($1,$2)):2:($3+Clip($1+$3,$2+$4)):4:5 w vec lc pal not

    CenterX = 1
    CenterY = 1
    plot $Data u ($1+Clip($1,$2)):2:($3+Clip($1+$3,$2+$4)):4:5 w vec lc pal not

unset multiplot
### end of code

Результат: enter image description here

...