graphics: bug 9270 fixed - The contour function was broken.
[scilab.git] / scilab / modules / graphics / macros / contour2d.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) INRIA
3 // Copyright (C) 2011 - DIGITEO - Michael Baudin
4 // This file must be used under the terms of the CeCILL.
5 // This source file is licensed as described in the file COPYING, which
6 // you should have received as part of this distribution.  The terms
7 // are also available at    
8 // http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
9
10 function levels=contour2d(x,y,z,nz,style,strf,leg,rect,nax,void)
11
12 [lhs,rhs]=argn(0)
13 if rhs<4 then
14   error(msprintf(gettext("%s: Wrong number of input argument(s): At least %d expected.\n"), "contour2d", 4));
15 end
16
17 opts=[]
18 levels=[]
19 if ~exists('style','local')==1 then 
20   if size(nz,'*')==1 then
21     style=1:nz,
22   else
23     style=1:size(nz,'*')
24   end
25 end
26 if exists('strf','local')==1 then 
27   yflag=part(strf,2)
28   if or(yflag==['2' '4' '6' '8']) then
29     rect=[min(x),min(y),max(x),max(y)]
30     yflag=string(evstr(yflag)-1)
31     strf=part(strf,1)+yflag+part(strf,3)
32   end
33   opts=[opts,'strf=strf'],
34 end
35 if exists('leg','local')==1 then opts=[opts,'leg=leg'],end
36 rectSpecified = %f ;
37 if exists('rect','local')==1 then 
38   opts=[opts,'rect=rect'];
39   rectSpecified = %t ;
40 end
41 if exists('nax','local')==1 then opts=[opts,'nax=nax'],end
42 if exists('logflag','local')==1 then opts=[opts,'logflag=logflag'],end
43 //if exists('frameflag','local')==1 then opts=[opts,'frameflag=frameflag'],end
44 if exists('frameflag','local')==1 then 
45   opts=[opts,'frameflag=frameflag'],
46 else 
47   frameflag=[]
48 end
49 if exists('axesflag','local')==1 then opts=[opts,'axesflag=axesflag'],end
50 opts=strcat([opts,"style=style(c)"],',')
51
52 if or(type(z)==[11 13]) then 
53   fun=z;clear z //to avoid redfinition warning
54   if type(fun)==11 then comp(fun),end
55   z=feval(x,y,fun)
56 end
57
58 [xc,yc]=contour2di(x,y,z,nz);
59 fpf=xget("fpf");if fpf=='' then fpf='%.3g',end
60
61
62 fig=gcf();
63 autoc=fig.auto_clear;
64 if autoc=="on" then, clf(),end
65 a=gca();
66 v=fig.immediate_drawing;
67 fig.immediate_drawing="off"
68 fig.auto_clear="off"
69 cnt=0
70
71
72 // we draw the contour with call to plot2d for each level line
73 // however the data_bounds will be always reset after each plot
74 // so we must compute before the bounding rectangle (xmin,ymin,xmax,ymax)
75 // and give it to each plot2d. This is useful for frameflag = (2,4,6,8)
76 // since the data_bounds are given by the extrema of x and y
77 if ( frameflag == 2 | frameflag == 4 | frameflag == 6 | frameflag == 8 )
78   // get the bounding rectangle
79   rect = [min(x),min(y),max(x),max(y)];
80   // set the option accordingly
81   if ~rectSpecified then
82     opts=strcat([opts,'rect=rect'],',');
83   end
84   // the rect will be taken into account
85   frameflag = frameflag - 1 ;
86 elseif (~rectSpecified) then
87   // get rect any way for clipping
88   rect = [min(x),min(y),max(x),max(y)];
89 end
90
91 k=1;n=yc(k); c=0; level = %inf;
92 while k < length(xc)
93    n = yc(k)
94    if xc(k) ~= level then 
95      c = c+1; level = xc(k),levels=[level levels];
96
97      if cnt>0 then glue(a.children(1:cnt)),cnt=0,end
98
99    end
100    err = execstr('plot2d(xc(k+(1:n)),yc(k+(1:n)),'+opts+')','errcatch','m');
101    frameflag = 0 ;
102    
103    // add a test to see if plot2d call succeed
104    // and, if not, restore good figure property values before exiting
105    if err <> 0
106      mprintf("Error %d : in plot2d called by contour2d",err);
107      fig.immediate_drawing=v;
108      fig.auto_clear=autoc;
109      return;
110    end
111    
112
113     unglue(a.children(1))
114     cnt = cnt+1
115
116    if stripblanks(fpf)<>'' then
117       labelText = " " + msprintf(fpf,level);
118           labelPos = [xc(k+1+n/2),yc(k+1+n/2)];
119           labelBox = stringbox(labelText, labelPos(1), labelPos(2));
120           // check that the text is not outside the box
121           // better than clipping to avoid half cut strings
122       if labelBox(1,1) > rect(1) & labelBox(2,1) > rect(2) & ...
123          labelBox(1,3) < rect(3) & labelBox(2,3) < rect(4) then
124         xstring(labelPos(1),labelPos(2),labelText)
125                 e = gce();e.clip_state = "off";
126         cnt=cnt+1;
127       end
128    end
129    k=k+n+1;
130 end
131
132
133  if cnt>0 then glue(a.children(1:cnt)),cnt=0,end
134  set('current_entity',a);
135  fig.immediate_drawing=v;
136  fig.auto_clear=autoc;
137  draw(fig)
138
139 endfunction