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