Я пытаюсь построить простую линейную поверхность уравнения x + y + 2z = 0. Это мой файл:
set xrange [-4:4]
set yrange [-4:4]
set zrange [-4:4]
set xlabel 'x'
set ylabel 'y'
set zlabel 'z'
set xyplane at -4.0
unset xzeroaxis
unset yzeroaxis
unset zzeroaxis
set border 1023-128
set xtics out nomirror
set ytics out nomirror
set ztics out
set xtics add ('' -4)
set label 1 "{/:Italic x} + {/:Italic y} + 2{/:Italic z} = 0" at 4,4.2,-2 font 'Times New Roman, 11'
set arrow 1 from 0,0,-4 to 0,0,4 filled
set arrow 2 from 0,-4,0 to 0,4,0 filled
set arrow 3 from -4,0,0 to 4,0,0 filled
set arrow 4 from 3.9,4.1,-2.1 to 3.6,3.6,-2.5
unset key
set pm3d lighting primary 0.5 specular 0.6
set style fill transparent solid 1 noborder
set palette defined (0 "cyan", 1 "green")
unset colorbox
set pm3d depthorder
splot -x/2-y/2 with pm3d
Я использую стрелки, чтобы показать ось, так как они, кажется, застряли в плоскости xy, и ее перемещение вызывает дополнительные проблемы с тиками и границей. Но теперь проблема в том, что они полностью закрыты поверхностью. Есть ли настройка, позволяющая появляться впереди, когда они "протыкают" поверхность? Я бы хотел сделать поверхность полупрозрачной, но с этими настройками проблема становится яснее.
gnuplot> help layer
A gnuplot plot is built up by drawing its various components in a fixed order.
This order can be modified by assigning some components to a specific layer
using the keywords `behind`, `back`, or `front`. For example, to replace the
background color of the plot area you could define a colored rectangle with the
attribute `behind`.
set object 1 rectangle from graph 0,0 to graph 1,1 fc rgb "gray" behind
The order of drawing is
behind
back
the plot itself
the plot legend (`key`)
front
Within each layer elements are drawn in the order
grid, axis, and border elements
pixmaps in numerical order
Таким образом, в основном вам нужно добавить атрибут «передний» к объектам, которые вы хотите отобразить перед графиком.
Да, то, что вы предложили вместе с разбиением каждой стрелки на 2, в конце концов сработало. Спасибо за ответ, Итан.
Я предполагаю, что ваша первоначальная идея, т. е. «прокалывание» 3D-поверхности стрелкой или линией, не работает сразу в gnuplot, потому что gnuplot не будет автоматически вычислять точки прокалывания. Пожалуйста, поправьте меня, если я ошибаюсь, и дайте мне знать, если это может быть простое решение.
Как и в вашем простом случае, вы можете просто разделить стрелку в начале координат, потому что вы уже знаете точку прокола. Однако что делать, если поверхность неровная или имеет несколько точек прокола?
Решение: приложите усилия, чтобы создать сегментированную трехмерную стрелку и позволить gnuplot автоматически отображать и скрывать поверхности по мере необходимости. Это, вероятно, приближается к тому, что вы имели в виду. Однако это решение покажет сюрпризы, когда вы захотите изменить цвет стрелок. Так что есть еще куда расти.
Код: (простая версия со стрелками вдоль осей x, y, z)
### arrows "piercing" a 3D surface
reset session
set view equal xyz
set xyplane relative 0.0
set xrange [-4:4]
set yrange [-4:4]
set zrange [-4:4]
# create 3D arrow
r = 0.01 # radius of arrow
rHead = 0.1 # radius of arrrowhead
n = 6 # corners of arrow
set print $myArrow
do for [h=-100:90] {
do for [a=360/n:360:360/n] {
print sprintf("%g %g %g",r*cos(a),r*sin(a), h/100.)
}
print ""
}
do for [h=90:100] {
do for [a=360/n:360:360/n] {
print sprintf("%g %g %g",rHead*(100-h)/10.*cos(a), \
rHead*(100-h)/10.*sin(a), h/100.)
}
print ""
}
set print
unset key
unset colorbox
set pm3d depthorder
set samples 100
set isosamples 100
set view 65,46,1.3
# function to demonstrate "piercing"
f(x,y) = (sin(x*3)/x + sin(y*3)/y - 3)/2
splot \
f(x,y) w pm3d, \
$myArrow u 1:2:($3*4):(0) w pm3d lc rgb var, \
$myArrow u 2:($3*4):1:(0) w pm3d lc rgb var, \
$myArrow u ($3*4):1:2:(0) w pm3d lc rgb var
### end of code
Результат:
А, отличный ответ. Я увеличил точки вокруг каждой стрелки, чтобы придать ей более плавный вид. Моим первым побуждением было установить параметрический режим. Если это уже другой 3d-объект, то менять его цвета утомительно, но легко на примере вроде этого: stackoverflow.com/questions/57465513/…
Спасибо :). Да, я забыл включить упомянутый вами ответ и еще один из моих ответов несколько месяцев назад: stackoverflow.com/a/64092310/7295599 . Было бы неплохо указать либо начальную/конечную точку трехмерного вектора/стрелки, либо, альтернативно, начальную точку, направление и длину вектора. Возможно, что-то похожее на («утомительные» векторные операции) используется здесь: stackoverflow.com/a/58468236/7295599
Я имею в виду. Наверное. Проблема по-прежнему остается, так как теперь все стрелки находятся спереди. Я бы подумал, что мой лучший шанс - иметь два объекта, заднюю часть стрелки, просто линию до места пересечения и другую от пересечения до кончика, причем кончики должны быть впереди. Позвольте мне попробовать это.