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: s1235.c,v 1.3 2001-03-19 15:58:42 afr Exp $
45 *
46 */
47
48
49 #define S1235
50
51 #include "sislP.h"
52
53 #if defined(SISLNEEDPROTOTYPES)
54 void
s1235(double et[],int in,int ik,int * jnbreak,double ** gbreak,int * jstat)55 s1235(double et[],int in,int ik,int *jnbreak,double **gbreak,int *jstat)
56 #else
57 void s1235(et,in,ik,jnbreak,gbreak,jstat)
58 double et[];
59 int in;
60 int ik;
61 int *jnbreak;
62 double **gbreak;
63 int *jstat;
64 #endif
65 /*
66 *********************************************************************
67 *
68 *********************************************************************
69 *
70 * PURPOSE : Find break points in a knot vector. The first and last
71 * parameter values are break values.
72 *
73 *
74 *
75 * INPUT : et - Knot vector to find break points in.
76 * in - Number of vertices of the curve corresponding
77 * to the knot vector.
78 * ik - Order of the curve corresponding to et.
79 *
80 *
81 *
82 * OUTPUT : jnbreak - Number of break points found.
83 * gbreak - Array containing parameter values of break points.
84 * jstat - status messages
85 * > 0 : warning
86 * = 0 : ok
87 * < 0 : error
88 *
89 *
90 * METHOD : The knot vector has a break point at a knot if the
91 * multiplicity of the knot is ik-1.
92 *
93 *
94 * REFERENCES :
95 *
96 *-
97 * CALLS :
98 *
99 * WRITTEN BY : Vibeke Skytt, SI, 88-11.
100 * REVISED BY : Vibeke Skytt, SINTEF, 9801. Correction in loop counter
101 * for the periodic case.
102 *
103 *********************************************************************
104 */
105 {
106 int kpos = 0; /* Position of error. */
107 int kj; /* Counter. */
108 int kbreak; /* Current number of break points found. */
109 int kmult; /* Multiplisity of current knot. */
110 double tprev; /* Value of previous knot. */
111 double *sbreak; /* Pointer into break point array. */
112 double *st; /* Pointer into knot vector. */
113
114 /* Allocate space for an array that is at least as great as the
115 number of break points. */
116
117 *gbreak = SISL_NULL;
118 if ((*gbreak = newarray(in+2,double)) == SISL_NULL) goto err101;
119
120 /* Set local pointer to and counter of break points. */
121
122 sbreak = *gbreak;
123 kbreak = 0;
124
125 /* Find break point in start of parameter interval and internal breaks. */
126
127 tprev = et[ik-1];
128 kmult = ik - 1;
129 for (st=et+ik,kj=ik; kj<in; st++,kj++)
130 {
131
132 if (*st == tprev) kmult++;
133 else
134 {
135 if (kmult >= ik-1)
136 {
137
138 /* New break point found. */
139
140 *(sbreak++) = tprev;
141 kbreak++;
142 }
143 tprev = *st;
144 kmult = 1;
145 }
146 }
147
148 /* Find break point in end of interval. */
149
150 if (et[in] != tprev && kmult >= ik-1)
151 {
152
153 /* Remember last internal break point. */
154
155 *(sbreak++) = tprev;
156 kbreak++;
157 }
158 *(sbreak++) = et[in];
159 kbreak++;
160
161 /* Reduce break point array to correct size. */
162
163 if (kbreak < in+2)
164 if ((*gbreak = increasearray(*gbreak,kbreak,double)) == SISL_NULL) goto err101;
165
166 /* Break points found. */
167
168 *jnbreak = kbreak;
169 *jstat = 0;
170 goto out;
171
172 /* Error in space allocation. */
173
174 err101:
175 *jstat = -101;
176 s6err("s1235",*jstat,kpos);
177 goto out;
178
179 out:
180 return;
181 }
182