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