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