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: s1614.c,v 1.2 1994-12-07 12:05:37 pfu Exp $
45  *
46  */
47 
48 
49 #define S1614
50 
51 #include "sislP.h"
52 
53 #if defined(SISLNEEDPROTOTYPES)
s1614(double epoint[],int inbpnt,int idim,int eptyp[],double spoint[],int * jnbpnt,int sptyp[],int * jstat)54 void s1614(double epoint[], int inbpnt, int idim, int eptyp[],
55 	   double spoint[], int *jnbpnt, int sptyp[], int *jstat)
56 
57 #else
58 void s1614(epoint, inbpnt, idim, eptyp,spoint, jnbpnt, sptyp, jstat)
59      double epoint[];
60      int    inbpnt;
61      int    idim;
62      int    eptyp[];
63      double spoint[];
64      int    *jnbpnt;
65      int    sptyp[];
66      int    *jstat;
67 #endif
68 /*
69 *************************************************************************
70 *
71 * PURPOSE: To check the point description vector to ensure that the
72 *          points returned from this routine can be used directly in the
73 *          conversion of conics to B-spline representation.
74 *
75 * INPUT:
76 *        Epoint - The points/tangents describing the conic.
77 *        Inbpnt - No. of points/tangents in the epoint array.
78 *        Idim   - The dimension of the space in which the points lie.
79 *        Eptyp  - Type indicator for points/tangents :
80 *                  1 - Ordinary point.
81 *                  2 - Knuckle point. (Is treated as an ordinary point.)
82 *                  3 - Tangent to next point.
83 *                  4 - Tangent to prior point.
84 *
85 * Output:
86 
87 *        Spoint - The corrected points.
88 *        Jnbpnt - No. of corrected points.
89 *        Sptyp  - Type indicator for corrected points.
90 *        Jstat  - status messages:
91 *                  < 0 : Error.
92 *                  = 0 : Ok.
93 *                  > 0 : Warning.
94 *
95 * Method:
96 * 	The point description is run through, to check if some points are
97 *	 assigned two tangents. If two tangents are detected, the first is
98 * 	used and the second discarded. In addition, the first points
99 * 	interpolation-condition detected is put in the start of the output
100 * 	array, and the last points interpolation-condition is put in the end
101 * 	of the output array.
102 *-
103 * Calls: s6err.
104 *
105 * Written by: A.M. Ytrehus, SI  Oslo Oct.91.
106 * After FORTRAN (P1614) written by: T. Dokken  SI.
107 * Revised by: J. Kaasa, SI, Aug. 92 (Fixed bugs in connection with
108 *             type handling).
109 *****************************************************************
110 */
111 {
112   int ki, kp, kk, kki;
113   int khelp;
114   int ktell = 0;
115   int kflag = 0;
116   int knbpnt = 0;
117   int ktyp = 1;
118   int ktypm1;
119   double tdum;
120   int kpos = 0;
121 
122   *jstat = 0;
123 
124 
125   /* Run through and test the type of the data points. Copy
126      approved points and tangents into output variables. */
127 
128   for (ki = 0; ki < inbpnt; ki++)
129     {
130       ktypm1 = ktyp;
131       ktyp = eptyp[ki];
132 
133       if (!((ktyp < 1 || ktyp > 4) ||
134 	    (knbpnt == 0 && ktyp == 4) ||
135 	    (ktyp == 3 && ktypm1 == 3) ||
136 	    (ktyp == 4 && ktypm1 == 4) ||
137 	    (ktyp == 4 && ktypm1 == 3)))
138 	{
139 	  /* Save this point or tangent in spoint and sptyp. */
140 
141 	  sptyp[knbpnt] = ktyp;
142 
143 	  kki = idim * ki;
144 	  kk = idim * knbpnt;
145 
146 	  for (kp = 0; kp < idim; kp++)
147 	    spoint[kk + kp] = epoint[kki + kp];
148 	  knbpnt++;
149 	}
150     }
151 
152   /* Remove last point if the type is 3 (which means tangent to next point. */
153 
154   if (ktyp == 3)
155     knbpnt--;
156 
157 
158   /* We cannot make use of more than five points.
159      Choose the first five points. */
160 
161   if (knbpnt > 5)
162     {
163       knbpnt = 5;
164 
165       /* Check the type of (new) last point. */
166 
167       if (sptyp[knbpnt - 1] == 3)
168 	{
169 	  /* Cut out this point, and use point no. 6 instead. */
170 
171 	  sptyp[knbpnt - 1] = sptyp[knbpnt];
172 
173 	  kk = idim * (knbpnt - 1);
174 
175 	  for (kp = 0; kp < idim; kp++)
176 	    spoint[kk + kp] = spoint[kk + idim + kp];
177 	}
178     }
179 
180 
181   /* Ensure that first entry is a point. */
182 
183   ktyp = sptyp[0];
184 
185   if (ktyp > 2)
186     {
187       /* Interchange the two first conditions. */
188 
189       kflag = 1;
190 
191       sptyp[0] = 1;
192       sptyp[1] = 4;
193 
194       for (kp = 0; kp < idim; kp++)
195 	{
196 	  tdum = spoint[kp];
197 	  spoint[kp] = spoint[kp + idim];
198 	  spoint[kp + idim] = tdum;
199 	}
200     }
201 
202   /* Ensure that last entry is a point. */
203 
204   ktyp = sptyp[knbpnt - 1];
205 
206   if (ktyp > 2)
207     {
208 
209       /* Interchange the two last conditions. */
210 
211       kflag = 1;
212 
213       sptyp[knbpnt - 1] = 1;
214       sptyp[knbpnt - 2] = 3;
215 
216       kk = idim * (knbpnt - 1);
217 
218       for (kp = 0; kp < idim; kp++)
219 	{
220 	  tdum = spoint[kk + kp];
221 	  spoint[kk + kp] = spoint[kk - idim + kp];
222 	  spoint[kk - idim + kp] = tdum;
223 	}
224     }
225 
226   /* Count no. of points. If less than two, we cannot even
227      create a straight line. */
228 
229   for (ki = 0; ki < knbpnt; ki++)
230     {
231       ktyp = sptyp[ki];
232       if (ktyp < 3)
233 	ktell++;
234     }
235 
236   if (ktell <= 1)
237     goto err181;
238 
239 
240   /* Run through and remove double tangents that may be introduced by
241      the interchange of end-point/end-tangents. */
242 
243   ktyp = 1;
244 
245   if (kflag == 1)
246     {
247       khelp = knbpnt;
248 
249       ktypm1 = ktyp;
250 
251       for (ki = 0; ki < khelp; ki++)
252 	{
253 	  ktyp = sptyp[ki];
254 
255 	  if ((ktyp == 3 && ktypm1 == 3) ||
256 	      (ktyp == 4 && ktypm1 == 4) ||
257 	      (ktyp == 4 && ktypm1 == 3))
258 	    {
259 	      /* Remove last of doble tangent. */
260 
261 	      knbpnt--;
262 
263 	      for (kk = ki; kk < knbpnt; kk++)
264 		{
265 		  sptyp[kk] = sptyp[kk + 1];
266 
267 		  kki = idim * kk;
268 
269 		  for (kp = 0; kp < idim; kp++)
270 		    spoint[kki + kp] = spoint[kki + idim + kp];
271 		}
272 	    }
273 	}
274     }
275 
276 
277   *jnbpnt = knbpnt;
278 
279   goto out;
280 
281 
282   /* Error in input, less than two points given in problem formulation. */
283 
284 err181:
285   *jstat = -181;
286   s6err ("s1614", *jstat, kpos);
287   goto out;
288 
289 out:
290 
291   return;
292 }
293