Search code examples
gnuplot

Plot angle arches, or how to have a custom `range` for successive (re)plot


I'm trying to create a 3d plot of some vectors in a unit sphere with angle arches between some of them. Here is the current situation. Note: I currently tried only two angle arches but in the end I need some more.

In order to add the arches, I oriented myself on the following tutorial (near the end '3D Case'): http://www.gnuplotting.org/tag/circle/

The problem is, they use urange and vrange to limit the angle of the arch. They can do this, because they only have two angles in the example and not multiple as I have.

So with my limited mathematical and gnuplot knowledge, I tinkered something together which kind of works: my angle arches attempt

What is kind of ungly is, that the line from the 'end' of my angle arch to 0,0,0is drawn and that even on top of my arrows specified underneath.

Is there a way to plot every arch with different urangeand vrange? Something like:

splot cos(u)*cos(v),cos(u)*sin(v),sin(u) notitle lc rgb "#B0000000" linetype 2,\
    [-pi/2:pi/2][0:2*pi] fvx(v),fvy(v),fvz lc rgb "#7878ff" linetype 1,\
    [-pi/2:0][0:2*pi] fux(u),fuy(u),fuz(u)

Or is there something I'm completely missing?

Here is my code so far..:

set xrange [-1:1]
set yrange [-1:1]
set zrange [-1:1]

set xyplane at 0 #z axis 0 should be on xy-plane


set parametric

set urange [-pi/2:pi/2]
set vrange [0:2*pi]

set key off

#view schraeg: 32,320
set view 32,320, 1,1
set style arrow 1 linecolor rgb "#FF0000"
set style arrow 2 linecolor rgb "#ff5252" 
set style arrow 3 linecolor rgb "#0000FF" 
set style arrow 4 linecolor rgb "#0000FF" nohead
set style arrow 6 linecolor rgb "#880000FF" nohead
set style arrow 5 linecolor rgb "#FF0000" nohead

# Angle between m' and x axis
r0 = 0.1
fvx(v) = v<2.5793017540894563 ? r0*cos(v) : 0
fvy(v) = v<2.5793017540894563 ? r0*sin(v) : 0
fvz = 0

# Angle between n and m
r = 0.5
fux(u) = u >= 0.7915660086835659 ? r*cos(u)*cos(2.5793017540894563) : 0
fuy(u) = u >= 0.7915660086835659 ? r*cos(u)*sin(2.5793017540894563) : 0
fuz(u) = u >= 0.7915660086835659 ? r*sin(u) : 0

splot cos(u)*cos(v),cos(u)*sin(v),sin(u) notitle lc rgb "#B0000000" linetype 2,\
    fvx(v),fvy(v),fvz lc rgb "#7878ff" linetype 1,\
    fux(u),fuy(u),fuz(u)

set arrow from 0,0,0 to 1,0,0 nohead # x axis       
set arrow from 0,0,0 to 0,1.5,0 nohead # y axis
set arrow from 0,0,0 to 0,0,2 nohead # z axis

set arrow from 0,0,0 to 0.49999999999999994, 0, 0.8660254037844387 arrowstyle 1     #light
set arrow from 0,0,0 to 0.49999999999999994, 0, 0 arrowstyle 5      #light 1
set arrow from 0.49999999999999994, 0, 0 to 0.49999999999999994, 0, 0.8660254037844387 arrowstyle 5     #light 2
set arrow from 0,0,0 to -0.49999999999999994, 0, 0.8660254037844387 arrowstyle 2        #specular
set arrow from 0,0,0 to -0.6078313957973345, 0.3830222215594889, 0.6955824696430309 arrowstyle 3        #measure
set arrow from 0,0,0 to -0.6078313957973345, 0.3830222215594889, 0 arrowstyle 6                         #measure flat
set arrow from 0,0.3830222215594889,0 to -0.6078313957973345, 0.3830222215594889, 0 arrowstyle 6        #measure 1
set arrow from -0.6078313957973345,0,0 to -0.6078313957973345, 0.3830222215594889, 0 arrowstyle 6       #measure 2
set arrow from -0.6078313957973345, 0.3830222215594889, 0 to -0.6078313957973345, 0.3830222215594889, 0.6955824696430309 arrowstyle 4       #measure 3


pause -1

Solution

  • If you cannot specify the range (because you are using a replot approach, which is sensible), then, change the function!

    You can make a change of variable to accomodate any other range. Say:

    set parametric
    set urange [0:pi]
    splot 0,0,0 # because internal variables are not initialised else, this will not be a problem in your example.
    CoV(u,min,max)=min+(u-GPVAL_U_MIN)*(max-min)/(GPVAL_U_MAX-GPVAL_U_MIN)
    splot cos(CoV(u,pi/3,pi/2)),sin(CoV(u,pi/3,pi/2)),0
    

    The CoV (change of variable) uses the ranges of variable u at the time of plotting (Gnuplot variables GPVAL_U_*) to rescale u between the prescribed minimum and maximum values. The ugly splot 0,0,0 might be spared with future versions of gnuplot using stats command, but not yet with version 5.0. Alternatively, one can set his own variables initially:

    my_u_min=0.
    my_u_max=pi
    set urange [my_u_min:my_u_max]
    U_MIN(dummy)=(exists("GPVAL_U_MIN")?GPVAL_U_MIN:my_u_min)
    U_MAX(dummy)=(exists("GPVAL_U_MAX")?GPVAL_U_MAX:my_u_max)
    CoV(u,min,max)=min+(u-U_MIN(0))*(max-min)/(U_MAX(0)-U_MIN(0))