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