d1aa18d1b27a8f9e6271eed52ad043d1b46c6ec7
[scilab.git] / scilab / modules / graphics / sci_gateway / c / sci_plot2d.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2006 - INRIA - Fabrice Leray
4  * Copyright (C) 2006 - INRIA - Jean-Baptiste Silvy
5  * 
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at    
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 /*------------------------------------------------------------------------*/
15 /* file: sci_plot2d.c                                                     */
16 /* desc : interface for plot2d routine                                    */
17 /*------------------------------------------------------------------------*/
18
19 #include "gw_graphics.h"
20 #include "GetCommandArg.h"
21 #include "stack-c.h"
22 #include "BasicAlgos.h"
23 #include "sciCall.h"
24 #include "DefaultCommandArg.h"
25 #include "Scierror.h"
26 #include "localization.h"
27 #include "CurrentObjectsManagement.h"
28
29 /*------------------------------------------------------------------------*/
30 int sci_plot2d( char * fname, unsigned long fname_len )
31 {
32
33   int m1, n1, l1, m2, n2, l2, lt;
34   int test,i,j,iskip;
35   int frame_def=8;
36   int *frame=&frame_def;
37   int axes_def=1;
38   int *axes=&axes_def;
39
40   /* F.Leray 18.05.04 : log. case test*/
41   int size_x,size_y;
42   double xd[2];
43   double *x1;
44   char dataflag;
45
46   char   * logFlags = NULL  ;
47   int    * style    = NULL  ;
48   double * rect     = NULL  ;
49   char   * strf     = NULL  ;
50   char   * legend   = NULL  ;
51   int    * nax      = NULL  ;
52   BOOL     flagNax  = FALSE ;
53
54   static rhs_opts opts[]= { {-1,"axesflag","?",0,0,0},
55                                               {-1,"frameflag","?",0,0,0},
56                                         {-1,"leg","?",0,0,0},
57                                         {-1,"logflag","?",0,0,0},
58                                         {-1,"nax","?",0,0,0},
59                                         {-1,"rect","?",0,0,0},
60                                         {-1,"strf","?",0,0,0},
61                                         {-1,"style","?",0,0,0},
62                             {-1,NULL,NULL,0,0}};
63   if (Rhs == 0) 
64   {
65     sci_demo(fname, fname_len);
66     return 0;
67   }
68
69   CheckRhs(1,9);
70
71   iskip=0;
72   if ( get_optionals(fname,opts) == 0) 
73   { 
74           C2F(putlhsvar)();
75           return 0 ; 
76   }
77
78   if (GetType(1)==sci_strings)
79   {
80     /* logflags */
81     GetLogflags( fname, 1, opts, &logFlags ) ;
82     iskip=1;
83   }
84
85   if (GetType(1+iskip) != sci_matrix) {
86           Scierror(999, _("%s: Wrong type for input argument #%d: Real or Complex matrix expected.\n"), fname, 1+iskip);
87     return 0;
88   }
89
90   if (FirstOpt() == 2+iskip)                                    /** plot2d([loglags,] y, <opt_args>); **/
91   {
92     GetRhsVar(1+iskip,MATRIX_OF_DOUBLE_DATATYPE, &m2, &n2, &l2);
93
94     if (m2 == 1 && n2 > 1) { m2 = n2; n2 = 1;}
95     m1 = m2;  n1 = n2;
96     CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,  &m1, &n1, &l1);
97
98     for (i = 0; i < m2 ; ++i) 
99     {
100             for (j = 0 ; j < n2 ;  ++j)
101       {
102               *stk( l1 + i + m2*j) = (double) i+1;
103       }
104     }
105   }
106   else if (FirstOpt() >= 3 + iskip)     /** plot2d([loglags,] x, y[, style [,...]]); **/
107   {
108
109     /* x */
110     GetRhsVar(1+iskip,MATRIX_OF_DOUBLE_DATATYPE, &m1, &n1, &l1);
111
112     /* y */
113     if (GetType(2+iskip) != sci_matrix) {
114             Scierror(999, _("%s: Wrong type for input argument #%d: Real or Complex matrix expected.\n"), fname, 2+iskip);
115       return 0;
116     }
117     GetRhsVar(2+iskip,MATRIX_OF_DOUBLE_DATATYPE, &m2, &n2, &l2);
118
119     test = (m1*n1 == 0)||
120       ((m1 == 1 || n1 == 1) && (m2 == 1 || n2 ==1) && (m1*n1 == m2*n2))  ||
121       ((m1 == m2) && (n1 == n2)) ||
122       ((m1 == 1 && n1 == m2) || (n1 == 1 && m1 == m2));
123     CheckDimProp(1+iskip,2+iskip,!test);
124
125     if (m1*n1 == 0)
126     { /* default x=1:n */
127       CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,  &m2, &n2, &lt);
128       if (m2 == 1 && n2 > 1) { m2 = n2; n2 = 1;}
129       for (i = 0; i < m2 ; ++i) 
130       {
131               for (j = 0 ; j < n2 ;  ++j)
132         {
133                  *stk( lt + i + m2*j) = (double) i+1;
134         }
135       }
136       m1 = m2;
137       n1 = n2;
138       l1 = lt;
139     }
140     else if ((m1 == 1 || n1 == 1) && (m2 != 1 && n2 != 1) )
141     {
142       /* a single x vector for mutiple columns for y */
143       CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,  &m2, &n2, &lt);
144       for (i = 0; i < m2 ; ++i)
145       {
146               for (j = 0 ; j < n2 ;  ++j)
147         {
148                 *stk( lt + i + m2*j) = *stk(l1 +i);
149         }
150       }
151       m1 = m2;
152       n1 = n2;
153       l1 = lt;
154     }
155     else if ((m1 == 1 && n1 == 1) && (n2 != 1) )
156     {
157       /* a single y row vector  for a single x */
158       CreateVar(Rhs+1,MATRIX_OF_DOUBLE_DATATYPE,  &m1, &n2, &lt);
159       for (j = 0 ; j < n2 ;  ++j)
160       {
161               *stk( lt + j ) = *stk(l1);
162       }
163       n1 = n2;
164       l1 = lt;
165     }
166     else
167     {
168       if (m2 == 1 && n2 > 1) { m2 = n2; n2 = 1;}
169       if (m1 == 1 && n1 > 1) { m1 = n1; n1 = 1;}
170     }
171   }
172   else
173   {
174           Scierror(999, _("%s: Wrong number of mandatory input arguments. At least %d expected.\n"), fname, 1);
175           return 0;    
176   }
177
178   if(n1 == -1 || n2 == -1 || m1 == -1 || m2 == -1)
179   {
180           Scierror(999, _("%s: Wrong size for input arguments #%d and #%d.\n"), fname, 1, 2); /* @TODO : detail error */
181           return 0;
182   }
183
184   sciGetStyle( fname, 3+iskip, n1, opts, &style ) ;
185   GetStrf( fname, 4+iskip, opts, &strf ) ;
186   GetLegend( fname, 5+iskip, opts, &legend );
187   GetRect( fname, 6+iskip, opts, &rect );
188   GetNax( 7+iskip, opts, &nax, &flagNax ) ;
189   if (iskip==0) { GetLogflags( fname, 8, opts, &logFlags ) ; }
190
191   if ( isDefStrf( strf ) )
192   {
193     char strfl[4];
194     strcpy(strfl,DEFSTRFN);
195
196     strf = strfl;
197     if ( !isDefRect( rect ) )
198     {
199       strfl[1] = '7';
200     }
201     if ( !isDefLegend( legend ) )
202     {
203       strfl[0] = '1';
204     }
205
206     GetOptionalIntArg(fname,9,"frameflag",&frame,1,opts);
207     if( frame != &frame_def )
208     {
209       strfl[1] = (char)(*frame+48);
210     }
211     GetOptionalIntArg(fname, 9,"axesflag",&axes,1,opts);
212     if(axes != &axes_def)
213     {
214       strfl[2] = (char)(*axes+48);
215     }
216   }
217
218   /* Make a test on log. mode : available or not depending on the bounds set by Rect arg. or xmin/xmax :
219   Rect case :
220   - if the min bound is strictly posivite, we can use log. mode
221   - if not, send error message 
222   x/y min/max case:
223   - we find the first strictly positive min bound in Plo2dn.c ?? */
224
225   switch (strf[1])
226   {
227   case '0': 
228     /* no computation, the plot use the previous (or default) scale */
229     break;
230   case '1' : case '3' : case '5' : case '7':
231     /* based on Rect arg */ 
232     if( rect[0] > rect[2] || rect[1] > rect[3])
233     {
234       Scierror(999, _("%s: Impossible status min > max in x or y rect data.\n"),fname);
235       return -1;
236     }
237
238     if( rect[0] <= 0. && logFlags[1] =='l') /* xmin */
239     {
240       Scierror(999, _("%s: Bounds on x axis must be strictly positive to use logarithmic mode.\n"),fname);
241       return -1 ;
242     }
243
244     if( rect[1] <= 0. && logFlags[2] =='l') /* ymin */
245     {
246       Scierror(999, _("%s: Bounds on y axis must be strictly positive to use logarithmic mode.\n"),fname);
247       return -1 ;
248     }
249
250     break;
251   case '2' : case '4' : case '6' : case '8': case '9':
252     /* computed from the x/y min/max */
253     if ( (int)strlen(logFlags) < 1)
254     {
255       dataflag='g' ;
256     }
257     else
258     {
259       dataflag=logFlags[0];
260     }
261
262     switch ( dataflag )
263     {
264     case 'e' : 
265       xd[0] = 1.0; xd[1] = (double)m1;
266       x1 = xd;size_x = (m1 != 0) ? 2 : 0 ;
267       break; 
268     case 'o' : 
269       x1 = stk(l1);size_x = m1;
270       break;
271     case 'g' : 
272     default  : 
273       x1 = stk(l1);size_x = (n1*m1) ;
274       break; 
275     }
276
277     if (size_x != 0)
278     {
279       if(logFlags[1] == 'l' && sciFindStPosMin(stk(l1),size_x) <= 0.0 )
280       {
281         Scierror(999, _("%s: At least one x data must be strictly positive to compute the bounds and use logarithmic mode.\n"),fname);
282         return -1 ;
283       }
284     }
285
286     size_y = (n1*m1) ;
287
288     if (size_y != 0)
289     {
290       if( logFlags[2] == 'l' && sciFindStPosMin(stk(l2),size_y) <= 0.0 )
291       {
292         Scierror(999, _("%s: At least one y data must be strictly positive to compute the bounds and use logarithmic mode\n"),fname);
293         return -1 ;
294       }
295     }
296
297     break;
298   }
299
300   // open a figure if none already exists
301   sciGetCurrentFigure();
302   Objplot2d (1,logFlags,stk(l1), stk(l2), &n1, &m1, style, strf,legend, rect,nax,flagNax);
303
304   LhsVar(1) = 0;
305   C2F(putlhsvar)();
306   return 0;
307 }
308 /*------------------------------------------------------------------------*/