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: s1422.c,v 1.2 2001-03-19 15:58:49 afr Exp $ 45 * 46 */ 47 48 49 #define S1422 50 51 #include "sislP.h" 52 53 #if defined(SISLNEEDPROTOTYPES) 54 void s1422(SISLSurf * ps1,int ider,int iside1,int iside2,double epar[],int * ilfs,int * ilft,double eder[],double enorm[],int * jstat)55 s1422(SISLSurf *ps1,int ider,int iside1,int iside2,double epar[],int *ilfs, 56 int *ilft,double eder[],double enorm[],int *jstat) 57 #else 58 void s1422(ps1,ider,iside1,iside2,epar,ilfs,ilft,eder,enorm,jstat) 59 SISLSurf *ps1; 60 int ider; 61 int iside1; 62 int iside2; 63 double epar[]; 64 int *ilfs; 65 int *ilft; 66 double eder[]; 67 double enorm[]; 68 int *jstat; 69 #endif 70 /* 71 ********************************************************************* 72 * 73 ********************************************************************* 74 * 75 * PURPOSE : Evaluate the surface pointed at by ps1 at the parameter 76 * value epar. Compute ider derivatives from the right hand 77 * or the left hand sides. 78 * 79 * 80 * 81 * INPUT : ps1 - Pointer to the surface to evaluate. 82 * ider - Number of derivatives to calculate. 83 * < 0 : No derivative calculated. 84 * = 0 : Position calculated. 85 * = 1 : Position and first derivative calculated. 86 * etc. 87 * iside1 - Indicator telling if the derivatives in the first 88 * parameter direction is to be calculated from the 89 * left or from the right: 90 * < 0 calculate derivative from the left hand side 91 * >= 0 calculate derivative from the right hand side. 92 * iside2 - Indicator telling if the derivatives in the second 93 * parameter direction is to be calculated from the 94 * left or from the right: 95 * < 0 calculate derivative from the left hand side 96 * >= 0 calculate derivative from the right hand side. 97 * epar - Parameter-value at which to calculate. Dimension 98 * of epar is 2. 99 * 100 * 101 * 102 * INPUT/OUTPUT : ilfs - Pointer to the interval in the knotvector 103 * in first parameter direction where epar[0] 104 * is found. The relation 105 * 106 * et1[ilfs] <= epar[0] < et1[ilfs+1] 107 * 108 * where et1 is the knotvektor should hold. 109 * ilfs is set equal to zero at the first call 110 * to the routine. 111 * ilft - Corresponding to ilfs in the second parameter 112 * direction. 113 * 114 * 115 * 116 * 117 * OUTPUT : eder - Array where the derivative of the curve in 118 * apar is placed. The sequence is position, 119 * first derivative in first parameter direction, 120 * first derivative in second parameter direction, 121 * (2,0) derivative, (1,1) derivative, (0,2) 122 * derivative, etc. Dimension of eder is 123 * idim*(1+2+...+(ider+1)). 124 * enorm - Normal of surface. Is calculated if ider >= 1. 125 * Dimension is idim. The normal is not normalized. 126 * jstat - status messages 127 * = 2 : Surface is degenerate 128 * at the point, normal 129 * has zero length 130 * = 1 : Surface is close to 131 * degenerate at the point 132 * Angle between tangents, 133 * less than angular tolerance 134 * = 0 : ok 135 * < 0 : error 136 * 137 * 138 * METHOD : 139 * 140 * REFERENCES : 141 * 142 *- 143 * CALLS : 144 * 145 * WRITTEN BY : 146 * 147 ********************************************************************* 148 */ 149 { 150 int kstat=0; /* Local status variable. */ 151 int kpos=0; /* Position of error. */ 152 int kdim; /* Dimension of the space in which the surface lies. */ 153 int keder; /* Integer used in address calculations on eder */ 154 int ksp; /* Integer used in address calculations on sp */ 155 int kincre; /* Increment for address calculations */ 156 int ki,kl; /* Control variables in for loop */ 157 int knumb; /* Number of elements used for storage of deriv.s */ 158 double *sp; /* Pointer to temporary array */ 159 double sdum[48]; /* Array used in stead of allocation */ 160 161 162 /* Allocate array for storage of ider*ider derivatives */ 163 164 sp = SISL_NULL; 165 kdim = ps1 -> idim; 166 knumb = kdim*(ider+1)*(ider+1); 167 168 /* Only allocate space if sdum is too smaall */ 169 170 if (knumb>48) 171 sp = newarray(knumb,DOUBLE); 172 else 173 sp = &sdum[0]; 174 175 if (sp == SISL_NULL) goto err101; 176 177 178 /* Evaluate s1422surface. */ 179 180 s1425(ps1,ider,ider,iside1,iside2,epar,ilfs,ilft,sp,&kstat); 181 182 if (kstat < 0) goto error; 183 184 /* Copy required derivatives into eder */ 185 186 kincre = kdim*ider; 187 188 /* Copy all derivatives of order 0, then of order 1, up to order ider */ 189 190 for (kl=0,keder=0;kl<=ider;kl++) 191 { 192 for (ki=0,ksp=kl*kdim ; ki<=kl ; ki++,ksp+=kincre,keder+=kdim) 193 { 194 memcopy(eder+keder,sp+ksp,kdim,DOUBLE); 195 } 196 } 197 198 /* Make cross products of tangents, if idim==3 and derivative >0 */ 199 200 if (ider>0 && kdim ==3) 201 { 202 double tlen1,tlen2,tnorm,tang=(double)0.0; 203 204 s6crss(eder+kdim,eder+2*kdim,enorm); 205 206 /* Make length of tangents and normal */ 207 208 tlen1 = s6length(eder+kdim,kdim,&kstat); 209 tlen2 = s6length(eder+2*kdim,kdim,&kstat); 210 tnorm = s6length(enorm,kdim,&kstat); 211 212 /* Calculate angle between tangents */ 213 214 if (tlen1 != DZERO && tlen2 != DZERO && tnorm != DZERO) 215 tang = tnorm/(tlen1*tlen2); 216 217 if (tang == DZERO) *jstat = 2; 218 else if (tang <= ANGULAR_TOLERANCE) *jstat = 1; 219 else *jstat = 0; 220 goto out; 221 222 } 223 224 *jstat = 0; 225 goto out; 226 227 /* Error in lower level routine. */ 228 229 error : *jstat = kstat; 230 s6err("s1422",*jstat,kpos); 231 goto out; 232 233 err101: *jstat = -101; 234 s6err("s1422",*jstat,kpos); 235 236 237 out: 238 239 /* Free allocated space (Space only allocated if sdum is too small) */ 240 241 if (knumb>48) 242 if (sp != SISL_NULL) freearray(sp); 243 244 return; 245 } 246 247 248