* Bug 15816 fixed: upstream drawlater ignored by polarplot, mesh, pie, contourf
[scilab.git] / scilab / modules / graphics / macros / polarplot.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) INRIA
3 // Copyright (C) 2010 - DIGITEO - Manuel Juliachs
4 // Copyright (C) 2012 - 2016 - Scilab Enterprises
5 // Copyright (C) 2010, 2018 - Samuel GOUGEON
6 //
7 // This file is hereby licensed under the terms of the GNU GPL v2.0,
8 // pursuant to article 5.3.4 of the CeCILL v.2.1.
9 // This file was originally licensed under the terms of the CeCILL v2.1,
10 // and continues to be available under such terms.
11 // For more information, see the COPYING file which you should have received
12 // along with this program.
13
14 function polarplot(theta,rho,style,strf,leg,rect)
15     [lhs,rhs]=argn(0)
16     if rhs<=0 then
17         theta=0:.01:2*%pi;
18         rho=sin(2*theta).*cos(2*theta)
19         s = gca().axes_bounds;
20         delete(gca()); xsetech(s) // clears & keeps the current axes area
21         polarplot(theta,rho)
22         return
23     end
24     if size(theta,1)==1 then
25         theta=theta(:),
26     end
27     if size(rho,1)==1 then
28         rho=rho(:),
29     end
30     rm=max(abs(rho))
31     x=rho.*cos(theta)
32     y=rho.*sin(theta)
33
34     opts=[]
35     isstrf=%f;
36     isframeflag=%f;
37     isrect=%f;
38     if exists("style","local")==1 then
39         opts=[opts,"style=style"]
40     end
41     if exists("strf","local")==1 then
42         opts=[opts,"strf=strf"]
43         isstrf=%t
44     end
45     if exists("leg","local")==1 then
46         opts=[opts,"leg=leg"]
47     end
48     if exists("rect","local")==1 then
49         opts=[opts,"rect=rect"]
50         isrect=%t
51     end
52     if exists("frameflag","local")==1 then
53         opts=[opts,"frameflag=frameflag"]
54         isframeflag=%t
55     end
56
57     if size(opts,2)<rhs-2 then
58         error(msprintf(gettext("%s: Wrong value for input argument: ''%s'', ''%s'', ''%s'', ''%s'' or ''%s'' expected.\n"),"polarplot","style","strf","leg","rect","frameflag"));
59     end
60
61     // Some default values:
62     Amin=0 // starting angle for the frame
63     dA=360 // span of the angular frame
64     nn=4    // number of quadrants to be drawn
65
66     xmin=min(x);
67     xmax=max(x);
68     L=(xmax-xmin)*1.07;
69     ymin=min(y);
70     ymax=max(y);
71     H=(ymax-ymin)*1.07;
72     // Angle at which Radial labels will be displayed
73     A=round(atan((ymin+ymax)/2,(xmin+xmax)/2)/%pi*180/45)*45;
74     dx=-0.5, dy=-0.5  // H & V shifts in string-width and string-height units
75
76     // Case without rect=
77     if ~isrect then
78         // Determines quadrant(s) to be drawn
79         Q=[%T %T %T %T];
80         e=rm/500;
81
82         if min(x)<-e then
83             xmin=-rm;
84         else
85             xmin=0; Q([2 3])=%F;
86         end
87
88         if max(x)>e then
89             xmax= rm;
90         else
91             xmax=0; Q([1 4])=%F;
92         end
93
94         if min(y)<-e then
95             ymin=-rm;
96         else
97             ymin=0; Q([3 4])=%F;
98         end
99
100         if max(y)>e then
101             ymax= rm;
102         else
103             ymax=0; Q([1 2])=%F;
104         end
105
106         L=(xmax-xmin)*1.1; if L==0, L=2*rm*1.1; end
107         H=(ymax-ymin)*1.1; if H==0, H=2*rm*1.1; end
108         x0=(xmin+xmax)/2; y0=(ymin+ymax)/2;
109         rect=[x0-L/2 y0-H/2 x0+L/2 y0+H/2]
110
111         // Special case: data aligned on the x or y axis
112         if Q==[%F %F %F %F],
113             if (ymax-ymin)<2*e, // on x axis
114                 if xmin<-e then
115                     Q([2 3])=%T
116                 end
117                 if xmax> e  then
118                     Q([1 4])=%T
119                 end
120             else  // on y axis
121                 if ymin<-e  then
122                     Q([3 4])=%T
123                 end
124                 if ymax> e then
125                     Q([1 2])=%T
126                 end
127             end
128         end
129
130         n=find(Q);   // id numbers of quadrants to be drawn
131         nn=length(n) // number of quadrants to be drawn
132         Amin=(n(1)-1)*90
133
134         select nn
135         case 1,
136             dA=90;
137             if n==1, A=90, dx=-1.1, dy=-0.5
138             elseif n==2, A=90, dx=0.2, dy=-0.5
139             elseif n==3, A=270, dx=0.2, dy=-0.5
140             else A=270, dx=-1.1, dy=-0.5
141             end
142         case 2
143             dA=180;
144             if n(1)==1
145                 if n(2)==2, //A=90, dx=0.1, dy=-0.5
146                 else Amin=-90, A=90, dx=-1.2, dy=-0.5, end
147             elseif n(1)==2, A=90, dx=0.2, dy=-0.5
148             else A=0, dx=-0.5, dy=0.2
149             end
150         else
151             Amin=0, dA=360
152         end
153         opts=[opts,"rect=rect"]
154     end // if ~isrect
155
156     if isstrf& isframeflag then
157         error(msprintf(gettext("%s: ''%s'' cannot be used with ''%s''.\n"),"polarplot","frameflag","strf"));
158     end
159     if ~(isstrf) then
160         axesflag=0
161         opts=[opts,"axesflag=axesflag"],
162     end
163     if ~(isstrf|isframeflag) then
164         frameflag=4
165         opts=[opts,"frameflag=frameflag"],
166     end
167
168     initDrawingMode = gcf().immediate_drawing;
169     gcf().immediate_drawing = "off";
170     execstr("plot2d(x,y,"+strcat(opts,",")+")")
171
172     fcolor=color("grey70");
173
174     // CIRCULAR FRAME:
175     // Radial values for the frame:
176     fmt_in=format(), format("v",9)
177     // Tunning for smart values:
178     p=floor(log10(abs(rm)));
179     m=rm/10^p;
180     if m<1.3, dm=0.2
181     elseif m<=2, dm=0.3
182     elseif m<4, dm=0.5
183     else dm=1,
184     end
185     k=fix(m/dm)
186     if m-k*dm < dm/5, k=k-1, end
187     R=[(1:k)*dm*10^p ]
188     // Tuning for smart 10^ display using LaTeX instead of D+## exponential display
189     if abs(p)<4,
190         Rtxt=string(R)
191         [v,k]=max(length(Rtxt))
192         tmp=xstringl(0,0,Rtxt(k))
193     else
194         if dm<1, dm=dm*10, p=p-1, end
195         tmp = string(R/10^p)+"108"
196         [v,k] = max(length(tmp))
197         tmp = xstringl(0,0,tmp(k))
198         Rtxt = "$\scriptstyle "+string(R/10^p)+"\:.10^{"+string(p)+"}$";
199     end
200     w = tmp(3); h = tmp(4);
201     format(fmt_in(2),fmt_in(1))  // Restoring entrance format
202     R = [ R  rm ]
203
204     // Drawing & labelling the radial frame
205     kM=size(R,"*");
206     for k=1:kM
207         r=R(k)
208         xarc(-r,r,2*r,2*r,Amin*64,dA*64)
209         e = gce();
210         e.line_style = 3
211         e.foreground = fcolor;
212         if k==kM
213             e.line_style=1;  // solid outer arc
214         else
215             xstring(r*cosd(A)+w*dx, r*sind(A)+h*dy, Rtxt(k))
216             e = gce();
217             e.clip_state = "off";
218         end
219     end
220
221     // ANGULAR FRAME:
222     if nn<3, eA=10, else eA=30; end // adaptative angular sampling
223     an=linspace(Amin,Amin+dA,round(dA/eA)+1);
224     // avoiding 360 == 0
225     if nn>2, tmp=find(abs(an-360)<eA/10); an(tmp)=[]; end
226     // Adjusting H-shifts of angular labels
227     tmp=xstringl(0,0,"360");
228     w=tmp(3); h=tmp(4);
229     rL=rm*1.03;  // Radius of angular labels
230     for k=an  // draws and labels angular rays
231         xsegs([0;rm*cosd(k)],[0;rm*sind(k)])
232         e = gce();
233         e.segs_color = fcolor;
234         e.line_style = 3;
235         xstring((rL+w/2)*cosd(k)-w/2, (rL+h/2)*sind(k)-h/2, string(k))
236         e = gce();
237         e.clip_state = "off";
238     end
239
240     a=gca();
241     a.data_bounds=[rect(1:2);rect(3:4)]
242     a.margins=[0.07 0.07 0.12 0.07]
243
244     gcf().immediate_drawing = initDrawingMode;
245 endfunction