forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

%PL - some issues/questions
Goto page Previous  1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+
View previous topic :: View next topic  
Author Message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 6334
Location: Salford, UK

PostPosted: Wed May 13, 2020 2:46 pm    Post subject: Reply with quote

Martin

I have sent you a personal message.
Back to top
View user's profile Send private message AIM Address
Kenneth_Smith



Joined: 18 May 2012
Posts: 271
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Thu May 14, 2020 10:27 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Kenneth_Smith



Joined: 18 May 2012
Posts: 271
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Thu May 14, 2020 10:28 am    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 6334
Location: Salford, UK

PostPosted: Thu May 14, 2020 11:30 am    Post subject: Reply with quote

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
View user's profile Send private message AIM Address
Martin_K



Joined: 09 Apr 2020
Posts: 69

PostPosted: Thu May 14, 2020 6:37 pm    Post subject: Reply with quote

Ken,

many thanks, I will try to implement it!
Back to top
View user's profile Send private message
Martin_K



Joined: 09 Apr 2020
Posts: 69

PostPosted: Thu May 14, 2020 6:46 pm    Post subject: Reply with quote

Paul - thanks!

I implemented it and now it works as I want.
Back to top
View user's profile Send private message
Kenneth_Smith



Joined: 18 May 2012
Posts: 271
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Thu May 14, 2020 7:39 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Kenneth_Smith



Joined: 18 May 2012
Posts: 271
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Thu May 14, 2020 7:41 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Martin_K



Joined: 09 Apr 2020
Posts: 69

PostPosted: Thu May 14, 2020 10:44 pm    Post subject: Reply with quote

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
View user's profile Send private message
Kenneth_Smith



Joined: 18 May 2012
Posts: 271
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Thu May 14, 2020 11:33 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Martin_K



Joined: 09 Apr 2020
Posts: 69

PostPosted: Fri May 15, 2020 8:34 pm    Post subject: Reply with quote

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
View user's profile Send private message
Kenneth_Smith



Joined: 18 May 2012
Posts: 271
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Fri May 15, 2020 10:11 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Martin_K



Joined: 09 Apr 2020
Posts: 69

PostPosted: Fri May 15, 2020 10:13 pm    Post subject: Reply with quote

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
View user's profile Send private message
Martin_K



Joined: 09 Apr 2020
Posts: 69

PostPosted: Fri May 15, 2020 10:47 pm    Post subject: Reply with quote

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
View user's profile Send private message
Kenneth_Smith



Joined: 18 May 2012
Posts: 271
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Sat May 16, 2020 1:29 pm    Post subject: Reply with quote

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
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+ All times are GMT + 1 Hour
Goto page Previous  1, 2, 3, 4, 5, 6  Next
Page 2 of 6

 
Jump to:  
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