Add interactive zoom_rect.
[scilab.git] / scilab / modules / graphics / src / c / math_graphics.c
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 1998-2001 - ENPC - Jean-Philippe Chancelier
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  *    Graphic library
16  --------------------------------------------------------------------------*/
17
18 #include "math_graphics.h"
19
20 /* 
21  * we use spConfig.h for machine constants 
22  * XXX : spConfig should be merged and unified 
23  *       with other machine constant scilab code 
24  */
25
26 #define spINSIDE_SPARSE
27 #include "../../sparse/includes/spConfig.h"
28
29 double Mini(double *vect, integer n)
30 {
31   int i;
32   double vmin;
33   vmin = LARGEST_REAL;
34   for (i = 0 ; i < n ; i++)
35     /*    if ( isinf(vect[i])== 0 && isnan(vect[i])==0 && vect[i] < vmin)  */
36     if ( finite(vect[i])== 1 && vect[i] < vmin) 
37       vmin=vect[i];
38   return(vmin);
39 }
40
41 double Maxi(double *vect,integer n)
42 {
43   int i;
44   double maxi;
45   maxi= - LARGEST_REAL;
46   for (i =0 ; i < n ; i++)
47     /* if ( isinf(vect[i])== 0 && isnan(vect[i])==0 && vect[i] > maxi) */
48     if ( finite(vect[i])== 1 && vect[i] > maxi) 
49       maxi=vect[i];
50   return(maxi);
51 }
52
53 /*----------------------------------------------------------------------------*/
54
55 /* perform the rotation of point from to point dest  */
56 void rotate2D( double from[2], double center[2], double angle, double dest[2] )
57 {
58   rotate2Dim( from, center, cos( angle ), sin( angle ), dest ) ;
59 }
60
61 /*----------------------------------------------------------------------------*/
62 /* perform the rotation of point from to point to. */
63 /* the angle is directly given with its sine and cosine for speed */
64 void rotate2Dim( double from[2]   ,
65                  double center[2] ,
66                  double cosAngle  ,
67                  double sinAngle  ,
68                  double dest[2]    )
69 {
70   double diff[2] ;
71
72   /* put the center to (0,0) */
73   diff[0] = from[0] - center[0] ;
74   diff[1] = from[1] - center[1] ;
75
76   /* turn and translate back */
77   dest[0] = diff[0] * cosAngle - diff[1] * sinAngle + center[0] ;
78   dest[1] = diff[0] * sinAngle + diff[1] * cosAngle + center[1] ;
79 }
80 /*----------------------------------------------------------------------------*/
81 /* perform the rotation of point from to point dest given in int with angle in radian  */
82 void iRotate2D( int from[2], int center[2], double angle, int dest[2] )
83 {
84   iRotate2Dim( from, center, cos( angle ), sin( angle ), dest ) ;
85 }
86
87 /*----------------------------------------------------------------------------*/
88 /* perform the rotation of point from to point to. */
89 /* the angle is directly given with its sine and cosine for speed */
90 void iRotate2Dim( int    from[2]   ,
91                   int    center[2] ,
92                   double cosAngle  ,
93                   double sinAngle  ,
94                   int    dest[2]    )
95 {
96   int diff[2] ;
97
98   /* put the center to (0,0) */
99   diff[0] = from[0] - center[0] ;
100   diff[1] = from[1] - center[1] ;
101
102   /* turn and translate back */
103   dest[0] = round( diff[0] * cosAngle - diff[1] * sinAngle + center[0] ) ;
104   dest[1] = round( diff[0] * sinAngle + diff[1] * cosAngle + center[1] ) ;
105 }
106 /*----------------------------------------------------------------------------*/
107 /* perform an homethety point from to point dest. The 2 factors stand for the ration */
108 /* along the 2 coordinates */
109 void homothety2D( double from[2], double center[2], double factors[2], double dest[2] )
110 {
111   dest[0] = center[0] + factors[0] * ( from[0] - center[0] ) ;
112   dest[1] = center[1] + factors[1] * ( from[1] - center[1] ) ;
113 }
114 /*----------------------------------------------------------------------------*/
115 /* perform an homethety point from to point dest given in pixels. */
116 /* The 2 factors stand for the ration along the 2 coordinates */
117 void iHomothety2D( int from[2], int center[2], double factors[2], int dest[2] )
118 {
119   dest[0] = round( center[0] + factors[0] * ( from[0] - center[0] ) ) ;
120   dest[1] = round( center[1] + factors[1] * ( from[1] - center[1] ) ) ;
121 }
122 /*----------------------------------------------------------------------------*/
123 /* perform the translation of point from to point to with vector trans */
124 void translate2D( double from[2], double trans[2], double dest[2] )
125 {
126   dest[0] = from[0] + trans[0] ;
127   dest[1] = from[1] + trans[1] ;
128 }
129 /*----------------------------------------------------------------------------*/
130 void iTranslate2D( int from[2], int trans[2], int dest[2] )
131 {
132   dest[0] = from[0] + trans[0] ;
133   dest[1] = from[1] + trans[1] ;
134 }
135 /*----------------------------------------------------------------------------*/
136 void vectSubstract2D(const double vect1[2], const double vect2[], double res[2])
137 {
138   res[0] = vect1[0] - vect2[0];
139   res[1] = vect1[1] - vect2[1];
140 }
141 /*----------------------------------------------------------------------------*/
142 void normalize2d( double vect[2] )
143 {
144   double norm = NORM_2D(vect) ;
145   vect[0] /= norm ;
146   vect[1] /= norm ;
147 }
148 /*----------------------------------------------------------------------------*/
149 void iNormalize2d( int vect[2] )
150 {
151   double norm = NORM_2D(vect) ;
152   vect[0] = round( vect[0] / norm ) ;
153   vect[1] = round( vect[1] / norm ) ;
154 }
155 /*----------------------------------------------------------------------------*/
156 void crossProduct( const double v1[3], const double v2[3], double res[3] )
157 {
158   /* save data to be able to use v1 o v2 as res */
159   double v10 = v1[0];
160   double v20 = v2[0];
161   double v11 = v1[1];
162   double v21 = v2[1];
163   res[0] = v11 * v2[2] - v1[2] * v21 ;
164   res[1] = v1[2] * v20 - v10 * v2[2] ;
165   res[2] = v10 * v21 - v11 * v20 ;
166 }
167 /*----------------------------------------------------------------------------*/
168 void vectSubstract3D(const double v1[3] ,const double v2[3], double res[3])
169 {
170   res[0] = v1[0] - v2[0];
171   res[1] = v1[1] - v2[1];
172   res[2] = v1[2] - v2[2];
173 }
174 /*----------------------------------------------------------------------------*/
175 void vectAdd3D(const double v1[3], const double v2[3], double res[3])
176 {
177   res[0] = v1[0] + v2[0];
178   res[1] = v1[1] + v2[1];
179   res[2] = v1[2] + v2[2];
180 }
181 /*----------------------------------------------------------------------------*/
182 void scalarMult3D(const double v[3], const double scalar, double res[3])
183 {
184   res[0] = scalar * v[0];
185   res[1] = scalar * v[1];
186   res[2] = scalar * v[2];
187 }
188 /*----------------------------------------------------------------------------*/
189 void normalize3D( double vect[3] )
190 {
191   double norm = NORM_3D(vect) ;
192   vect[0] /= norm ;
193   vect[1] /= norm ;
194   vect[2] /= norm ;
195 }
196 /*----------------------------------------------------------------------------*/
197 void setToIdentity(double mat4D[4][4])
198 {
199   int i;
200   int j;
201   for (i = 0; i < 4; i++)
202   {
203     for (j = 0; j < 4; j++)
204     {
205       mat4D[i][j] = 0.0;
206     }
207     mat4D[i][i] = 1.0;
208   }
209 }
210 /*----------------------------------------------------------------------------*/
211 void mat4DMult(const double mat4D[4][4], const double vect3D[3], double res[3])
212 {
213   int i;
214   double res4D[4];
215   // w coordinate of the vector is supposed to be 1;
216   for (i = 0; i < 4; i++) {
217     res4D[i]  =  vect3D[0] * mat4D[i][0] + vect3D[1] * mat4D[i][1]
218                + vect3D[2] * mat4D[i][2] + mat4D[i][3];
219   }
220   res[0] = res4D[0] / res4D[3];
221   res[1] = res4D[1] / res4D[3];
222   res[2] = res4D[2] / res4D[3];
223 }
224 /*----------------------------------------------------------------------------*/
225 /* check if two values can be considered equal given an accurracy */
226 int safeEqual( double val1, double val2, double accuracy )
227 {
228   /* the val1 == val2 is put to avoid division by 0 */
229   return ( val1 == val2 ) || ( Abs( val1 - val2 ) < accuracy * Max( Abs(val1), Abs(val2 ) ) ) ;
230 }
231 /*----------------------------------------------------------------------------*/