|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7931 Location: Salford, UK
|
Posted: Wed May 13, 2020 2:46 pm Post subject: |
|
|
Martin
I have sent you a personal message. |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Thu May 14, 2020 10:27 am Post subject: |
|
|
Martin,
Below you will find an example that allows you to change the extents of the %pl region after it is initially displayed - a crude zoom function.
For this to work you must use the new DLLs posted by Paul this morning.
http://forums.silverfrost.com/viewtopic.php?t=4214
Ken
Last edited by Kenneth_Smith on Thu May 14, 2020 10:37 am; edited 1 time in total |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Thu May 14, 2020 10:28 am Post subject: |
|
|
Code: | module example
implicit none
integer, parameter :: dp = kind(1.d0), n = 1000
real(kind=dp), parameter :: pi = 3.14159265359d0
real(kind=dp), parameter :: dt = 1.d-4, omega = 50.d0*2.d0*pi, ta = 0.040d0
real(kind=dp) t1(1:n), ac(1:n), dc(1:n), inst(1:n)
real(kind=dp) :: xmin_data, xmax_data, ymin_data, ymax_data, xmin_plot, xmax_plot, ymin_plot, ymax_plot, xstep, ystep
contains
integer function generate_data()
integer i
do i = 1, n, 1
if (i .gt. 1) then
t1(i) = t1(i-1) + dt
else
t1(i) = 0.d0
end if
ac(i) = sqrt(2.d0)*cos(omega*t1(i)-pi) ; dc(i) = -ac(1)*exp(-t1(i)/ta) ; inst(i)=ac(i)+dc(i)
end do
generate_data = 1
end function generate_data
integer function plot()
include<windows.ins>
integer, save :: iw
xmin_data = minval(t1) ; xmax_data = maxval(t1)
ymin_data = min(minval(ac), minval(dc), minval(inst)) ; ymax_data = max(maxval(ac), maxval(dc), maxval(inst))
xstep = (xmax_data - xmin_data)/5.d0 ; print*, xstep ; ystep = (ymax_data - ymin_data)/5.d0 ; print*, ystep
xmin_plot = xmin_data ; ymin_plot = ymin_data ; xmax_plot = xmax_data ; ymax_plot = ymax_data
call winop@('%pl[native,x_array,gridlines,n_graphs=3,width=2,frame,etched,colour=blue,colour=red,colour=black]')
iw = winio@('%^pl&',700,600,n,t1,ac,dc,inst,pl_cb)
iw = winio@('%2nl%cn%^tt[Change limits]&',change_limits_cb)
iw = winio@('%ff%2nl%cn%tt[Close]&')
iw = winio@(' ')
plot = 1
end function plot
integer function pl_cb()
include<windows.ins>
character(len=30) cb_reason
cb_reason = clearwin_string@('callback_reason')
print*, 'pl_cb: ', cb_reason
pl_cb = 1
end function pl_cb
integer function change_limits_cb()
include<windows.ins>
integer, save :: iw
integer k
iw = winio@('%nl%ws%ta%fl%df%rf&', 'Xmin',xmin_data,xmax_data,xstep, xmin_plot)
iw = winio@('%nl%ws%ta%fl%df%rf&', 'Ymin',ymin_data,ymax_data,ystep, ymin_plot)
iw = winio@('%nl%ws%ta%fl%df%rf&', 'Xmax',xmin_data,xmax_data,xstep, xmax_plot)
iw = winio@('%nl%ws%ta%fl%df%rf&', 'Ymax',ymin_data,ymax_data,ystep, ymax_plot)
iw = winio@('%2nl%cn%^tt[Apply]&', apply_new_limits_cb)
iw = winio@(' ')
change_limits_cb = 1
end function change_limits_cb
integer function apply_new_limits_cb()
include<windows.ins>
integer k
if (xmax_plot - xmin_plot .gt. epsilon(1.0) ) then
if (ymax_plot - ymin_plot .gt. epsilon(1.0) ) then
k = CHANGE_PLOT_DBL@(0, 'x_min', 0, xmin_plot) ; print*,'x_min',k
k = CHANGE_PLOT_DBL@(0, 'x_max', 0, xmax_plot) ; print*,'x_max',k
k = CHANGE_PLOT_DBL@(0, 'y_min', 0, ymin_plot) ; print*,'y_min',k
k = CHANGE_PLOT_DBL@(0, 'y_max', 0, ymax_plot) ; print*,'y_max',k
call simpleplot_redraw@()
else
print*, 'Bad range for Y'
end if
else
print*, 'Bad range for X'
end if
apply_new_limits_cb = 1
end function apply_new_limits_cb
end module example
program main
use example
i = generate_data() ; i = plot()
end program main |
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7931 Location: Salford, UK
|
Posted: Thu May 14, 2020 11:30 am Post subject: |
|
|
Martin
The E format can be avoided by specifying the number of significant figures. For example...
Code: | CALL winop@('%pl[x_sigfigs=7]')
CALL winop@('%pl[y_sigfigs=7]')
|
|
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Thu May 14, 2020 6:37 pm Post subject: |
|
|
Ken,
many thanks, I will try to implement it! |
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Thu May 14, 2020 6:46 pm Post subject: |
|
|
Paul - thanks!
I implemented it and now it works as I want. |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Thu May 14, 2020 7:39 pm Post subject: |
|
|
Martin,
Take a look at this.
Code: | module example
implicit none
integer, parameter :: dp = kind(1.d0), n = 1000
real(kind=dp), parameter :: pi = 3.14159265359d0, dt = 1.d-4, omega = 50.d0*2.d0*pi, ta = 0.040d0
real(kind=dp) t1(1:n), ac(1:n), dc(1:n), inst(1:n), xmin_data, xmax_data, ymin_data, ymax_data, xstep, ystep
real(kind=dp) x_min_now, x_max_now, y_min_now, y_max_now
contains
integer function generate_data()
integer i
do i = 1, n, 1
if (i .gt. 1) then
t1(i) = t1(i-1) + dt
else
t1(i) = 0.d0
end if
ac(i) = sqrt(2.d0)*cos(omega*t1(i)-pi) ; dc(i) = -ac(1)*exp(-t1(i)/ta) ; inst(i)=ac(i)+dc(i)
end do
generate_data = 1
end function generate_data
integer function plot()
include<windows.ins>
integer, save :: iw
xmin_data = minval(t1) ; xmax_data = maxval(t1)
ymin_data = min(minval(ac), minval(dc), minval(inst)) ; ymax_data = max(maxval(ac), maxval(dc), maxval(inst))
xstep = (xmax_data - xmin_data)/10.d0 ; ystep = (ymax_data - ymin_data)/10.d0
x_min_now = xmin_data ; x_max_now = xmax_data ; y_min_now = ymin_data ; y_max_now = ymax_data
call winop@('%pl[native,x_array,gridlines,n_graphs=3,width=2,frame,etched,colour=blue,colour=red,colour=black]')
iw = winio@('%pl[full_mouse_input]&',700,600,n,t1,ac,dc,inst)
iw = winio@('%ob[scored]&')
iw = winio@('%2nl%cn%^tt[Zoom in]&', zoom_in_cb)
iw = winio@('%2nl%cn%^tt[Zoom out]&', zoom_out_cb)
iw = winio@('%2nl%cn%^tt[Full extents]%2nl&', zoom_out_full_cb)
iw = winio@('%2nl%cn%^tt[Pan pos X]&', pan_positive_x_cb)
iw = winio@('%2nl%cn%^tt[Pan neg X]&', pan_negative_x_cb)
iw = winio@('%2nl%cn%^tt[Pan pos Y]&', pan_positive_y_cb)
iw = winio@('%2nl%cn%^tt[Pan neg Y]&', pan_negative_y_cb)
iw = winio@('%cb%ff%2nl%cn%tt[Close]&')
iw = winio@(' ') ; plot = 1
end function plot
integer function update_pl_limits()
include<windows.ins>
integer k
k = CHANGE_PLOT_DBL@(0, 'x_min', 0, x_min_now) ; k = CHANGE_PLOT_DBL@(0, 'x_max', 0, x_max_now)
k = CHANGE_PLOT_DBL@(0, 'y_min', 0, y_min_now) ; k = CHANGE_PLOT_DBL@(0, 'y_max', 0, y_max_now)
call simpleplot_redraw@()
update_pl_limits = 1
end function update_pl_limits
subroutine swap_real_dp(r1,r2)
real(kind=dp), intent(inout) :: r1, r2
real(kind=dp) temp
temp = r2 ; r2 = r1 ; r1 = temp
end subroutine swap_real_dp
integer function zoom_out_cb()
include<windows.ins>
integer i
x_min_now = x_min_now - xstep ; x_max_now = x_max_now + xstep ; y_min_now = y_min_now - ystep ; y_max_now = y_max_now + ystep
i = update_pl_limits() ; zoom_out_cb = 1
end function zoom_out_cb | [/quote] |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Thu May 14, 2020 7:41 pm Post subject: |
|
|
Part 2
Code: |
integer function zoom_in_cb()
real(kind=dp) x_min_now_save, x_max_now_save, y_min_now_save, y_max_now_save
integer i
integer, save :: iw
x_min_now_save = x_min_now ; x_max_now_save = x_max_now ; y_min_now_save = y_min_now ; y_max_now_save = y_max_now
x_min_now = x_min_now + xstep ; x_max_now = x_max_now - xstep ; y_min_now = y_min_now + ystep ; y_max_now = y_max_now - ystep
if ( ( x_max_now - x_min_now .gt. xstep ) .and. ( y_max_now - y_min_now .gt. xstep ) ) then
i = update_pl_limits()
else
x_min_now = x_min_now_save ; x_max_now = x_max_now_save ; y_min_now = y_min_now_save ; y_max_now = y_max_now_save
iw = winio@('%ws%2nl%cn%tt[Continue]','Max zoom level with this control.')
end if
zoom_in_cb = 1
end function zoom_in_cb
integer function zoom_out_full_cb()
integer i
x_min_now = xmin_data ; y_min_now = ymin_data ; x_max_now = xmax_data ; y_max_now = ymax_data ; i = update_pl_limits()
zoom_out_full_cb = 1
end function zoom_out_full_cb
integer function pan_positive_x_cb()
integer i
x_min_now = x_min_now + xstep ; x_max_now = x_max_now + xstep ; i = update_pl_limits() ; pan_positive_x_cb = 1
end function pan_positive_x_cb
integer function pan_negative_x_cb()
integer i
x_min_now = x_min_now - xstep ; x_max_now = x_max_now - xstep ; i = update_pl_limits() ; pan_negative_x_cb = 1
end function pan_negative_x_cb
integer function pan_positive_y_cb()
integer i
y_min_now = y_min_now + ystep ; y_max_now = y_max_now + ystep ; i = update_pl_limits() ; pan_positive_y_cb = 1
end function pan_positive_y_cb
integer function pan_negative_y_cb()
integer i
y_min_now = y_min_now - ystep ; y_max_now = y_max_now - ystep ; i = update_pl_limits() ; pan_negative_y_cb = 1
end function pan_negative_y_cb
end module example
program main
use example
implicit none
integer i
i = generate_data() ; i = plot()
end program main |
|
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Thu May 14, 2020 10:44 pm Post subject: |
|
|
Ken - huge thanks!
I will review your code thoroughly and will try to implement it. Just one thing is not quite clear for me at the moment (after first review of your code).
One line of your code says:
Code: |
iw = winio@('%pl[full_mouse_input]&',700,600,n,t1,ac,dc,inst)
|
Are the INST values for the 4th graphs? (you specified in the preceding statement that N_GRAPHS=3 and in the code above seems to me that the 4th argument INST should provide the values for the 4th graph. When you specified N_GRAPHS=3, why do you use 4 arguments: t1 array, ac array, dc array and inst array? There should be only 3 arguments - t1,ac,dc. Am I wrong with this interpretation?).
Martin |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Thu May 14, 2020 11:33 pm Post subject: |
|
|
Martin,
In this case I am not using the [independent] option. There are three graphs to be plotted.
ac vs. t1 i.e. Y1 vs X (a sinusoidal wave)
dc vs. tt i.e. Y2 vs X (a decaying dc wave)
inst vs. t1 i.e. Y3 vs X (the sum of these waves � at this point you may realise I am an electrical engineer).
Looking again at the code, in this case you can dispense with the [full_mouse_input] option. That�s a hangover from something that did not work as I expected it to with certain combinations of compiler options. For the same reason you can delete the subroutine swap_real_dp.
So the call to %pl should be:
Code: |
call winop@('%pl[native,x_array,gridlines,n_graphs=3,width=2,frame,etched,colour=blue,colour=red,colour=black]')
iw = winio@('%pl&',700,600,n,t1,ac,dc,inst)
|
n is the number of data points, scalar as all three graphs have the same number of points and I am not using [independent]
t1 is the array of x data common to all three graphs.
ac is the first graph (y1 data).
dc is the second graph (y2 data).
inst is the third graph (y3 data)
The important lines to permit everything to work after the %pl is initially drawn are at the beginning of the function plot(). These identify the range of the data, by scanning the input arrays, and set the increment size for zooming in and out.
Ken |
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Fri May 15, 2020 8:34 pm Post subject: |
|
|
Ken - many thanks!
Now, I am making an effort to implement it. Formally, I already got it, but I have still troubles.
Questions to you:
Q1: Should I use in the function UPDATE_PL_LIMITS in the code:
Code: |
k = CHANGE_PLOT_DBL@(0, 'x_min', 0, x_min_now) ; k = CHANGE_PLOT_DBL@(0, 'x_max', 0, x_max_now)
k = CHANGE_PLOT_DBL@(0, 'y_min', 0, y_min_now) ; k = CHANGE_PLOT_DBL@(0, 'y_max', 0, y_max_now)
|
exactly the names 'x_min' , 'y_min', 'x_max', 'y_max' (which are officially declared %PL options)
OR
can I use my own names for them (like below)?
Code: |
k=CHANGE_PLOT_DBL@(0,'x_mriezka_min',0,x_min_now); k=CHANGE_PLOT_DBL@(0,'x_mriezka_max',0,x_max_now)
k=CHANGE_PLOT_DBL@(0,'y_mriezka_min',0,y_min_now); k=CHANGE_PLOT_DBL@(0,'y_mriezka_max',0,y_max_now)
|
Q2: Since I sue [independent], I have two graphs put in one (points of the state border and grid points (nodes) overlaying the first one).
Should I define the whole procedures also for first graph (points of state border)? I defined the procedures only for the grid points. |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Fri May 15, 2020 10:11 pm Post subject: |
|
|
Martin,
You must use the names �x_min� etc as these will be the strings which the internal code in CHANCE_PLOT_DBLE@ searches for when working through its own internal logic.
Assuming your arrays are X_BORDER, Y_BORDER, X_GRID, Y_GRID, then you will need:
Code: | xmin_data = min ( minval(X_BORDER), minval(X_GRID) )
ymin_data = min ( minval(Y_BORDER), minval(Y_GRID) )
xmax_data = max ( maxval(X_BORDER), maxval(X_GRID) )
ymax_data = max ( maxval(Y_BORDER), maxval(Y_GRID) )
xstep = (xmax_data - xmin_data)/10.d0
ystep = (ymax_data - ymin_data)/10.d0
x_min_now = xmin_data
x_max_now = xmax_data
y_min_now = ymin_data
y_max_now = ymax_data
npoints(1) = size(X_BORDER) ! Two element integer array.
npoints(2) = size(X_GRID) !Assuming the same number of points in each paired X and Y array.
call winop@('%pl[native,x_array,gridlines,n_graphs=2,width=2,frame,etched,colour=blue,colour=red, link=lines, link=none ,symbol=0, symbol=12')
iw = winio@('%pl[independent]&',700,600,npoints,X_BORDER,Y_BORDER,X_GRID,Y_GRID)
|
As I have just typed the above its not been tested! From this point onwards in the code, I don�t think any other parts of code in the module will require any changes as xmin_data, ymin_data etc, capture the full range of coordinates for both sets of input data.
Symbol=12 is a recent addition, which has not found its way into the help file yet � it draws a �+� at the data points.
Note however, if you have a 5 km x 5 km grid, with 1 km spacing, if X_GRID = (0, 1, 2, 3, 4, 5) and Y_GRID = (0, 1, 2, 3, 4, 5) the code above will draw the grid points in a diagonal line across the %pl region, as what�s expected (in an X-Y plotter) is
X_GRID = (0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5,0,1,2,3,4,5 ����������)
Y_GRID = (0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3, ���������.)
So the storage requirements increases by N**2.
Hopefully we will see a screen shot of it all working before too long.
Ken |
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Fri May 15, 2020 10:13 pm Post subject: |
|
|
Ken, partial SUCCESS!
Now, it (partially) works. Forget my Q1 question. It was - of coarse - due
to reserved words 'x_min', 'y_min', ... for the function CHANGE_PLOT_DBL@!
I used them instead of the names defined by me and first problem is solved. I can see that the values on both axes are changing when clicking on zoom in/out.
However, there is still another problem: as soon as I zoom in or zoom out, the cloud of 87000+ points (which is initially drawn very dense, so it appears as a rectangular surface with no distances visible between neighbouring nodes of the grid) disappears and never
come back (although the tick values on both axes are changing after zoom in/out clicking accordingly!
I would also like to see your answer to Q2 - thanks! |
|
Back to top |
|
|
Martin_K
Joined: 09 Apr 2020 Posts: 227
|
Posted: Fri May 15, 2020 10:47 pm Post subject: |
|
|
Thanks Ken for your fast response!
In the meantime, I already found the problem. I forgot that I have to change the axes, since slovakian coordinate system has a very specific feature: it uses Křov�k conic projection on Bessel�s ellipsoid and direction of its planar axes is totally different than in mathematics, it means - the +X direction goes to the South and +Y direction goes to the West. So, mathematically, we are in the 3rd quadrant. So, I changed the axes and the grid points are there!
I will try to realize your suggestion for both graphs, BUT the number of points in the two graphs is NOT identical. Number of border points is 47000+ and number of grid points is 87000+. BTW, even now, when I switch off the grid points and clicking on zoom in/out when only the graphs of border points is switched on (hence, I see Slovakia on the graphs), it reacts to zooming in/out and the shape of the country is changing (is extending or scaling down).
The step of grid points is 1000m in both directions. For the zooming in/out - what step would be sensible? At the moment - I have the same like grid step. |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 697 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Sat May 16, 2020 1:29 pm Post subject: |
|
|
Martin,
In the demonstration code you will see the calculation of xstep and ystep. These define the changes to the displayed data for when zooming in or out, or panning left, right, up, or down. At present these are fixed before the call to %pl, and they also define the maximum possible zoom in
Code: | xstep = (xmax_data - xmin_data)/10.d0
ystep = (ymax_data - ymin_data)/10.d0
|
With the code above, the extents drawn decreases by 20% of the full extents at each zoom in operation, with a maximum of 4 such operations , due to the logical test:
Code: | if ( ( x_max_now - x_min_now .gt. xstep ) .and. ( y_max_now - y_min_now .gt. xstep ) ) then
�����
|
in function zoom_in_cb().
You may have to vary this approach slightly for your application. For example you could program your code to zoom in by a percentage of the currently displayed extents at each zoom operation, i.e. modify the value of effective value of xstep and ystep (by a zoom level dependent multiplying factor) as applied in the call back functions.
The question you have to think about is how many zoom operations is required to get from the full extents to the level where the display finally becomes useful to the user. You will need to experiment to get something that works well for your application.
Yes, the border will become distorted since the no of pixels per km on the x and y axis differ.
One way to get round this would be ensure that x_min_data, y_min_data, x_max_data, and y_max_data define a square, modifying the example code immediately after these are calculated and before the calculation of x_step and y_step. Then make sure the graphics area in which the %pl plot is generated is also a square. Note the size of the plot is not the first two X, Y, size values in the call to %pl. These X, Y values define the overall size of the graphics area which includes four borders. If you make sure X and Y are equal, and setting all borders to the **same value** this will preserve the aspect ratio as you zoom in and out. Note the border must be sufficient large to accommodate the caption, and x and y axis labels. The y axis label will be the critical one when deciding which size of border to use. Note the %pl code is [margin] not border!
If you want to preserve a landscape format � to fit a wide screen for example you will need a different strategy for zooming in/out etc. However, you now have all the necessary understanding of how %pl works, and how to get it to redraw a selected region to apply your adopted strategy � whatever that may be.
Ken |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|