1 /*
2  * Copyright (C) 1998, 2000-2007, 2010, 2011, 2012, 2013 SINTEF ICT,
3  * Applied Mathematics, Norway.
4  *
5  * Contact information: E-mail: tor.dokken@sintef.no
6  * SINTEF ICT, Department of Applied Mathematics,
7  * P.O. Box 124 Blindern,
8  * 0314 Oslo, Norway.
9  *
10  * This file is part of SISL.
11  *
12  * SISL is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Affero General Public License as
14  * published by the Free Software Foundation, either version 3 of the
15  * License, or (at your option) any later version.
16  *
17  * SISL is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Affero General Public License for more details.
21  *
22  * You should have received a copy of the GNU Affero General Public
23  * License along with SISL. If not, see
24  * <http://www.gnu.org/licenses/>.
25  *
26  * In accordance with Section 7(b) of the GNU Affero General Public
27  * License, a covered work must retain the producer line in every data
28  * file that is created or manipulated using SISL.
29  *
30  * Other Usage
31  * You can be released from the requirements of the license by purchasing
32  * a commercial license. Buying such a license is mandatory as soon as you
33  * develop commercial activities involving the SISL library without
34  * disclosing the source code of your own applications.
35  *
36  * This file may be used in accordance with the terms contained in a
37  * written agreement between you and SINTEF ICT.
38  */
39 
40 #include "sisl-copyright.h"
41 
42 /*
43  *
44  * $Id: s2500.c,v 1.8 2001-03-19 15:58:59 afr Exp $
45  *
46  */
47 
48 
49 #define S2500
50 
51 #include "sislP.h"
52 
53 #if defined(SISLNEEDPROTOTYPES)
54 void
s2500(SISLSurf * surf,int ider,int iside1,int iside2,double parvalue[],int * leftknot1,int * leftknot2,double * gaussian,int * jstat)55 s2500(SISLSurf *surf, int ider, int iside1, int iside2, double parvalue[],
56       int *leftknot1,int *leftknot2, double *gaussian, int *jstat)
57 #else
58  void s2500(surf, ider, iside1, iside2, parvalue, leftknot1, leftknot2, gaussian, jstat)
59       SISLSurf *surf;
60       int    ider;
61       int    iside1;
62       int    iside2;
63       double parvalue[];
64       int *leftknot1;
65       int *leftknot2;
66       double *gaussian;
67       int *jstat;
68 #endif
69 /*
70 ***************************************************************************
71 *
72 ***************************************************************************
73 *  PURPOSE      :  To compute the Gaussian K(u,v) of a Surface for given
74 *                  values (u,v) = (parvalue[0],parvalue[1]), where:
75 *
76 *                          et1[leftknot1] <= parvalue[0] < et1[leftknot1+1],
77 *                          et2[leftknot2] <= parvalue[1] < et2[leftknot2+1].
78 *                  See also s2501().
79 *
80 *  INPUT        :
81 *          surf     - Pointer to the surface to evaluate.
82 *          ider     - Number of derivatives to calculate.
83 *                     Only implemented for ider=0.
84 *                       < 0 : No derivative calculated.
85 *                       = 0 : Position calculated.
86 *                       = 1 : Position and first derivative calculated.
87 *                       etc.
88 *          iside1   - Indicator telling if the derivatives in the first
89 *                     parameter direction is to be calculated from the
90 *                     left or from the right:
91 *                        <  0 calculate derivative from the left hand side
92 *                        >= 0 calculate derivative from the right hand side.
93 *          iside2   - Indicator telling if the derivatives in the second
94 *                     parameter direction is to be calculated from the
95 *                     left or from the right:
96 *                        <  0 calculate derivative from the left hand side
97 *                        >= 0 calculate derivative from the right hand side.
98 *      parvalue     - Parameter-value at which to evaluate. Dimension of
99 *                     parvalue is 2.
100 *
101 *  INPUT/OUTPUT :
102 *     leftknot1     - Pointer to the interval in the knot vector in the
103 *                     first parameter direction where parvalue[0] is found,
104 *                     that is:
105 *                          et1[leftknot1] <= parvalue[0] < et1[leftknot1+1].
106 *                     leftknot1 should be set equal to zero at the first call
107 *                     to the routine.
108 *
109 *     leftknot2     - Pointer to the interval in the knot vector in the
110 *                     second parameter direction where parvalue[1] is found,
111 *                     that is:
112 *                          et2[leftknot2] <= parvalue[1] < et2[leftknot2+1].
113 *                     leftknot2 should be set equal to zero at the first call
114 *                     to the routine.
115 *
116 *  OUTPUT       :
117 *     gaussian      - Gaussian of the surface in (u,v) =
118 *                     (parvalue[0],parvalue[1]).
119 *        jstat      - Status messages
120 *                         = 2 : Surface is degenerate at the point, that is,
121 *                               the surface is not regular at this point.
122 *                         = 1 : Surface is close to degenerate at the point.
123 *                               Angle between tangents is less than the angular
124 *                               tolerance.
125 *                         = 0 : Ok.
126 *                         < 0 : Error.
127 *
128 *  METHOD       :  The Gaussian is given by
129 *
130 *                      K(x,y) = (hxx*hyy-hxy^2)/((1+hx^2+hy^2)^2),
131 *
132 *                  if the surface (h(x,y)) is 1D, and
133 *
134 *                      K(u,v) = (eg-f*f)/(EG-F*F),
135 *
136 *                  if the surface (X(u,v)) is 3D. The variables E,F,G,e,f and g
137 *                  are the coefficients of the first and second fundamental form.
138 *                  They are given by: e = <N,Xuu>, f = <N,Xuv>, g = <N,Xvv>,
139 *                  E = <Xu,Xu>, F = <Xu,Xv> and G = <Xv,Xv>. The routine will
140 *                  test if the surface is degenerate (not regular) or close to
141 *                  degenerate. Call s2501().
142 *
143 *  REFERENCES   :  Differential Geometry of Curves and Surfaces,
144 *                    (Manfredo P. Do Carmo, Prentice Hall,
145 *                      ISBN: 0-13-212589-7).
146 *-
147 *  CALLS        :  s1422() and s2501().
148 *
149 *  LIMITATIONS  :
150 *                (i) If the surface is degenerated (not regular) at the point
151 *                    (u,v), it makes no sense to speak about the Gaussian
152 *                    K(u,v). The routine returns jstat = 2.
153 *               (ii) If the surface is closed to degenerate, the Gaussian
154 *                    K(u,v) can be numerical instable. The routine returns
155 *                    jstat = 1.
156 *              (iii) If the surface is Cr the curvature calculated is C(r-2).
157 *               (iv) The dimension of the space in which the surface lies must
158 *                    be 1,2 or 3.
159 *
160 *
161 * WRITTEN BY :    Geir Westgaard, SINTEF, Oslo, Norway.            Date: 1995-1
162 * CORRECTED BY :  Ulf J Krystad, SINTEF, Oslo, Norway.             Date: 1995-1
163 *                 Added ider, iside1 and iside2 parameters.
164 ******************************************************************************
165 */
166 {
167   int kwarn = 0;      /* Local staus variable(warning).                  */
168   int kistat = 0;        /* Local staus variable.                           */
169   double derive[18];     /* Array containing the computed derivatives.      */
170   double normal[3];      /* Array containing the computed normalvektor.     */
171 
172 
173   if (ider != 0) goto err178;
174 
175 
176   if (surf == SISL_NULL)  goto err150;
177   else
178   {
179     /* Compute derivates and normal. */
180 
181     s1422(surf,2,iside1,iside2,parvalue,leftknot1,leftknot2,derive,normal,&kistat);
182     if (kistat > 0) kwarn=kistat;
183 
184     if (kistat < 0) /* Error in lower level routine. */
185     {
186       goto error;
187     }
188     else if (kistat != 2) /* The surface is not degenerate */
189     {
190       s2501(surf, ider, derive, normal, gaussian, &kistat);
191 
192       if (kistat < 0)
193 	goto error;
194     }
195     else if (kistat == 2) /* The surface is degenerated. */
196     {
197       *gaussian = 0.0;
198       goto war002;
199     }
200 
201   }
202 
203 
204   /* Successful computations  */
205 
206   *jstat = kwarn;
207   goto out;
208 
209 
210    /* The surface is degenerated at (u,v) */
211 war002:
212   *jstat = 2;
213   goto out;
214 
215   /* Error. Input (surface) pointer is SISL_NULL. */
216 err150:
217   *jstat = -150;
218   s6err("s2500", *jstat, 0);
219   goto out;
220 
221   /* Illegal derivative requested. */
222 err178:
223   *jstat = -178;
224   s6err("s2500",*jstat,0);
225   goto out;
226   /* Error in lower level routine.  */
227 
228 error:
229   *jstat = kistat;
230   s6err("s2500",*jstat,0);
231   goto out;
232 
233 
234 out:
235 
236   return;
237 
238 }
239