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