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