Interface property zoom_box and zoom_state of axes objects.
[scilab.git] / scilab / modules / graphics / src / c / axesScale.c
1 /*------------------------------------------------------------------------*/
2 /* file: axesScale.c                                                      */
3 /* Copyright INRIA 2006                                                   */
4 /* Authors : Fabrice Leray, Jean-Baptiste Silvy                           */
5 /* desc : Contains functions to compute scale changes in a specific       */
6 /*        subwindow.                                                      */
7 /*------------------------------------------------------------------------*/
8
9
10 #include "axesScale.h"
11 #include "math_graphics.h"
12 #include "MALLOC.h"
13 #include "GetProperty.h"
14 #include "SetProperty.h"
15 #include "sciprint.h"
16 #include "PloEch.h"
17 #include "GraphicZoom.h"
18 #include "Vertices.h"
19 #include "localization.h"
20 #include "SetPropertyStatus.h"
21
22 /*------------------------------------------------------------------------------*/
23 double InvAxis( double min, double max, double u )
24 {
25   /*return (u-min) / (max-min) * min + (u-max) / (min-max) * max ;*/
26   return min + max - u ; /* ahah little simplification */
27 }
28 /*------------------------------------------------------------------------------*/
29 int ReverseDataFor3DXonly( sciPointObj * psubwin, double xvect[], int n1 )
30 {
31   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin) ;
32   int cmp;
33
34   if( ppsubwin->axes.reverse[0] )
35   {
36     /* agir sur x */
37     if( ppsubwin->logflags[0] == 'l' )
38     {
39       for( cmp = 0 ; cmp < n1 ; cmp++ )
40       {
41         xvect[cmp] = log10( xvect[cmp] ) ;
42         xvect[cmp] = InvAxis( ppsubwin->FRect[0], ppsubwin->FRect[2], xvect[cmp] ) ;
43         xvect[cmp] = exp10( xvect[cmp] ) ;
44       }
45     }
46     else
47     {
48       for( cmp = 0 ; cmp < n1 ; cmp++ )
49       {
50         xvect[cmp] = InvAxis( ppsubwin->FRect[0], ppsubwin->FRect[2], xvect[cmp] ) ;
51       }
52     }
53   }
54
55   return 0 ;
56 }
57 /*------------------------------------------------------------------------------*/
58 int ReverseDataFor3DYonly( sciPointObj * psubwin, double yvect[], int n1 )
59 {
60   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin);
61   int cmp;
62
63   if( ppsubwin->axes.reverse[1] )
64   {
65     /* agir sur y */
66     if(ppsubwin->logflags[1]=='l'){
67       for(cmp=0;cmp<n1;cmp++)
68       {
69         yvect[cmp] = log10(yvect[cmp]);
70         yvect[cmp] = InvAxis(ppsubwin->FRect[1],ppsubwin->FRect[3],yvect[cmp]);
71         yvect[cmp] = exp10(yvect[cmp]);
72       }
73     }
74     else
75     {
76       for(cmp=0;cmp<n1;cmp++)
77       {
78         yvect[cmp] =  InvAxis(ppsubwin->FRect[1],ppsubwin->FRect[3],yvect[cmp]);
79       }
80     }
81   }
82
83   return 0;
84 }
85 /*------------------------------------------------------------------------------*/
86 int ReverseDataFor3DZonly( sciPointObj * psubwin, double zvect[], int n1 )
87 {
88   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(psubwin);
89   int cmp;
90
91   if( zvect == NULL ) { return 0 ; }
92
93   if( ppsubwin->axes.reverse[2] )
94   {
95     /* agir sur z */
96     if(ppsubwin->logflags[2]=='l')
97     {
98       for(cmp=0;cmp<n1;cmp++)
99       {
100         zvect[cmp] = log10(zvect[cmp]);
101         zvect[cmp] = InvAxis(ppsubwin->FRect[4],ppsubwin->FRect[5],zvect[cmp]);
102         zvect[cmp] = exp10(zvect[cmp]);
103       }
104     }
105     else
106     {
107       for(cmp=0;cmp<n1;cmp++)
108       {
109         zvect[cmp] =  InvAxis(ppsubwin->FRect[4],ppsubwin->FRect[5],zvect[cmp]);
110       }
111     }
112   }
113
114   return 0;
115 }
116 /*------------------------------------------------------------------------------*/
117 int ReverseDataFor3D( sciPointObj * psubwin, double xvect[], double yvect[], double zvect[], int n1 )
118 {
119
120   ReverseDataFor3DXonly(psubwin, xvect, n1);
121   ReverseDataFor3DYonly(psubwin, yvect, n1);
122   ReverseDataFor3DZonly(psubwin, zvect, n1);
123
124   return 0;
125 }
126 /*------------------------------------------------------------------------------*/
127 int trans3d( sciPointObj * pobj,
128              integer       n   ,
129              integer       xm[],
130              integer       ym[],
131              double        x[] ,
132              double        y[] ,
133              double        z[]  )
134 {
135   integer i;
136   double tmpx,tmpy,tmpz;
137   double  tmpx1,tmpy1,tmpz1;
138   /* TEST F.Leray 20.04.04: I fix HERE temporarily BOOL cube_scaling = FALSE; */
139   BOOL cube_scaling;
140   /* Test to enable reverse axis in 3D */ /* F.Leray 14.10.04 */
141   sciSubWindow * ppsubwin = pSUBWIN_FEATURE(pobj);
142
143   double *xtmp = NULL;
144   double *ytmp = NULL;
145   double xz1 ;
146   double yz1 ;
147
148   if (sciGetEntityType(pobj) != SCI_SUBWIN) { return 1 ; }
149
150   xtmp = MALLOC(n*sizeof(double));
151   ytmp = MALLOC(n*sizeof(double));
152
153   cube_scaling = pSUBWIN_FEATURE(pobj)->cube_scaling;
154
155   if( !cube_scaling)
156   {
157     if (z == (double *) NULL)
158     {
159       for ( i=0 ; i < n ; i++)
160       {
161         /* F.Leray 19.10.04 */
162         /* Test to export logscale in 3D */
163
164         if(ppsubwin->logflags[0] == 'l')
165         {
166           tmpx = log10(x[i]);
167         }
168         else
169         {
170           tmpx = x[i];
171         }
172
173         if(ppsubwin->logflags[1] == 'l')
174         {
175           tmpy = log10(y[i]);
176         }
177         else
178         {
179           tmpy = y[i];
180         }
181
182         if(ppsubwin->logflags[2] == 'l'){
183           sciprint(_("Warning: Value on z data is negative or zero while logarithmic scale enabled\n"));
184           sciprint(_("Object not drawn\n"));
185           FREE(xtmp); xtmp = NULL; FREE(ytmp); ytmp = NULL;
186           return 0;
187         }
188
189         xz1 = TX3D(tmpx,tmpy,0.0);
190         yz1 = TY3D(tmpx,tmpy,0.0);
191         xm[i] = inint( xz1 ) ;
192         ym[i] = inint( yz1 ) ;
193
194         if( isZoom3dOn() )
195         {
196           Store3DPixelValues(pobj,xm[i],ym[i],tmpx,tmpy,0.); /* stockage des xm, ym pour le zoom */
197         }
198
199         if ( finite(xz1)==0||finite(yz1)==0 ){
200           FREE(xtmp); xtmp = NULL; FREE(ytmp); ytmp = NULL;
201           return(0);
202         }
203       }
204     }
205     else /* z != NULL */
206     {
207       for ( i=0 ; i < n ; i++) /* cas 3d le + general */
208       {
209
210         /* F.Leray 19.10.04 */
211         /* Test to export logscale in 3D */
212
213         if(ppsubwin->logflags[0] == 'l')
214           tmpx = log10(x[i]);
215         else
216           tmpx = x[i];
217
218         if(ppsubwin->logflags[1] == 'l')
219           tmpy = log10(y[i]);
220         else
221           tmpy = y[i];
222
223         if(ppsubwin->logflags[2] == 'l')
224           tmpz = log10(z[i]);
225         else
226           tmpz = z[i];
227
228         
229         xz1 = TX3D(tmpx,tmpy,tmpz);
230         yz1 = TY3D(tmpx,tmpy,tmpz);
231         xm[i] = inint( xz1 ) ;
232         ym[i] = inint( yz1 ) ;
233
234         if( isZoom3dOn() )
235           Store3DPixelValues(pobj,xm[i],ym[i],tmpx,tmpy,tmpz); /* stockage des xm, ym pour le zoom */
236
237         if ( finite(xz1)==0||finite(yz1)==0 ){
238           FREE(xtmp); xtmp = NULL; FREE(ytmp); ytmp = NULL;
239           return(0);
240         }
241         /*      } */
242       }
243       FREE(xtmp); xtmp = NULL; FREE(ytmp); ytmp = NULL;
244     }
245   }
246   else   /* cube_scaling == TRUE now */
247   {
248     if (z == (double *) NULL)
249     {
250       for ( i=0 ; i < n ; i++)
251       {
252
253         /* F.Leray 03.11.04 */
254         /* Test to export logscale in 3D */
255
256         if(ppsubwin->logflags[0] == 'l')
257           tmpx = log10(x[i]);
258         else
259           tmpx = x[i];
260
261         if(ppsubwin->logflags[1] == 'l')
262           tmpy = log10(y[i]);
263         else
264           tmpy = y[i];
265
266         if(ppsubwin->logflags[2] == 'l'){
267           sciprint(_("Warning: Value on z data is negative or zero while logarithmic scale enabled\n"));
268           sciprint(_("Object not drawn\n"));
269           FREE(xtmp); xtmp = NULL; FREE(ytmp); ytmp = NULL;
270           return 0;
271         }
272
273         tmpx1 = tmpx;
274         tmpy1 = tmpy;
275         tmpz1 = 0.;
276
277         tmpx=(tmpx-pSUBWIN_FEATURE (pobj)->FRect[0])/(pSUBWIN_FEATURE (pobj)->FRect[2]-pSUBWIN_FEATURE (pobj)->FRect[0]);
278         tmpy=(tmpy-pSUBWIN_FEATURE (pobj)->FRect[1])/(pSUBWIN_FEATURE (pobj)->FRect[3]-pSUBWIN_FEATURE (pobj)->FRect[1]);
279         tmpz=(0.-pSUBWIN_FEATURE (pobj)->FRect[4])/(pSUBWIN_FEATURE (pobj)->FRect[5]-pSUBWIN_FEATURE (pobj)->FRect[4]); /* Adding F.Leray 04.11.04 */
280
281         xz1 = TX3D(tmpx,tmpy,tmpz);
282         yz1 = TY3D(tmpx,tmpy,tmpz);
283         xm[i] = inint( xz1 ) ;
284         ym[i] = inint( yz1 ) ;
285
286         if( isZoom3dOn())
287           Store3DPixelValues(pobj,xm[i],ym[i],tmpx1,tmpy1,tmpz1); /* stockage des xm, ym pour le zoom */
288
289         if ( finite(xz1)==0||finite(yz1)==0 ){
290           FREE(xtmp); xtmp = NULL; FREE(ytmp); ytmp = NULL;
291           return(0);
292         }
293       }
294     }
295     else /* z != NULL */
296     {
297       for ( i=0 ; i < n ; i++)
298       {
299
300         /* F.Leray 03.11.04 */
301         /* Test to export logscale in 3D */
302
303         if(ppsubwin->logflags[0] == 'l')
304           tmpx = log10(x[i]);
305         else
306           tmpx = x[i];
307
308         if(ppsubwin->logflags[1] == 'l')
309           tmpy = log10(y[i]);
310         else
311           tmpy = y[i];
312
313         if(ppsubwin->logflags[2] == 'l')
314           tmpz = log10(z[i]);
315         else
316           tmpz = z[i];
317
318         tmpx1 = tmpx;
319         tmpy1 = tmpy;
320         tmpz1 = tmpz;
321
322         tmpx= (tmpx-pSUBWIN_FEATURE (pobj)->FRect[0])/(pSUBWIN_FEATURE (pobj)->FRect[2]-pSUBWIN_FEATURE (pobj)->FRect[0]);
323         tmpy= (tmpy-pSUBWIN_FEATURE (pobj)->FRect[1])/(pSUBWIN_FEATURE (pobj)->FRect[3]-pSUBWIN_FEATURE (pobj)->FRect[1]);
324         tmpz= (tmpz-pSUBWIN_FEATURE (pobj)->FRect[4])/(pSUBWIN_FEATURE (pobj)->FRect[5]-pSUBWIN_FEATURE (pobj)->FRect[4]); /* Adding F.Leray 28.04.04 */
325
326         xz1 = TX3D(tmpx,tmpy,tmpz);
327         yz1 = TY3D(tmpx,tmpy,tmpz);
328         xm[i] = inint( xz1 ) ;
329         ym[i] = inint( yz1 ) ;
330
331         if( isZoom3dOn() )
332           Store3DPixelValues(pobj,xm[i],ym[i],tmpx1,tmpy1,tmpz1); /* stockage des xm, ym pour le zoom */
333
334         if ( finite(xz1)==0||finite(yz1)==0 ){
335           FREE(xtmp); xtmp = NULL; FREE(ytmp); ytmp = NULL;
336           return(0);
337         }
338       }
339     }
340   }
341   FREE(xtmp); xtmp = NULL; FREE(ytmp); ytmp = NULL;
342   return(1);
343 }
344 /*------------------------------------------------------------------------------*/
345 /**
346  * Specify new zoom box for a subwin object.
347  * @param zoomRect vector [xMin, yMin, xMax, yMax]
348  */
349 int sciZoom2D(sciPointObj * pObj, const double zoomRect[4])
350 {
351   double zoomBox[6];
352
353   // add Z scale to data bounds.
354   sciGetDataBounds(pObj, zoomBox);
355   zoomBox[0] = zoomRect[0];
356   zoomBox[1] = zoomRect[1];
357   zoomBox[2] = zoomRect[2];
358   zoomBox[3] = zoomRect[3];
359
360   return sciZoom3D(pObj, zoomBox);
361
362 }
363 /*------------------------------------------------------------------------------*/
364 /**
365  * Specify a new zoom box for a subwin object
366  * @param zoomBox vector [xMin, yMin, xMax, yMax, zMin, zMax].
367  */
368 int sciZoom3D(sciPointObj * pObj, const double zoomBox[6])
369 {
370   // convert zoomBox to [xMin, xMax, yMin, yMax, zMin, zMax]
371   double zoomBox3D[6];
372   zoomBox3D[0] = zoomBox[0];
373   zoomBox3D[1] = zoomBox[2];
374   zoomBox3D[2] = zoomBox[1];
375   zoomBox3D[3] = zoomBox[3];
376   zoomBox3D[4] = zoomBox[4];
377   zoomBox3D[5] = zoomBox[5];
378
379   if (!checkDataBounds(pObj, zoomBox3D[0], zoomBox3D[1], zoomBox3D[2],
380                        zoomBox3D[3], zoomBox3D[4], zoomBox3D[5]))
381   {
382     return SET_PROPERTY_ERROR;
383   }
384
385   sciSetZoomBox(pObj, zoomBox3D);
386
387   sciSetZooming(pObj, TRUE);
388
389   return SET_PROPERTY_SUCCEED;
390 }
391 /*------------------------------------------------------------------------------*/
392 /**
393  * Unzoom the selected subwin
394  */
395 void sciUnzoom(sciPointObj * pObj)
396 {
397   sciSetZooming(pObj, FALSE);
398 }
399 /*------------------------------------------------------------------------------*/
400 /**
401  * get the zoom box to dispplay in Scilab for a sunwin object
402  * @param[out] zoomBox [xMin, yMin, xMax, yMax, zMin, zMax];
403  */
404 void sciGetZoom3D(sciPointObj * pObj, double zoomBox[6])
405 {
406   double temp;
407
408   // here we get [xMin, xMax, yMin, yMax, zMin, zMax]
409   // we need to switch xMax and yMin
410   sciGetZoomBox(pObj, zoomBox);
411   temp = zoomBox[1];
412   zoomBox[1] = zoomBox[2];
413   zoomBox[2] = temp;
414 }
415 /*------------------------------------------------------------------------------*/
416 /**
417  * Check if the follawing data bounds can be used as new data bounds for the subwin object
418  * @return TRUE if values can be used, false otherwise
419  */
420 BOOL checkDataBounds(sciPointObj * pObj, double xMin, double xMax,
421                      double yMin, double yMax, double zMin, double zMax)
422 {
423   char logFlags[3];
424   sciGetLogFlags(pObj, logFlags);
425
426   /* check if there is not an inf within the values */
427   /* since this has not any meaning */
428   if (    !finite(xMin) || !finite(xMax)
429        || !finite(yMin) || !finite(yMax)
430        || !finite(zMin) || !finite(zMax) )
431   {
432     sciprint("Error : data bounds values must be finite.");
433     return FALSE ;
434   }
435
436
437   /* check if the bounds are corrects */
438   /* allows equality with bounds since it is working */
439   if ( xMin > xMax || yMin > yMax || zMin > zMax )
440   {
441     sciprint("Error : Min and Max values for one axis do not verify Min <= Max.\n");
442     return FALSE ;
443   }
444
445   /* check for logflags that values are greater than 0 */
446   if (   ( logFlags[0] == 'l' && xMin <= 0.0 )
447       || ( logFlags[1] == 'l' && yMin <= 0.0 )
448       || ( logFlags[2] == 'l' && zMin <= 0.0 ) )
449   {
450     sciprint("Error: bounds on axis must be strictly positive to use logarithmic mode.\n" ) ;
451     return FALSE ;
452   }
453
454   return TRUE;
455 }
456 /*------------------------------------------------------------------------------*/