Bug 12399 fixed: Bad data bounds computation with %inf and log scale
[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(const double vect[], int n)
30 {
31     int i = 0;
32     double vmin = LARGEST_REAL;
33     for (; i < n ; i++)
34     {
35         /*    if ( isinf(vect[i])== 0 && isnan(vect[i])==0 && vect[i] < vmin)  */
36         if (finite(vect[i]) == 1 && vect[i] < vmin)
37         {
38             vmin = vect[i];
39         }
40     }
41
42     return vmin;
43 }
44
45 double Maxi(const double vect[], int n)
46 {
47     int i = 0;
48     double maxi = -LARGEST_REAL;
49     for (; i < n ; i++)
50     {
51         /* if ( isinf(vect[i])== 0 && isnan(vect[i])==0 && vect[i] > maxi) */
52         if (finite(vect[i]) == 1 && vect[i] > maxi)
53         {
54             maxi = vect[i];
55         }
56     }
57
58     return maxi;
59 }
60
61 void MiniMaxi(const double vect[], int n, double * const min, double * const max)
62 {
63     int i = 0;
64     double _min = LARGEST_REAL;
65     double _max = -LARGEST_REAL;
66     for (; i < n ; i++)
67     {
68         /*    if ( isinf(vect[i])== 0 && isnan(vect[i])==0 && vect[i] < vmin)  */
69         if (finite(vect[i]) == 1)
70         {
71             if (vect[i] < _min)
72             {
73                 _min = vect[i];
74             }
75             if (vect[i] > _max)
76             {
77                 _max = vect[i];
78             }
79         }
80     }
81
82     *min = _min;
83     *max = _max;
84 }
85
86 /*----------------------------------------------------------------------------*/
87
88 /* perform the rotation of point from to point dest  */
89 void rotate2D( double from[2], double center[2], double angle, double dest[2] )
90 {
91     rotate2Dim( from, center, cos( angle ), sin( angle ), dest ) ;
92 }
93
94 /*----------------------------------------------------------------------------*/
95 /* perform the rotation of point from to point to. */
96 /* the angle is directly given with its sine and cosine for speed */
97 void rotate2Dim( double from[2]   ,
98                  double center[2] ,
99                  double cosAngle  ,
100                  double sinAngle  ,
101                  double dest[2]    )
102 {
103     double diff[2] ;
104
105     /* put the center to (0,0) */
106     diff[0] = from[0] - center[0] ;
107     diff[1] = from[1] - center[1] ;
108
109     /* turn and translate back */
110     dest[0] = diff[0] * cosAngle - diff[1] * sinAngle + center[0] ;
111     dest[1] = diff[0] * sinAngle + diff[1] * cosAngle + center[1] ;
112 }
113 /*----------------------------------------------------------------------------*/
114 /* perform the translation of point from to point to with vector trans */
115 void translate2D( double from[2], double trans[2], double dest[2] )
116 {
117     dest[0] = from[0] + trans[0] ;
118     dest[1] = from[1] + trans[1] ;
119 }
120 /*----------------------------------------------------------------------------*/
121 void iTranslate2D( int from[2], int trans[2], int dest[2] )
122 {
123     dest[0] = from[0] + trans[0] ;
124     dest[1] = from[1] + trans[1] ;
125 }
126 /*----------------------------------------------------------------------------*/
127 void vectSubstract2D(const double vect1[2], const double vect2[], double res[2])
128 {
129     res[0] = vect1[0] - vect2[0];
130     res[1] = vect1[1] - vect2[1];
131 }
132 /*----------------------------------------------------------------------------*/
133 void vectAdd2D(const double v1[2], const double v2[2], double res[2])
134 {
135     res[0] = v1[0] + v2[0];
136     res[1] = v1[1] + v2[1];
137 }
138 /*----------------------------------------------------------------------------*/
139 void scalarMult2D(const double v[2], const double scalar, double res[2])
140 {
141     res[0] = scalar * v[0];
142     res[1] = scalar * v[1];
143 }
144 /*----------------------------------------------------------------------------*/
145 void normalize2d( double vect[2] )
146 {
147     double norm = NORM_2D(vect) ;
148     vect[0] /= norm ;
149     vect[1] /= norm ;
150 }
151 /*----------------------------------------------------------------------------*/
152 void iNormalize2d( int vect[2] )
153 {
154     double norm = NORM_2D(vect) ;
155     vect[0] = round( vect[0] / norm ) ;
156     vect[1] = round( vect[1] / norm ) ;
157 }
158 /*----------------------------------------------------------------------------*/
159 BOOL isPointInTriangle(const double point[2], const double a[2],
160                        const double b[2], const double c[2])
161 {
162     return (   areOnSameSideOfLine(point, a, b, c)
163                && areOnSameSideOfLine(point, b, a, c)
164                && areOnSameSideOfLine(point, c, a, b));
165 }
166 /*----------------------------------------------------------------------------*/
167 BOOL areOnSameSideOfLine(const double p1[2], const double p2[2],
168                          const double a[2], const double b[2])
169 {
170     // point are on the same if and only if (AB^AP1).(AB^AP2) >= 0
171     double ab[3];
172     double ap1[3];
173     double ap2[3];
174     double cp1[3];
175     double cp2[3];
176
177     ab[0] = b[0] - a[0];
178     ab[1] = b[1] - a[1];
179     ab[2] = 0.0;
180
181     ap1[0] = p1[0] - a[0];
182     ap1[1] = p1[1] - a[1];
183     ap1[2] = 0.0;
184
185     ap2[0] = p2[0] - a[0];
186     ap2[1] = p2[1] - a[1];
187     ap2[2] = 0.0;
188
189     crossProduct(ab, ap1, cp1);
190     crossProduct(ab, ap2, cp2);
191
192     return (DOT_PROD_3D(cp1, cp2) >= 0.0);
193
194 }
195 /*----------------------------------------------------------------------------*/
196 void crossProduct( const double v1[3], const double v2[3], double res[3] )
197 {
198     /* save data to be able to use v1 o v2 as res */
199     double v10 = v1[0];
200     double v20 = v2[0];
201     double v11 = v1[1];
202     double v21 = v2[1];
203     res[0] = v11 * v2[2] - v1[2] * v21 ;
204     res[1] = v1[2] * v20 - v10 * v2[2] ;
205     res[2] = v10 * v21 - v11 * v20 ;
206 }
207 /*----------------------------------------------------------------------------*/
208 void vectSubstract3D(const double v1[3] , const double v2[3], double res[3])
209 {
210     res[0] = v1[0] - v2[0];
211     res[1] = v1[1] - v2[1];
212     res[2] = v1[2] - v2[2];
213 }
214 /*----------------------------------------------------------------------------*/
215 void vectAdd3D(const double v1[3], const double v2[3], double res[3])
216 {
217     res[0] = v1[0] + v2[0];
218     res[1] = v1[1] + v2[1];
219     res[2] = v1[2] + v2[2];
220 }
221 /*----------------------------------------------------------------------------*/
222 void scalarMult3D(const double v[3], double scalar, double res[3])
223 {
224     res[0] = scalar * v[0];
225     res[1] = scalar * v[1];
226     res[2] = scalar * v[2];
227 }
228 /*----------------------------------------------------------------------------*/
229 void normalize3D( double vect[3] )
230 {
231     double norm = NORM_3D(vect) ;
232     vect[0] /= norm ;
233     vect[1] /= norm ;
234     vect[2] /= norm ;
235 }
236 /*----------------------------------------------------------------------------*/
237 void setToIdentity(double mat4D[4][4])
238 {
239     int i = 0;
240     int j = 0;
241     for (i = 0; i < 4; i++)
242     {
243         for (j = 0; j < 4; j++)
244         {
245             mat4D[i][j] = 0.0;
246         }
247         mat4D[i][i] = 1.0;
248     }
249 }
250 /*----------------------------------------------------------------------------*/
251 void mat4DMult(const double mat4D[4][4], const double vect3D[3], double res[3])
252 {
253     int i = 0;
254     double res4D[4];
255     // w coordinate of the vector is supposed to be 1;
256     for (i = 0; i < 4; i++)
257     {
258         res4D[i]  =  vect3D[0] * mat4D[i][0] + vect3D[1] * mat4D[i][1]
259                      + vect3D[2] * mat4D[i][2] + mat4D[i][3];
260     }
261     res[0] = res4D[0] / res4D[3];
262     res[1] = res4D[1] / res4D[3];
263     res[2] = res4D[2] / res4D[3];
264 }
265 /*----------------------------------------------------------------------------*/