b311480e |
1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
3 | // |
973c2be1 |
4 | // This file is part of Open CASCADE Technology software library. |
b311480e |
5 | // |
d5f74e42 |
6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
10 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
11 | // |
973c2be1 |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
b311480e |
14 | |
7fd59977 |
15 | //JCV 16/10/91 |
16 | |
17 | #define No_Standard_OutOfRange |
18 | |
42cf5bc1 |
19 | |
20 | #include <BSplCLib.hxx> |
21 | #include <Convert_ConicToBSplineCurve.hxx> |
7fd59977 |
22 | #include <Convert_CosAndSinEvalFunction.hxx> |
23 | #include <Convert_PolynomialCosAndSin.hxx> |
42cf5bc1 |
24 | #include <gp.hxx> |
25 | #include <gp_Pnt2d.hxx> |
7fd59977 |
26 | #include <PLib.hxx> |
7fd59977 |
27 | #include <Precision.hxx> |
7fd59977 |
28 | #include <Standard_ConstructionError.hxx> |
42cf5bc1 |
29 | #include <Standard_OutOfRange.hxx> |
30 | #include <TColgp_Array1OfPnt.hxx> |
31 | #include <TColgp_Array1OfPnt2d.hxx> |
32 | #include <TColgp_HArray1OfPnt2d.hxx> |
33 | #include <TColStd_Array1OfInteger.hxx> |
34 | #include <TColStd_Array1OfReal.hxx> |
35 | #include <TColStd_HArray1OfInteger.hxx> |
36 | #include <TColStd_HArray1OfReal.hxx> |
7fd59977 |
37 | |
38 | //======================================================================= |
39 | //function : Convert_ConicToBSplineCurve |
40 | //purpose : |
41 | //======================================================================= |
7fd59977 |
42 | Convert_ConicToBSplineCurve::Convert_ConicToBSplineCurve |
43 | (const Standard_Integer NbPoles, |
44 | const Standard_Integer NbKnots, |
45 | const Standard_Integer Degree ) |
46 | : degree (Degree) , nbPoles (NbPoles) , nbKnots (NbKnots) |
47 | |
48 | { |
49 | if (NbPoles >= 2) { |
50 | poles = new TColgp_HArray1OfPnt2d (1, NbPoles) ; |
51 | |
52 | weights = new TColStd_HArray1OfReal (1, NbPoles) ; |
53 | } |
54 | if (NbKnots >= 2) { |
55 | knots = new TColStd_HArray1OfReal (1, NbKnots) ; |
56 | mults = new TColStd_HArray1OfInteger(1,NbKnots) ; |
57 | } |
58 | } |
59 | |
60 | |
61 | //======================================================================= |
62 | //function : Degree |
63 | //purpose : |
64 | //======================================================================= |
65 | |
66 | Standard_Integer Convert_ConicToBSplineCurve::Degree () const |
67 | { |
68 | return degree; |
69 | } |
70 | |
71 | //======================================================================= |
72 | //function : NbPoles |
73 | //purpose : |
74 | //======================================================================= |
75 | |
76 | Standard_Integer Convert_ConicToBSplineCurve::NbPoles () const |
77 | { |
78 | return nbPoles; |
79 | } |
80 | |
81 | //======================================================================= |
82 | //function : NbKnots |
83 | //purpose : |
84 | //======================================================================= |
85 | |
86 | Standard_Integer Convert_ConicToBSplineCurve::NbKnots () const |
87 | { |
88 | return nbKnots; |
89 | } |
90 | |
91 | //======================================================================= |
92 | //function : IsPeriodic |
93 | //purpose : |
94 | //======================================================================= |
95 | |
96 | Standard_Boolean Convert_ConicToBSplineCurve::IsPeriodic() const |
97 | { |
98 | return isperiodic; |
99 | } |
100 | |
101 | //======================================================================= |
102 | //function : Pole |
103 | //purpose : |
104 | //======================================================================= |
105 | |
106 | gp_Pnt2d Convert_ConicToBSplineCurve::Pole |
107 | (const Standard_Integer Index) const |
108 | { |
109 | if (Index < 1 || Index > nbPoles) |
9775fa61 |
110 | throw Standard_OutOfRange(" "); |
7fd59977 |
111 | return poles->Value (Index); |
112 | } |
113 | |
114 | |
115 | //======================================================================= |
116 | //function : Weight |
117 | //purpose : |
118 | //======================================================================= |
119 | |
120 | Standard_Real Convert_ConicToBSplineCurve::Weight |
121 | (const Standard_Integer Index) const |
122 | { |
123 | if (Index < 1 || Index > nbPoles) |
9775fa61 |
124 | throw Standard_OutOfRange(" "); |
7fd59977 |
125 | return weights->Value (Index); |
126 | } |
127 | |
128 | |
129 | //======================================================================= |
130 | //function : Knot |
131 | //purpose : |
132 | //======================================================================= |
133 | |
134 | Standard_Real Convert_ConicToBSplineCurve::Knot |
135 | (const Standard_Integer Index) const |
136 | { |
137 | if (Index < 1 || Index > nbKnots) |
9775fa61 |
138 | throw Standard_OutOfRange(" "); |
7fd59977 |
139 | return knots->Value (Index); |
140 | } |
141 | |
142 | |
143 | //======================================================================= |
144 | //function : Multiplicity |
145 | //purpose : |
146 | //======================================================================= |
147 | |
148 | Standard_Integer Convert_ConicToBSplineCurve::Multiplicity |
149 | (const Standard_Integer Index) const |
150 | { |
151 | if (Index < 1 || Index > nbKnots) |
9775fa61 |
152 | throw Standard_OutOfRange(" "); |
7fd59977 |
153 | return mults->Value (Index); |
154 | } |
155 | //======================================================================= |
156 | //function : CosAndSinRationalC1 |
157 | //purpose : evaluates U(t) and V(t) such that |
158 | // 2 2 |
159 | // U - V |
160 | // cos (theta(t)) = ---------- |
161 | // 2 2 |
162 | // U + V |
163 | // |
164 | |
165 | // 2 * U*V |
166 | // sin (theta(t)) = ---------- |
167 | // 2 2 |
168 | // U + V |
169 | // 2 2 |
170 | // such that the derivative at the domain bounds of U + V is 0.0e0 |
171 | // with is helpfull when having to make a C1 BSpline by merging two |
172 | // BSpline toghether |
173 | //======================================================================= |
174 | |
175 | void CosAndSinRationalC1(Standard_Real Parameter, |
176 | const Standard_Integer EvalDegree, |
177 | const TColgp_Array1OfPnt2d& EvalPoles, |
178 | const TColStd_Array1OfReal& EvalKnots, |
0e14656b |
179 | const TColStd_Array1OfInteger* EvalMults, |
7fd59977 |
180 | Standard_Real Result[2]) |
181 | { |
182 | gp_Pnt2d a_point ; |
183 | BSplCLib::D0(Parameter, |
184 | 0, |
185 | EvalDegree, |
186 | Standard_False, |
187 | EvalPoles, |
188 | BSplCLib::NoWeights(), |
189 | EvalKnots, |
190 | EvalMults, |
191 | a_point) ; |
192 | Result[0] = a_point.Coord(1) ; |
193 | Result[1] = a_point.Coord(2) ; |
194 | } |
195 | |
196 | |
197 | //======================================================================= |
198 | //function : CosAndSinQuasiAngular |
199 | //purpose : evaluates U(t) and V(t) such that |
200 | // 2 2 |
201 | // U - V |
202 | // cos (theta(t)) = ---------- |
203 | // 2 2 |
204 | // U + V |
205 | // |
206 | |
207 | // 2 * U*V |
208 | // sin (theta(t)) = ---------- |
209 | // 2 2 |
210 | // U + V |
211 | //======================================================================= |
212 | |
213 | void CosAndSinQuasiAngular(Standard_Real Parameter, |
214 | const Standard_Integer EvalDegree, |
215 | const TColgp_Array1OfPnt2d& EvalPoles, |
216 | // const TColStd_Array1OfReal& EvalKnots, |
217 | const TColStd_Array1OfReal& , |
218 | // const TColStd_Array1OfInteger& EvalMults, |
0e14656b |
219 | const TColStd_Array1OfInteger* , |
7fd59977 |
220 | Standard_Real Result[2]) |
221 | { |
222 | Standard_Real |
223 | param, |
224 | *coeff ; |
225 | |
226 | coeff = (Standard_Real *) &EvalPoles(EvalPoles.Lower()) ; |
227 | // |
228 | // rational_function_coeff represent a rational approximation |
229 | // of U ---> cotan( PI * U /2) between [0 1] |
230 | // rational_function_coeff[i][0] is the denominator |
231 | // rational_function_coeff[i][1] is the numerator |
232 | // |
233 | param = Parameter * 0.5e0 ; |
234 | PLib::NoDerivativeEvalPolynomial (param, |
235 | EvalDegree, |
236 | 2, |
237 | EvalDegree << 1, |
238 | coeff[0], |
239 | Result[0]) ; |
240 | } |
241 | |
242 | //======================================================================= |
243 | //function : function that build the Bspline Representation of |
244 | // an algorithmic description of the function cos and sin |
245 | //purpose : |
246 | //======================================================================= |
247 | void AlgorithmicCosAndSin(Standard_Integer Degree, |
248 | const TColStd_Array1OfReal& FlatKnots, |
249 | const Standard_Integer EvalDegree, |
250 | const TColgp_Array1OfPnt2d& EvalPoles, |
251 | const TColStd_Array1OfReal& EvalKnots, |
0e14656b |
252 | const TColStd_Array1OfInteger* EvalMults, |
7fd59977 |
253 | Convert_CosAndSinEvalFunction Evaluator, |
254 | TColStd_Array1OfReal& CosNumerator, |
255 | TColStd_Array1OfReal& SinNumerator, |
256 | TColStd_Array1OfReal& Denominator) |
257 | { |
258 | Standard_Integer order, |
259 | num_poles, |
260 | pivot_index_problem, |
261 | ii; |
262 | |
263 | Standard_Real result[2], |
264 | inverse ; |
265 | |
266 | order = Degree + 1 ; |
267 | num_poles = FlatKnots.Length() - order ; |
268 | |
269 | if (num_poles != CosNumerator.Length() || |
270 | num_poles != SinNumerator.Length() || |
271 | num_poles != Denominator.Length() ) { |
9775fa61 |
272 | throw Standard_ConstructionError(); |
7fd59977 |
273 | } |
274 | TColStd_Array1OfReal parameters(1,num_poles) ; |
275 | TColgp_Array1OfPnt poles_array(1,num_poles) ; |
276 | TColStd_Array1OfInteger contact_order_array(1,num_poles) ; |
277 | BSplCLib::BuildSchoenbergPoints(Degree, |
278 | FlatKnots, |
279 | parameters) ; |
280 | for (ii = parameters.Lower() ; ii <= parameters.Upper() ; ii++) { |
281 | Evaluator(parameters(ii), |
282 | EvalDegree, |
283 | EvalPoles, |
284 | EvalKnots, |
285 | EvalMults, |
286 | result) ; |
287 | contact_order_array(ii) = 0 ; |
288 | |
289 | poles_array(ii).SetCoord(1, |
290 | (result[1]*result[1] - result[0]*result[0])); |
291 | poles_array(ii).SetCoord(2, |
292 | 2.0e0 * result[1]* result[0]) ; |
293 | poles_array(ii).SetCoord(3, |
294 | result[1]*result[1] + result[0] * result[0]) ; |
295 | } |
296 | BSplCLib::Interpolate(Degree, |
297 | FlatKnots, |
298 | parameters, |
299 | contact_order_array, |
300 | poles_array, |
301 | pivot_index_problem) ; |
302 | for (ii = 1 ; ii <= num_poles ; ii++) { |
303 | inverse = 1.0e0 / poles_array(ii).Coord(3) ; |
304 | CosNumerator(ii) = poles_array(ii).Coord(1) * inverse ; |
305 | SinNumerator(ii) = poles_array(ii).Coord(2) * inverse ; |
306 | Denominator(ii) = poles_array(ii).Coord(3) ; |
307 | } |
308 | } |
309 | |
310 | //======================================================================= |
311 | //function : BuildCosAndSin |
312 | //purpose : |
313 | //======================================================================= |
314 | |
315 | void Convert_ConicToBSplineCurve::BuildCosAndSin( |
316 | const Convert_ParameterisationType Parameterisation, |
317 | const Standard_Real UFirst, |
318 | const Standard_Real ULast, |
319 | Handle(TColStd_HArray1OfReal)& CosNumeratorPtr, |
320 | Handle(TColStd_HArray1OfReal)& SinNumeratorPtr, |
321 | Handle(TColStd_HArray1OfReal)& DenominatorPtr, |
322 | Standard_Integer& Degree, |
323 | Handle(TColStd_HArray1OfReal)& KnotsPtr, |
324 | Handle(TColStd_HArray1OfInteger)& MultsPtr) const |
325 | { |
326 | Standard_Real delta = ULast - UFirst, |
327 | direct, |
328 | inverse, |
329 | value1, |
330 | value2, |
331 | cos_beta, |
332 | sin_beta, |
333 | alpha=0, |
334 | alpha_2, |
335 | alpha_4, |
336 | tan_alpha_2, |
337 | beta, |
338 | p_param, |
339 | q_param, |
340 | param ; |
341 | |
1d47d8d0 |
342 | Standard_Integer num_poles = 0, |
7fd59977 |
343 | ii, |
344 | jj, |
1d47d8d0 |
345 | num_knots = 1, |
346 | num_spans = 1, |
7fd59977 |
347 | num_flat_knots, |
348 | num_temp_knots, |
1d47d8d0 |
349 | temp_degree = 0, |
7fd59977 |
350 | tgt_theta_flag, |
351 | num_temp_poles, |
1d47d8d0 |
352 | order = 0; |
7fd59977 |
353 | |
354 | Convert_CosAndSinEvalFunction *EvaluatorPtr=NULL ; |
355 | |
356 | tgt_theta_flag = 0 ; |
357 | |
358 | |
359 | switch (Parameterisation) { |
360 | case Convert_TgtThetaOver2: |
361 | num_spans = |
c6541a0c |
362 | (Standard_Integer)IntegerPart( 1.2 * delta / M_PI) + 1; |
7fd59977 |
363 | |
364 | tgt_theta_flag = 1 ; |
365 | break ; |
366 | case Convert_TgtThetaOver2_1: |
367 | num_spans = 1 ; |
c6541a0c |
368 | if (delta > 0.9999 * M_PI) { |
9775fa61 |
369 | throw Standard_ConstructionError() ; |
7fd59977 |
370 | } |
371 | tgt_theta_flag = 1 ; |
372 | break ; |
373 | case Convert_TgtThetaOver2_2: |
374 | num_spans = 2 ; |
c6541a0c |
375 | if (delta > 1.9999 * M_PI) { |
9775fa61 |
376 | throw Standard_ConstructionError() ; |
7fd59977 |
377 | } |
378 | tgt_theta_flag = 1 ; |
379 | break ; |
380 | |
381 | case Convert_TgtThetaOver2_3: |
382 | num_spans = 3 ; |
383 | tgt_theta_flag = 1 ; |
384 | break ; |
385 | case Convert_TgtThetaOver2_4: |
386 | num_spans = 4 ; |
387 | tgt_theta_flag = 1 ; |
388 | break ; |
389 | case Convert_QuasiAngular: |
390 | num_poles = 7 ; |
391 | Degree = 6 ; |
392 | num_spans = 1 ; |
393 | num_knots = 2 ; |
394 | order = Degree + 1 ; |
395 | break ; |
396 | case Convert_RationalC1: |
397 | Degree = 4 ; |
398 | order = Degree + 1 ; |
399 | num_poles = 8 ; |
400 | num_knots = 3 ; |
401 | num_spans = 2 ; |
402 | break ; |
403 | case Convert_Polynomial: |
404 | Degree = 7 ; |
405 | num_poles = 8 ; |
406 | num_knots = 2 ; |
407 | num_spans = 1 ; |
408 | break ; |
409 | default: |
410 | break ; |
411 | } |
412 | if (tgt_theta_flag) { |
413 | alpha = delta / ( 2.0e0 * num_spans) ; |
414 | Degree = 2 ; |
415 | num_poles = 2 * num_spans + 1; |
416 | } |
417 | |
418 | CosNumeratorPtr = |
419 | new TColStd_HArray1OfReal(1,num_poles) ; |
420 | SinNumeratorPtr = |
421 | new TColStd_HArray1OfReal(1,num_poles) ; |
422 | DenominatorPtr = |
423 | new TColStd_HArray1OfReal(1,num_poles) ; |
424 | KnotsPtr = |
425 | new TColStd_HArray1OfReal(1,num_spans+1) ; |
426 | MultsPtr = |
427 | new TColStd_HArray1OfInteger(1,num_spans+1) ; |
428 | if (tgt_theta_flag) { |
429 | |
430 | param = UFirst ; |
431 | CosNumeratorPtr->SetValue(1,Cos(UFirst)) ; |
432 | SinNumeratorPtr->SetValue(1,Sin(UFirst)) ; |
433 | DenominatorPtr ->SetValue(1,1.0e0) ; |
434 | KnotsPtr->SetValue(1,param) ; |
435 | MultsPtr->SetValue(1,Degree + 1) ; |
436 | direct = Cos(alpha) ; |
437 | inverse = 1.0e0 / direct ; |
438 | for (ii = 1 ; ii <= num_spans ; ii++ ) { |
439 | CosNumeratorPtr->SetValue(2 * ii, inverse * Cos(param + alpha)) ; |
440 | SinNumeratorPtr->SetValue(2 * ii, inverse * Sin(param + alpha)) ; |
441 | DenominatorPtr->SetValue(2 * ii, direct) ; |
442 | CosNumeratorPtr->SetValue(2 * ii + 1, Cos(param + 2 * alpha)) ; |
443 | SinNumeratorPtr->SetValue(2 * ii + 1, Sin(param + 2 * alpha)) ; |
444 | DenominatorPtr->SetValue(2 * ii + 1, 1.0e0) ; |
445 | KnotsPtr->SetValue(ii + 1, param + 2 * alpha) ; |
446 | MultsPtr->SetValue(ii + 1, 2) ; |
447 | param += 2 * alpha ; |
448 | } |
449 | MultsPtr->SetValue(num_spans + 1, Degree + 1) ; |
450 | } |
451 | else if (Parameterisation != Convert_Polynomial) { |
452 | alpha = ULast - UFirst ; |
453 | alpha *= 0.5e0 ; |
454 | beta = ULast + UFirst ; |
455 | beta *= 0.5e0 ; |
456 | cos_beta = Cos(beta) ; |
457 | sin_beta = Sin(beta) ; |
458 | num_flat_knots = num_poles + order ; |
459 | |
460 | num_temp_poles = 4 ; |
461 | num_temp_knots = 3 ; |
462 | TColStd_Array1OfReal flat_knots(1, num_flat_knots) ; |
463 | |
464 | |
465 | TColgp_Array1OfPnt2d temp_poles(1,num_temp_poles) ; |
466 | TColStd_Array1OfReal temp_knots(1,num_temp_knots) ; |
467 | TColStd_Array1OfInteger temp_mults(1,num_temp_knots) ; |
468 | |
469 | for (ii = 1 ; ii <= order ; ii++) { |
470 | flat_knots(ii) = -alpha ; |
471 | flat_knots(ii + num_poles) = alpha ; |
472 | } |
473 | KnotsPtr->SetValue(1,UFirst) ; |
474 | KnotsPtr->SetValue(num_knots, ULast) ; |
475 | MultsPtr->SetValue(1,order) ; |
476 | MultsPtr->SetValue(num_knots,order) ; |
477 | |
478 | switch (Parameterisation) { |
479 | case Convert_QuasiAngular: |
480 | // |
481 | // we code here in temp_poles(xx).Coord(1) the following function V(t) |
482 | // and in temp_poles(xx).Coord(2) the function U(t) |
483 | // 3 |
484 | // V(t) = t + c t |
485 | // 2 |
486 | // U(t) = 1 + b t |
487 | // 1 |
488 | // c = --- + b = q_param |
489 | // 3 |
490 | // 3 |
491 | // gamma |
492 | // gamma + ------ - tang gamma |
493 | // 3 |
494 | // b =------------------------------ = p_param |
495 | // 2 |
496 | // gamma (tang gamma - gamma) |
497 | // |
498 | // with gamma = alpha / 2 |
499 | // |
500 | // |
501 | |
502 | alpha_2 = alpha * 0.5e0 ; |
503 | p_param = - 1.0e0 / (alpha_2 * alpha_2) ; |
504 | |
d538d7a2 |
505 | if (alpha_2 < M_PI * 0.5e0) |
506 | { |
507 | if (alpha_2 < 1.0e-7) |
508 | { |
509 | // Fixed degenerate case, when obtain 0 / 0 uncertainty. |
510 | // According to Taylor aprroximation: |
511 | // b (gamma) = -6.0 / 15.0 + o(gamma^2) |
512 | p_param = -6.0 / 15.0; |
513 | } |
514 | else |
515 | { |
516 | tan_alpha_2 = Tan(alpha_2) ; |
517 | value1 = 3.0e0 * (tan_alpha_2 - alpha_2) ; |
518 | value1 = alpha_2 / value1 ; |
519 | p_param += value1 ; |
520 | } |
7fd59977 |
521 | } |
522 | q_param = (1.0e0 / 3.0e0) + p_param ; |
523 | |
524 | |
525 | temp_degree = 3 ; |
526 | temp_poles(1).SetCoord(1,0.0e0); |
527 | temp_poles(2).SetCoord(1,1.0e0); |
528 | temp_poles(3).SetCoord(1,0.0e0) ; |
529 | temp_poles(4).SetCoord(1,q_param) ; |
530 | |
531 | temp_poles(1).SetCoord(2, 1.0e0) ; |
532 | temp_poles(2).SetCoord(2, 0.0e0) ; |
533 | temp_poles(3).SetCoord(2, p_param) ; |
534 | temp_poles(4).SetCoord(2, 0.0e0); |
535 | EvaluatorPtr = &CosAndSinQuasiAngular ; |
536 | break ; |
537 | case Convert_RationalC1: |
538 | for (ii = order + 1 ; ii <= num_poles ; ii++) { |
539 | flat_knots(ii) = 0.0e0 ; |
540 | } |
541 | KnotsPtr->SetValue(2,UFirst + alpha) ; |
542 | MultsPtr->SetValue(2,Degree -1) ; |
543 | temp_degree = 2 ; |
544 | alpha_2 = alpha * 0.5e0 ; |
545 | alpha_4 = alpha * 0.25e0 ; |
546 | tan_alpha_2 = Tan(alpha_2) ; |
547 | jj = 1 ; |
548 | for (ii = 1 ; ii <= 2 ; ii++) { |
549 | temp_poles(1+ ii).SetCoord(2,1.0e0 + alpha_4 * tan_alpha_2) ; |
550 | temp_poles(jj).SetCoord(2,1.e0) ; |
551 | jj += 3 ; |
552 | } |
553 | temp_poles(1).SetCoord(1,-tan_alpha_2) ; |
554 | temp_poles(2).SetCoord(1,alpha_4 - tan_alpha_2) ; |
555 | temp_poles(3).SetCoord(1,-alpha_4 + tan_alpha_2) ; |
556 | temp_poles(4).SetCoord(1,tan_alpha_2) ; |
557 | temp_knots(1) = -alpha ; |
558 | temp_knots(2) = 0.0e0 ; |
559 | temp_knots(3) = alpha ; |
560 | temp_mults(1) = temp_degree + 1; |
561 | temp_mults(2) = 1 ; |
562 | temp_mults(3) = temp_degree + 1; |
563 | |
564 | EvaluatorPtr = &CosAndSinRationalC1 ; |
565 | break ; |
566 | default: |
567 | break ; |
568 | } |
569 | AlgorithmicCosAndSin(Degree, |
570 | flat_knots, |
571 | temp_degree, |
572 | temp_poles, |
573 | temp_knots, |
0e14656b |
574 | &temp_mults, |
7fd59977 |
575 | *EvaluatorPtr, |
576 | CosNumeratorPtr->ChangeArray1(), |
577 | SinNumeratorPtr->ChangeArray1(), |
578 | DenominatorPtr->ChangeArray1()) ; |
579 | |
580 | for (ii = 1 ; ii <= num_poles ; ii++) { |
581 | value1 = cos_beta * CosNumeratorPtr->Value(ii) - |
582 | sin_beta * SinNumeratorPtr->Value(ii) ; |
583 | value2 = sin_beta * CosNumeratorPtr->Value(ii) + |
584 | cos_beta * SinNumeratorPtr->Value(ii) ; |
585 | CosNumeratorPtr->SetValue(ii,value1) ; |
586 | SinNumeratorPtr->SetValue(ii,value2) ; |
587 | } |
588 | } |
589 | else { // Convert_Polynomial |
590 | |
591 | KnotsPtr->SetValue(1, 0.) ; |
592 | KnotsPtr->SetValue(num_knots, 1.); |
593 | MultsPtr->SetValue(1, num_poles); |
594 | MultsPtr->SetValue(num_knots, num_poles); |
595 | |
596 | BuildPolynomialCosAndSin(UFirst,ULast,num_poles, |
597 | CosNumeratorPtr,SinNumeratorPtr,DenominatorPtr); |
598 | } |
599 | |
600 | |
601 | } |
602 | //======================================================================= |
603 | //function : BuildCosAndSin |
604 | //purpose : |
605 | //======================================================================= |
606 | |
607 | void Convert_ConicToBSplineCurve::BuildCosAndSin( |
608 | const Convert_ParameterisationType Parameterisation, |
609 | Handle(TColStd_HArray1OfReal)& CosNumeratorPtr, |
610 | Handle(TColStd_HArray1OfReal)& SinNumeratorPtr, |
611 | Handle(TColStd_HArray1OfReal)& DenominatorPtr, |
612 | Standard_Integer& Degree, |
613 | Handle(TColStd_HArray1OfReal)& KnotsPtr, |
614 | Handle(TColStd_HArray1OfInteger)& MultsPtr) const |
615 | { |
616 | Standard_Real half_pi, |
617 | param, |
618 | first_param, |
619 | last_param, |
620 | // direct, |
621 | inverse, |
622 | value1, |
623 | value2, |
624 | value3 ; |
625 | |
626 | Standard_Integer |
627 | ii, |
628 | jj, |
629 | index, |
630 | num_poles, |
631 | num_periodic_poles, |
632 | temp_degree, |
633 | pivot_index_problem, |
634 | num_flat_knots, |
635 | num_knots, |
636 | order ; |
637 | |
638 | if (Parameterisation != Convert_TgtThetaOver2 && |
639 | Parameterisation != Convert_RationalC1) { |
9775fa61 |
640 | throw Standard_ConstructionError() ; |
7fd59977 |
641 | } |
642 | Handle(TColStd_HArray1OfReal) temp_cos_ptr, |
643 | temp_sin_ptr, |
644 | temp_denominator_ptr, |
645 | temp_knots_ptr; |
646 | Handle(TColStd_HArray1OfInteger) temp_mults_ptr; |
647 | if (Parameterisation == Convert_TgtThetaOver2) { |
648 | BuildCosAndSin(Convert_TgtThetaOver2_3, |
649 | 0.0e0, |
c6541a0c |
650 | 2 * M_PI, |
7fd59977 |
651 | temp_cos_ptr, |
652 | temp_sin_ptr, |
653 | temp_denominator_ptr, |
654 | Degree, |
655 | KnotsPtr, |
656 | MultsPtr) ; |
657 | CosNumeratorPtr = |
658 | new TColStd_HArray1OfReal(1,temp_cos_ptr->Length() -1) ; |
659 | SinNumeratorPtr = |
660 | new TColStd_HArray1OfReal(1,temp_cos_ptr->Length() -1) ; |
661 | DenominatorPtr = |
662 | new TColStd_HArray1OfReal(1,temp_cos_ptr->Length() -1) ; |
663 | for (ii = temp_cos_ptr->Lower() ; ii <= temp_cos_ptr->Upper()-1 ; ii++) { |
664 | CosNumeratorPtr->SetValue(ii,temp_cos_ptr->Value(ii)) ; |
665 | SinNumeratorPtr->SetValue(ii,temp_sin_ptr->Value(ii)) ; |
666 | DenominatorPtr->SetValue(ii,temp_denominator_ptr->Value(ii)) ; |
667 | } |
668 | for (ii = MultsPtr->Lower() ; ii <= MultsPtr->Upper() ; ii++) { |
669 | MultsPtr->SetValue(ii, Degree) ; |
670 | } |
671 | } |
672 | else if (Parameterisation == Convert_RationalC1) |
673 | { |
674 | first_param = 0.0e0 ; |
c6541a0c |
675 | last_param = M_PI ; |
7fd59977 |
676 | BuildCosAndSin(Convert_RationalC1, |
677 | first_param, |
678 | last_param, |
679 | temp_cos_ptr, |
680 | temp_sin_ptr, |
681 | temp_denominator_ptr, |
682 | temp_degree, |
683 | temp_knots_ptr, |
684 | temp_mults_ptr) ; |
685 | |
686 | |
687 | Degree = 4 ; |
688 | order = Degree + 1 ; |
689 | num_knots = 5 ; |
690 | num_flat_knots = (Degree -1) * num_knots + 2 * 2 ; |
691 | num_poles = num_flat_knots - order ; |
692 | num_periodic_poles = num_poles - 2 ; |
693 | TColStd_Array1OfReal flat_knots(1,num_flat_knots) ; |
694 | CosNumeratorPtr = |
695 | new TColStd_HArray1OfReal(1,num_periodic_poles) ; |
696 | SinNumeratorPtr = |
697 | new TColStd_HArray1OfReal(1,num_periodic_poles) ; |
698 | DenominatorPtr = |
699 | new TColStd_HArray1OfReal(1,num_periodic_poles) ; |
700 | |
c6541a0c |
701 | half_pi = M_PI * 0.5e0 ; |
7fd59977 |
702 | index = 1 ; |
703 | for (jj = 1 ; jj <= 2 ; jj++) { |
704 | flat_knots(index) = - half_pi ; |
705 | index += 1 ; |
706 | } |
707 | for (ii = 1 ; ii <= num_knots ; ii++) { |
708 | for (jj = 1 ; jj <= Degree -1 ; jj++) { |
709 | flat_knots(index) = (ii-1) * half_pi ; |
710 | |
711 | index += 1 ; |
712 | |
713 | } |
714 | } |
715 | for (jj = 1 ; jj <= 2 ; jj++) { |
c6541a0c |
716 | flat_knots(index) = 2 * M_PI + half_pi ; |
7fd59977 |
717 | index += 1 ; |
718 | } |
719 | KnotsPtr = |
720 | new TColStd_HArray1OfReal(1,num_knots) ; |
721 | MultsPtr = |
722 | new TColStd_HArray1OfInteger(1,num_knots) ; |
723 | for ( ii = 1 ; ii <= num_knots ; ii++) { |
724 | KnotsPtr->SetValue(ii, (ii-1) * half_pi) ; |
725 | MultsPtr->SetValue(ii, Degree-1) ; |
726 | } |
727 | order = degree + 1 ; |
728 | |
729 | TColStd_Array1OfReal parameters(1,num_poles) ; |
730 | TColgp_Array1OfPnt poles_array(1,num_poles) ; |
731 | TColStd_Array1OfInteger contact_order_array(1,num_poles) ; |
732 | BSplCLib::BuildSchoenbergPoints(Degree, |
733 | flat_knots, |
734 | parameters) ; |
735 | inverse = 1.0e0 ; |
736 | for (ii = parameters.Lower() ; ii <= parameters.Upper() ; ii++) { |
737 | param = parameters(ii) ; |
c6541a0c |
738 | if (param > M_PI) { |
7fd59977 |
739 | inverse = -1.0e0 ; |
c6541a0c |
740 | param -= M_PI ; |
7fd59977 |
741 | } |
742 | BSplCLib::D0(param, |
743 | 0, |
744 | temp_degree, |
745 | Standard_False, |
746 | temp_cos_ptr->Array1(), |
0e14656b |
747 | &temp_denominator_ptr->Array1(), |
7fd59977 |
748 | temp_knots_ptr->Array1(), |
0e14656b |
749 | &temp_mults_ptr->Array1(), |
7fd59977 |
750 | value1) ; |
751 | |
752 | BSplCLib::D0(param, |
753 | 0, |
754 | temp_degree, |
755 | Standard_False, |
756 | temp_sin_ptr->Array1(), |
0e14656b |
757 | &temp_denominator_ptr->Array1(), |
7fd59977 |
758 | temp_knots_ptr->Array1(), |
0e14656b |
759 | &temp_mults_ptr->Array1(), |
7fd59977 |
760 | value2) ; |
761 | BSplCLib::D0(param, |
762 | 0, |
763 | temp_degree, |
764 | Standard_False, |
765 | temp_denominator_ptr->Array1(), |
766 | BSplCLib::NoWeights(), |
767 | temp_knots_ptr->Array1(), |
0e14656b |
768 | &temp_mults_ptr->Array1(), |
7fd59977 |
769 | value3) ; |
770 | contact_order_array(ii) = 0 ; |
771 | |
772 | poles_array(ii).SetCoord(1, |
773 | value1 * value3 * inverse) ; |
774 | poles_array(ii).SetCoord(2, |
775 | value2 * value3 * inverse) ; |
776 | poles_array(ii).SetCoord(3, |
777 | value3) ; |
778 | } |
779 | BSplCLib::Interpolate(Degree, |
780 | flat_knots, |
781 | parameters, |
782 | contact_order_array, |
783 | poles_array, |
784 | pivot_index_problem) ; |
785 | for (ii = 1 ; ii <= num_periodic_poles ; ii++) { |
786 | inverse = 1.0e0 / poles_array(ii).Coord(3) ; |
787 | CosNumeratorPtr->ChangeArray1()(ii) = poles_array(ii).Coord(1) * inverse ; |
788 | SinNumeratorPtr->ChangeArray1()(ii) = poles_array(ii).Coord(2) * inverse ; |
789 | DenominatorPtr->ChangeArray1()(ii) = poles_array(ii).Coord(3) ; |
790 | } |
791 | } |
792 | } |
793 | |
794 | |
795 | |