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: s1011.c,v 1.3 2001-03-19 15:58:40 afr Exp $
45 *
46 */
47
48
49 #define S1011
50
51 #include "sislP.h"
52
53 #if defined(SISLNEEDPROTOTYPES)
54 void
s1011(double start_pos[],double top_pos[],double end_pos[],double shape,int dim,SISLCurve ** arc_seg,int * stat)55 s1011(double start_pos[], double top_pos[], double end_pos[],
56 double shape, int dim, SISLCurve **arc_seg, int *stat)
57 #else
58 void s1011(start_pos, top_pos, end_pos, shape, dim, arc_seg, stat)
59 double start_pos[];
60 double top_pos[];
61 double end_pos[];
62 double shape;
63 int dim;
64 SISLCurve **arc_seg;
65 int *stat;
66 #endif
67 /*
68 *********************************************************************
69 *
70 * PURPOSE : To describe a conic arc as a NURBS. The arc is given by
71 * position at start, shoulder point and end, and a shape factor.
72 *
73 *
74 * INPUT : start_pos - Start point of segment
75 * top_pos - Shoulder point of segment. This is the intersection
76 * point of the tangents in start_pos and end_pos
77 * end_pos - End point of segment
78 * shape - Shape factor >= 0
79 * shape < 0.5 a ellipse
80 * shape = 0.5 a parabola
81 * shape > 0.5 a hyperbola
82 * shape >= 1 The start and end point lies on
83 * different branches of the hyperbola.
84 * We want a single arc segment, therefore
85 * if shape>=1, shape is put to 0.999999.
86 * dim - The dimension of the curve to be produced
87 *
88 *
89 *
90 *
91 * OUTPUT :
92 * stat - status messages
93 * > 0 : warning
94 * = 0 : ok
95 * < 0 : error
96 * arc_seg - Pointer to the curve produced
97 *
98 * METHOD : The conic is made as a rational B-spline curve according
99 * to the following formula:
100 *
101 * p0 (1-t)(1-t) + 2 s/(1-s) t(1-t) pt + tt p1
102 * p(t) = -------------------------------------------
103 * (1-t)(1-t) + 2 s/(1-s) t(1-t) + tt
104 *
105 * where p0 is the start point, pt is the shoulder point, p1 is
106 * the end point and s is the shape factor.
107 *
108 *
109 * REFERENCES :
110 *
111 *-
112 * CALLS :
113 *
114 * WRITTEN BY : Johannes Kaasa, SI, Oslo, Norway, Jan. 93 (Based on s1385,
115 * written by Tor Dokken)
116 * Revised by : Paal Fugelli, SINTEF, Oslo, Norway, Nov. 1994. Give error if
117 * shape < zero.
118 *********************************************************************
119 */
120 {
121 int kpos = 0; /* Error position. */
122 int ki; /* Index in for loop. */
123 int in = 3; /* Number of coefficients. */
124 int ik = 3; /* Order of the curve. */
125 int rdim = dim + 1; /* Rational dimension. */
126 double et[6]; /* Knot vector. */
127 double rcoef[12]; /* Rational coefficients. */
128 int kind = 4; /* Rational Bezier curve. */
129 double weight; /* Rational weight. */
130
131
132 /* Make sure we get a single arc segment and positive weights. */
133
134 if ( shape >= (DOUBLE)1.0 ) shape = (DOUBLE)0.9999999;
135 else if ( shape < (DOUBLE)0.0 ) goto err151;
136
137
138 /* Make the data needed for curve generation. */
139
140 for ( ki=0; ki < ik; ki++ )
141 {
142 et[ki] = DZERO;
143 et[ik + ki] = (DOUBLE)1.0;
144 }
145
146 weight = shape/((DOUBLE)1.0 - shape);
147
148 for ( ki=0; ki < dim; ki++ )
149 {
150 rcoef[ki] = start_pos[ki];
151 rcoef[rdim + ki] = weight*top_pos[ki];
152 rcoef[2*rdim + ki] = end_pos[ki];
153 }
154 rcoef[dim] = (DOUBLE)1.0;
155 rcoef[dim + rdim] = weight;
156 rcoef[dim + 2*rdim] = (DOUBLE)1.0;
157
158 (*arc_seg) = newCurve(in, ik, et, rcoef, kind, dim, 1);
159 if ((*arc_seg) == SISL_NULL) goto err101;
160
161 *stat = 0;
162 goto out;
163
164
165 /* Error in curve allocation. */
166
167 err101:
168 *stat = -101;
169 s6err("s1011", *stat, kpos);
170 goto out;
171
172
173 /* Error in input parameters - shape is negative. */
174
175 err151:
176 *stat = -151;
177 s6err("s1011", *stat, kpos);
178 goto out;
179
180 out:
181 return;
182 }
183