1 // Created on: 1997-01-15
2 // Created by: Stagiaire Francois DUMONT
3 // Copyright (c) 1997-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Geom_BSplineCurve.hxx>
19 #include <Geom2d_BSplineCurve.hxx>
20 #include <BSplCLib.hxx>
21 #include <TColStd_Array1OfReal.hxx>
22 #include <TColStd_HArray1OfReal.hxx>
23 #include <TColStd_Array1OfInteger.hxx>
24 #include <TColStd_HArray1OfInteger.hxx>
26 #include <Standard_Boolean.hxx>
27 #include <gp_Pnt2d.hxx>
28 #include <TColgp_Array1OfPnt2d.hxx>
29 #include <Standard_DimensionError.hxx>
30 #include <Standard_Real.hxx>
31 #include <TCollection_CompareOfReal.hxx>
32 #include <SortTools_QuickSortOfReal.hxx>
33 #include <Precision.hxx>
35 //=======================================================================
36 //function : HermiteCoeff
37 //purpose : calculate the Hermite coefficients of degree 3 from BS and
38 // store them in TAB(4 coefficients)
39 //=======================================================================
41 static void HermiteCoeff(const Handle(Geom_BSplineCurve)& BS,
42 TColStd_Array1OfReal& TAB)
45 TColStd_Array1OfReal Knots(1,BS->NbKnots());
46 TColStd_Array1OfReal Weights(1,BS->NbPoles());
47 TColStd_Array1OfInteger Mults(1,BS->NbKnots());
48 Standard_Integer Degree,Index0,Index1; // denominateur value for u=0 & u=1
49 Standard_Real Denom0,Denom1, // denominator value for u=0 & u=1
50 Deriv0,Deriv1 ; // derivative denominator value for u=0 & 1
51 Standard_Boolean Periodic;
54 BSplCLib::Reparametrize(0.0,1.0,Knots); //affinity on the nodal vector
56 BS->Multiplicities(Mults);
57 Degree = BS->Degree();
58 Periodic = BS->IsPeriodic();
59 Index0 = BS->FirstUKnotIndex();
60 Index1 = BS->LastUKnotIndex()-1;
62 BSplCLib::D1(0.0,Index0,Degree,Periodic,Weights,BSplCLib::NoWeights(),Knots,Mults,Denom0,Deriv0);
63 BSplCLib::D1(1.0,Index1,Degree,Periodic,Weights,BSplCLib::NoWeights(),Knots,Mults,Denom1,Deriv1);
64 TAB(0) = 1/Denom0; //Hermit coefficients
65 TAB(1) = -Deriv0/(Denom0*Denom0);
66 TAB(2) = -Deriv1/(Denom1*Denom1);
71 //=======================================================================
72 //function : HermiteCoeff
73 //purpose : calculate the Hermite coefficients of degree 3 from BS and
74 // store them in TAB(4 coefficients)
75 //=======================================================================
77 static void HermiteCoeff(const Handle(Geom2d_BSplineCurve)& BS,
78 TColStd_Array1OfReal& TAB)
81 TColStd_Array1OfReal Knots(1,BS->NbKnots());
82 TColStd_Array1OfReal Weights(1,BS->NbPoles());
83 TColStd_Array1OfInteger Mults(1,BS->NbKnots());
84 Standard_Integer Degree,Index0,Index1;
85 Standard_Real Denom0,Denom1, // denominateur value for u=0 & u=1
86 Deriv0,Deriv1 ; // denominator value for u=0 & u=1
87 Standard_Boolean Periodic; // derivative denominatur value for u=0 & 1
90 BSplCLib::Reparametrize(0.0,1.0,Knots); //affinity on the nodal vector
92 BS->Multiplicities(Mults);
93 Degree = BS->Degree();
94 Periodic = BS->IsPeriodic();
95 Index0 = BS->FirstUKnotIndex();
96 Index1 = BS->LastUKnotIndex()-1;
98 BSplCLib::D1(0.0,Index0,Degree,Periodic,Weights,BSplCLib::NoWeights(),Knots,Mults,Denom0,Deriv0);
99 BSplCLib::D1(1.0,Index1,Degree,Periodic,Weights,BSplCLib::NoWeights(),Knots,Mults,Denom1,Deriv1);
100 TAB(0) = 1/Denom0; //Hermit coefficients
101 TAB(1) = -Deriv0/(Denom0*Denom0);
102 TAB(2) = -Deriv1/(Denom1*Denom1);
107 //=======================================================================
108 //function : SignDenom
109 //purpose : give the sign of Herm(0) True=Positive
110 //=======================================================================
112 static Standard_Boolean SignDenom(const TColgp_Array1OfPnt2d& Poles)
115 Standard_Boolean Result;
118 Result=Standard_False;
119 else Result=Standard_True;
123 //=======================================================================
125 //purpose : give the max and the min of the Poles (by their index)
126 //=======================================================================
129 static void Polemax(const TColgp_Array1OfPnt2d& Poles,
130 Standard_Integer& min,
131 Standard_Integer& max)
134 // Standard_Integer i,index=0;
136 Standard_Real Max,Min; //intermediate value of max and min ordinates
137 min=0;max=0; //initialisation of the indices
139 Min=Poles(0).Y(); //initialisation of the intermediate value
141 for (i=1;i<=(Poles.Length()-1);i++){
142 if (Poles(i).Y()<Min){
146 if (Poles(i).Y()>Max){
153 //=======================================================================
154 //function : PolyTest
155 //purpose : give the knots U4 and U5 to insert to a(u)
156 //=======================================================================
159 static void PolyTest(const TColStd_Array1OfReal& Herm,
160 const Handle(Geom_BSplineCurve)& BS,
163 Standard_Integer& boucle,
164 const Standard_Real TolPoles,
165 // const Standard_Real TolKnots,
166 const Standard_Real ,
167 const Standard_Real Ux,
168 const Standard_Real Uy)
171 Standard_Integer index,i,
172 I1=0,I2=0,I3=0,I4=0; //knots index
173 TColgp_Array1OfPnt2d Polesinit(0,3) ;
174 Handle(TColStd_HArray1OfReal) Knots; //array of the BSpline knots + the ones inserted
175 Standard_Integer cas=0,mark=0,dercas=0, //loop marks
176 min,max; //Pole min and max indices
177 Standard_Real Us1,Us2,a; //bounderies value of the knots to be inserted
179 TCollection_CompareOfReal Comp;
181 U4=0.0;U5=1.0; //default value
183 BS->LocateU(Ux,0.0,I1,I2); //localization of the inserted knots
185 BS->LocateU(Uy,0.0,I3,I4);
188 if (I1==I2) //definition and filling of the
189 if((I3==I4)||(I3==0)){ //array of knots
190 Knots=new TColStd_HArray1OfReal(1,BS->NbKnots());
191 for (i=1;i<=BS->NbKnots();i++)
192 Knots->SetValue(i,BS->Knot(i));
195 Knots=new TColStd_HArray1OfReal(1,BS->NbKnots()+1);
196 for (i=1;i<=BS->NbKnots();i++)
197 Knots->SetValue(i,BS->Knot(i));
198 Knots->SetValue(BS->NbKnots()+1,Uy);
201 if((I3==I4)||(I3==0)){
202 Knots=new TColStd_HArray1OfReal(1,BS->NbKnots()+1);
203 for (i=1;i<=BS->NbKnots();i++)
204 Knots->SetValue(i,BS->Knot(i));
205 Knots->SetValue(BS->NbKnots()+1,Ux);
208 Knots=new TColStd_HArray1OfReal(1,BS->NbKnots()+2);
209 for (i=1;i<=BS->NbKnots();i++)
210 Knots->SetValue(i,BS->Knot(i));
211 Knots->SetValue(BS->NbKnots()+1,Ux);
212 Knots->SetValue(BS->NbKnots()+2,Uy);
216 TColStd_Array1OfReal knots(1,Knots->Length());
217 knots=Knots->ChangeArray1();
218 SortTools_QuickSortOfReal::Sort(knots,Comp); //sort of the array of knots
220 Polesinit(0).SetCoord(0.0,Herm(0)); //poles of the Hermite polynome in the BSpline form
221 Polesinit(1).SetCoord(0.0,Herm(0)+Herm(1)/3.0);
222 Polesinit(2).SetCoord(0.0,Herm(3)-Herm(2)/3.0);
223 Polesinit(3).SetCoord(0.0,Herm(3));
225 //loop to check the tolerances on poles
227 Polemax(Polesinit,min,max);
228 Standard_Real Polemin=Polesinit(min).Y();
229 Standard_Real Polemax=Polesinit(max).Y();
230 if (((Polemax)>=((1/TolPoles)*Polemin))||((Polemin==0.0)&&(Polemax>=(1/TolPoles)))){
231 if (Polesinit(0).Y()>=(1/TolPoles)*Polesinit(3).Y()||Polesinit(0).Y()<=TolPoles*Polesinit(3).Y())
232 Standard_DimensionError::Raise("Hermit Impossible Tolerance");
233 if ((max==0)||(max==3))
236 Polesinit(i).SetCoord(0.0,(Polesinit(i).Y()-TolPoles*Polemax));
238 else if ((max==1)||(max==2)) {
239 if ((min==0)||(min==3))
242 Polesinit(i).SetCoord(0.0,(Polesinit(i).Y()-(1/TolPoles)*Polemin));
245 if ((TolPoles*Polemax<Polesinit(0).Y())&&(TolPoles*Polemax<Polesinit(3).Y())){
247 Polesinit(i).SetCoord(0.0,(Polesinit(i).Y()-TolPoles*Polemax));
250 if ((1/TolPoles*Polemin>Polesinit(0).Y())&&(1/TolPoles*Polemin>Polesinit(3).Y())&&(mark==0)){
252 Polesinit(i).SetCoord(0.0,(Polesinit(i).Y()-1/TolPoles*Polemin));
256 Standard_Real Pole0,Pole3;
257 Pole0=Polesinit(0).Y();
258 Pole3=Polesinit(3).Y();
260 a=Log10(Pole3/Pole0);
264 Polesinit(i).SetCoord(0.0, Polesinit(i).Y()-(Pole3*(Pow(10.0,(-0.5*Log10(TolPoles)-a/2.0)))));
269 Polesinit(i).SetCoord(0.0, Polesinit(i).Y()-(Pole0*(Pow(10.0,(a/2.0+0.5*Log10(TolPoles))))));
275 a=Log10(Pole0/Pole3);
279 Polesinit(i).SetCoord(0.0, Polesinit(i).Y()-(Pole0*(Pow(10.0,(-0.5*Log10(TolPoles)-a/2.0)))));
284 Polesinit(i).SetCoord(0.0, Polesinit(i).Y()-(Pole3*(Pow(10.0,(a/2.0+0.5*Log10(TolPoles))))));
294 if (!SignDenom(Polesinit)) //invertion of the polynome sign
296 for (index=0;index<=3;index++)
297 Polesinit(index).SetCoord(0.0,-Polesinit(index).Y());
300 // loop of positivity
301 if ((Polesinit(1).Y()<0.0)&&(Polesinit(2).Y()>=0.0))
303 Us1=Polesinit(0).Y()/(Polesinit(0).Y()-Polesinit(1).Y());
309 BSplCLib::LocateParameter(3,knots,Us1,Standard_False,1,knots.Length(),I1,Us1);
316 if ((Polesinit(1).Y()>=0.0)&&(Polesinit(2).Y()<0.0))
318 Us2=Polesinit(2).Y()/(Polesinit(2).Y()-Polesinit(3).Y());
320 Us2=knots(knots.Length()-1)+Us2*(1-knots(knots.Length()-1));
324 BSplCLib::LocateParameter(3,knots,Us2,Standard_False,1,knots.Length(),I1,Us2);
325 if (I1>=(knots.Length()-1))
334 if ((Polesinit(1).Y()<0.0)&&(Polesinit(2).Y()<0.0)){
335 Us1=Polesinit(0).Y()/(Polesinit(0).Y()-Polesinit(1).Y());
336 Us2=Polesinit(2).Y()/(Polesinit(2).Y()-Polesinit(3).Y());
343 BSplCLib::LocateParameter(3,knots,Us1,Standard_False,1,knots.Length(),I1,Us1);
344 if (knots(I1)>=Us2) //insertion of one knot for the two poles
347 if (I1>=2){ //insertion to the left and
348 U4=knots(I1); //to the right without a new knot
349 BSplCLib::LocateParameter(3,knots,Us2,Standard_False,1,knots.Length(),I3,Us2);
350 if (I3<(BS->NbKnots()-1)){
355 if(cas==0) //insertion of only one new knot
359 else{ //insertion of two knots
360 BSplCLib::LocateParameter(3,knots,Us1,Standard_False,1,knots.Length(),I1,Us1);
365 BSplCLib::LocateParameter(3,knots,Us2,Standard_False,1,knots.Length(),I3,Us2);
366 if (I3<(BS->NbKnots()-1))
374 //=======================================================================
375 //function : PolyTest
376 //purpose : give the knots U4 and U5 to insert to a(u)
377 //=======================================================================
380 static void PolyTest(const TColStd_Array1OfReal& Herm,
381 const Handle(Geom2d_BSplineCurve)& BS,
384 Standard_Integer& boucle,
385 const Standard_Real TolPoles,
386 // const Standard_Real TolKnots,
387 const Standard_Real ,
388 const Standard_Real Ux,
389 const Standard_Real Uy)
392 Standard_Integer index,i,
393 I1=0,I2=0,I3=0,I4=0; //knots index
394 TColgp_Array1OfPnt2d Polesinit(0,3) ;
395 Handle(TColStd_HArray1OfReal) Knots; //array of the BSpline knots + the ones inserted
396 Standard_Integer cas=0,mark=0,dercas=0, //loop marks
397 min,max; //Pole min and max indices
398 Standard_Real Us1,Us2,a; //bounderies value of the knots to be inserted
400 TCollection_CompareOfReal Comp;
402 U4=0.0;U5=1.0; //default value
404 BS->LocateU(Ux,0.0,I1,I2); //localization of the inserted knots
406 BS->LocateU(Uy,0.0,I3,I4);
409 if (I1==I2) //definition and filling of the
411 if((I3==I4)||(I3==0)){ //array of knots
412 Knots=new TColStd_HArray1OfReal(1,BS->NbKnots());
413 for (i=1;i<=BS->NbKnots();i++)
414 Knots->SetValue(i,BS->Knot(i));
417 Knots=new TColStd_HArray1OfReal(1,BS->NbKnots()+1);
418 for (i=1;i<=BS->NbKnots();i++)
419 Knots->SetValue(i,BS->Knot(i));
420 Knots->SetValue(BS->NbKnots()+1,Uy);
425 if((I3==I4)||(I3==0)){
426 Knots=new TColStd_HArray1OfReal(1,BS->NbKnots()+1);
427 for (i=1;i<=BS->NbKnots();i++)
428 Knots->SetValue(i,BS->Knot(i));
429 Knots->SetValue(BS->NbKnots()+1,Ux);
432 Knots=new TColStd_HArray1OfReal(1,BS->NbKnots()+2);
433 for (i=1;i<=BS->NbKnots();i++)
434 Knots->SetValue(i,BS->Knot(i));
435 Knots->SetValue(BS->NbKnots()+1,Ux);
436 Knots->SetValue(BS->NbKnots()+2,Uy);
440 TColStd_Array1OfReal knots(1,Knots->Length());
441 knots=Knots->ChangeArray1();
442 SortTools_QuickSortOfReal::Sort(knots,Comp); //sort of the array of knots
444 Polesinit(0).SetCoord(0.0,Herm(0)); //poles of the Hermite polynome in the BSpline form
445 Polesinit(1).SetCoord(0.0,Herm(0)+Herm(1)/3.0);
446 Polesinit(2).SetCoord(0.0,Herm(3)-Herm(2)/3.0);
447 Polesinit(3).SetCoord(0.0,Herm(3));
449 // loop to check the tolerances on poles
452 Polemax(Polesinit,min,max);
453 Standard_Real Polemin=Polesinit(min).Y();
454 Standard_Real Polemax=Polesinit(max).Y();
455 if (((Polemax)>=((1/TolPoles)*Polemin))||((Polemin==0.0)&&(Polemax>=(1/TolPoles))))
457 if (Polesinit(0).Y()>=(1/TolPoles)*Polesinit(3).Y()||Polesinit(0).Y()<=TolPoles*Polesinit(3).Y())
458 Standard_DimensionError::Raise("Hermit Impossible Tolerance");
459 if ((max==0)||(max==3))
462 Polesinit(i).SetCoord(0.0,(Polesinit(i).Y()-TolPoles*Polemax));
464 else if ((max==1)||(max==2))
466 if ((min==0)||(min==3))
469 Polesinit(i).SetCoord(0.0,(Polesinit(i).Y()-(1/TolPoles)*Polemin));
473 if ((TolPoles*Polemax<Polesinit(0).Y())&&(TolPoles*Polemax<Polesinit(3).Y()))
476 Polesinit(i).SetCoord(0.0,(Polesinit(i).Y()-TolPoles*Polemax));
480 if ((1/TolPoles*Polemin>Polesinit(0).Y())&&(1/TolPoles*Polemin>Polesinit(3).Y())&&(mark==0))
483 Polesinit(i).SetCoord(0.0,(Polesinit(i).Y()-1/TolPoles*Polemin));
488 Standard_Real Pole0,Pole3;
489 Pole0=Polesinit(0).Y();
490 Pole3=Polesinit(3).Y();
493 a=Log10(Pole3/Pole0);
497 Polesinit(i).SetCoord(0.0, Polesinit(i).Y()-(Pole3*(Pow(10.0,(-0.5*Log10(TolPoles)-a/2.0)))));
502 Polesinit(i).SetCoord(0.0, Polesinit(i).Y()-(Pole0*(Pow(10.0,(a/2.0+0.5*Log10(TolPoles))))));
508 a=Log10(Pole0/Pole3);
512 Polesinit(i).SetCoord(0.0, Polesinit(i).Y()-(Pole0*(Pow(10.0,(-0.5*Log10(TolPoles)-a/2.0)))));
517 Polesinit(i).SetCoord(0.0, Polesinit(i).Y()-(Pole3*(Pow(10.0,(a/2.0+0.5*Log10(TolPoles))))));
527 if (!SignDenom(Polesinit)) // invertion of the polynome sign
529 for (index=0;index<=3;index++)
530 Polesinit(index).SetCoord(0.0,-Polesinit(index).Y());
533 // boucle de positivite
534 if ((Polesinit(1).Y()<0.0)&&(Polesinit(2).Y()>=0.0))
536 Us1=Polesinit(0).Y()/(Polesinit(0).Y()-Polesinit(1).Y());
542 BSplCLib::LocateParameter(3,knots,Us1,Standard_False,1,knots.Length(),I1,Us1);
549 if ((Polesinit(1).Y()>=0.0)&&(Polesinit(2).Y()<0.0))
551 Us2=Polesinit(2).Y()/(Polesinit(2).Y()-Polesinit(3).Y());
553 Us2=knots(knots.Length()-1)+Us2*(1-knots(knots.Length()-1));
557 BSplCLib::LocateParameter(3,knots,Us2,Standard_False,1,knots.Length(),I1,Us2);
558 if (I1>=(knots.Length()-1))
567 if ((Polesinit(1).Y()<0.0)&&(Polesinit(2).Y()<0.0)){
568 Us1=Polesinit(0).Y()/(Polesinit(0).Y()-Polesinit(1).Y());
569 Us2=Polesinit(2).Y()/(Polesinit(2).Y()-Polesinit(3).Y());
576 BSplCLib::LocateParameter(3,knots,Us1,Standard_False,1,knots.Length(),I1,Us1);
577 if (knots(I1)>=Us2) //insertion of one knot for the two poles
580 if (I1>=2){ //insertion to the left and
581 U4=knots(I1); //to the right without a new knot
582 BSplCLib::LocateParameter(3,knots,Us2,Standard_False,1,knots.Length(),I3,Us2);
583 if (I3<(BS->NbKnots()-1)){
588 if(cas==0) //insertion of only one new knot
592 else{ //insertion of two knots
593 BSplCLib::LocateParameter(3,knots,Us1,Standard_False,1,knots.Length(),I1,Us1);
598 BSplCLib::LocateParameter(3,knots,Us2,Standard_False,1,knots.Length(),I3,Us2);
599 if (I3<(BS->NbKnots()-1))
607 //=======================================================================
608 //function : InsertKnots
609 //purpose : insert the knots in BS knot sequence if they are not null.
610 //=======================================================================
612 static void InsertKnots(Handle(Geom2d_BSplineCurve)& BS,
613 const Standard_Real U4,
614 const Standard_Real U5)
617 if (U4!=0.0) //insertion of :0 knot if U4=0
618 BS->InsertKnot(U4); // 1 knot if U4=U5
619 if ((U5!=1.0)&&(U5!=U4)) // 2 knots otherwise
624 //=======================================================================
625 //function : MovePoles
626 //purpose : move the poles above the x axis
627 //=======================================================================
629 static void MovePoles(Handle(Geom2d_BSplineCurve)& BS)
633 // Standard_Integer i,index;
636 for (i=3;i<=(BS->NbPoles()-2);i++){
637 P.SetCoord(1,(BS->Pole(i).Coord(1))); //raising of the no constrained poles to
638 P.SetCoord(2,(BS->Pole(1).Coord(2))); //the first pole level
643 //=======================================================================
644 //function : Solution
646 //=======================================================================
648 Handle(Geom2d_BSplineCurve) Hermit::Solution(const Handle(Geom_BSplineCurve)& BS,
649 const Standard_Real TolPoles,
650 const Standard_Real TolKnots)
653 TColStd_Array1OfReal Herm(0,3);
654 Standard_Real Upos1=0.0, Upos2=1.0, //positivity knots
656 Utol1=0.0, Utol2=1.0, //tolerance knots
657 Uint1=0.0, Uint2=1.0; //tolerance knots for the first loop
658 Standard_Integer boucle=1; //loop mark
659 TColStd_Array1OfReal Knots(1,2);
660 TColStd_Array1OfInteger Multiplicities(1,2);
661 TColgp_Array1OfPnt2d Poles(1,4);
662 Standard_Integer zeroboucle = 0 ;
663 HermiteCoeff(BS,Herm); //computation of the Hermite coefficient
665 Poles(1).SetCoord(0.0,Herm(0)); //poles of the Hermite polynome in the BSpline form
666 Poles(2).SetCoord(0.0,Herm(0)+Herm(1)/3.0);
667 Poles(3).SetCoord(0.0,Herm(3)-Herm(2)/3.0);
668 Poles(4).SetCoord(0.0,Herm(3));
674 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(Poles,Knots,Multiplicities,3);//creation of the basic
675 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(Poles,Knots,Multiplicities,3);//BSpline without modif
677 PolyTest(Herm,BS,Upos1,Upos2,zeroboucle,Precision::Confusion(),Precision::Confusion(),1.0,0.0);//computation of the positivity knots
678 InsertKnots(BS2,Upos1,Upos2); //and insertion
694 Herm(0)=BS2->Pole(1).Y(); //computation of the Hermite coefficient on the
695 Herm(1)=3*(BS2->Pole(2).Y()-BS2->Pole(1).Y()); //positive BSpline
696 Herm(2)=3*(BS2->Pole(BS2->NbPoles()).Y()-BS2->Pole(BS2->NbPoles()-1).Y());
697 Herm(3)=BS2->Pole(BS2->NbPoles()).Y();
699 PolyTest(Herm,BS,Utol1,Utol2,boucle,TolPoles,TolKnots,Ux,Uy); //computation of the tolerance knots
700 InsertKnots(BS2,Utol1,Utol2); //and insertion
702 if (boucle==2){ //insertion of two knots
703 Herm(0)=BS2->Pole(1).Y();
704 Herm(1)=3*(BS2->Pole(2).Y()-BS2->Pole(1).Y());
705 Herm(2)=3*(BS2->Pole(BS2->NbPoles()).Y()-BS2->Pole(BS2->NbPoles()-1).Y());
706 Herm(3)=BS2->Pole(BS2->NbPoles()).Y();
709 PolyTest(Herm,BS,Utol1,Utol2,boucle,TolPoles,TolKnots,Uint2,0.0);
713 PolyTest(Herm,BS,Utol1,Utol2,boucle,TolPoles,TolKnots,Uint1,0.0);
715 InsertKnots(BS2,Utol1,Utol2);
717 if ((BS2->Knot(2)<TolKnots)||(BS2->Knot(BS2->NbKnots()-1)>(1-TolKnots))) //checking of the knots tolerance
718 Standard_DimensionError::Raise("Hermit Impossible Tolerance");
720 if ((Upos2==1.0)&&(Utol2==1.0)&&(Uint2==1.0)) //test on the final inserted knots
721 InsertKnots(BS1,BS2->Knot(2),1.0);
723 if ((Upos1==0.0)&&(Utol1==0.0)&&(Uint1==0.0))
724 InsertKnots(BS1,BS2->Knot(BS2->NbKnots()-1),1.0);
726 InsertKnots(BS1,BS2->Knot(BS2->NbKnots()-1),BS2->Knot(2));
728 MovePoles(BS1); //relocation of the no-contrained knots
734 //=======================================================================
736 //=======================================================================
738 Handle(Geom2d_BSplineCurve) Hermit::Solution(const Handle(Geom2d_BSplineCurve)& BS,
739 const Standard_Real TolPoles,
740 const Standard_Real TolKnots)
743 TColStd_Array1OfReal Herm(0,3);
744 Standard_Real Upos1=0.0, Upos2=1.0, //positivity knots
746 Utol1=0.0, Utol2=1.0, //tolerance knots
747 Uint1=0.0, Uint2=1.0; //tolerance knots for the first loop
748 Standard_Integer boucle=1; //loop mark
749 TColStd_Array1OfReal Knots(1,2);
750 TColStd_Array1OfInteger Multiplicities(1,2);
751 TColgp_Array1OfPnt2d Poles(1,4);
752 Standard_Integer zeroboucle = 0 ;
753 HermiteCoeff(BS,Herm); //computation of the Hermite coefficient
755 Poles(1).SetCoord(0.0,Herm(0)); //poles of the Hermite polynome in the BSpline form
756 Poles(2).SetCoord(0.0,Herm(0)+Herm(1)/3.0);
757 Poles(3).SetCoord(0.0,Herm(3)-Herm(2)/3.0);
758 Poles(4).SetCoord(0.0,Herm(3));
764 Handle(Geom2d_BSplineCurve) BS1=new Geom2d_BSplineCurve(Poles,Knots,Multiplicities,3);//creation of the basic
765 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(Poles,Knots,Multiplicities,3);//BSpline without modif
767 PolyTest(Herm,BS,Upos1,Upos2,zeroboucle,Precision::Confusion(),Precision::Confusion(),1.0,0.0);//computation of the positivity knots
768 InsertKnots(BS2,Upos1,Upos2); //and insertion
784 Herm(0)=BS2->Pole(1).Y(); //computation of the Hermite coefficient on the
785 Herm(1)=3*(BS2->Pole(2).Y()-BS2->Pole(1).Y()); //positive BSpline
786 Herm(2)=3*(BS2->Pole(BS2->NbPoles()).Y()-BS2->Pole(BS2->NbPoles()-1).Y());
787 Herm(3)=BS2->Pole(BS2->NbPoles()).Y();
789 PolyTest(Herm,BS,Utol1,Utol2,boucle,TolPoles,TolKnots,Ux,Uy); //computation of the tolerance knots
790 InsertKnots(BS2,Utol1,Utol2); //and insertion
792 if (boucle==2){ //insertion of two knots
793 Herm(0)=BS2->Pole(1).Y();
794 Herm(1)=3*(BS2->Pole(2).Y()-BS2->Pole(1).Y());
795 Herm(2)=3*(BS2->Pole(BS2->NbPoles()).Y()-BS2->Pole(BS2->NbPoles()-1).Y());
796 Herm(3)=BS2->Pole(BS2->NbPoles()).Y();
799 PolyTest(Herm,BS,Utol1,Utol2,boucle,TolPoles,TolKnots,Uint2,0.0);
803 PolyTest(Herm,BS,Utol1,Utol2,boucle,TolPoles,TolKnots,Uint1,0.0);
805 InsertKnots(BS2,Utol1,Utol2);
807 if ((BS2->Knot(2)<TolKnots)||(BS2->Knot(BS2->NbKnots()-1)>(1-TolKnots))) //checking of the knots tolerance
808 Standard_DimensionError::Raise("Hermit Impossible Tolerance");
810 if ((Upos2==1.0)&&(Utol2==1.0)&&(Uint2==1.0)) //test on the final inserted knots
811 InsertKnots(BS1,BS2->Knot(2),1.0);
813 if ((Upos1==0.0)&&(Utol1==0.0)&&(Uint1==0.0))
814 InsertKnots(BS1,BS2->Knot(BS2->NbKnots()-1),1.0);
816 InsertKnots(BS1,BS2->Knot(BS2->NbKnots()-1),BS2->Knot(2));
818 MovePoles(BS1); //relocation of the no-contrained knots
823 //=======================================================================
824 //function : Solutionbis
826 //=======================================================================
828 void Hermit::Solutionbis(const Handle(Geom_BSplineCurve)& BS,
829 Standard_Real & Knotmin,
830 Standard_Real & Knotmax,
831 const Standard_Real TolPoles,
832 const Standard_Real TolKnots)
835 TColStd_Array1OfReal Herm(0,3);
836 Standard_Real Upos1=0.0, Upos2=1.0, //positivity knots
838 Utol1=0.0, Utol2=1.0, //tolerance knots
839 Uint1=0.0, Uint2=1.0; //tolerance knots for the first loop
840 Standard_Integer boucle=1; //loop mark
841 TColStd_Array1OfReal Knots(1,2);
842 TColStd_Array1OfInteger Multiplicities(1,2);
843 TColgp_Array1OfPnt2d Poles(1,4);
844 Standard_Integer zeroboucle = 0 ;
845 HermiteCoeff(BS,Herm); //computation of the Hermite coefficient
847 Poles(1).SetCoord(0.0,Herm(0)); //poles of the Hermite polynome in the BSpline form
848 Poles(2).SetCoord(0.0,Herm(0)+Herm(1)/3.0);
849 Poles(3).SetCoord(0.0,Herm(3)-Herm(2)/3.0);
850 Poles(4).SetCoord(0.0,Herm(3));
856 Handle(Geom2d_BSplineCurve) BS2=new Geom2d_BSplineCurve(Poles,Knots,Multiplicities,3);//creation of the basic
857 //BSpline without modif
859 PolyTest(Herm,BS,Upos1,Upos2,zeroboucle,Precision::Confusion(),Precision::Confusion(),1.0,0.0);//computation of the positivity knots
860 InsertKnots(BS2,Upos1,Upos2); //and insertion
876 Herm(0)=BS2->Pole(1).Y(); //computation of the Hermite coefficient on the
877 Herm(1)=3*(BS2->Pole(2).Y()-BS2->Pole(1).Y()); //positive BSpline
878 Herm(2)=3*(BS2->Pole(BS2->NbPoles()).Y()-BS2->Pole(BS2->NbPoles()-1).Y());
879 Herm(3)=BS2->Pole(BS2->NbPoles()).Y();
881 PolyTest(Herm,BS,Utol1,Utol2,boucle,TolPoles,TolKnots,Ux,Uy); //computation of the tolerance knots
882 InsertKnots(BS2,Utol1,Utol2); //and insertion
884 if (boucle==2){ //insertion of two knots
885 Herm(0)=BS2->Pole(1).Y();
886 Herm(1)=3*(BS2->Pole(2).Y()-BS2->Pole(1).Y());
887 Herm(2)=3*(BS2->Pole(BS2->NbPoles()).Y()-BS2->Pole(BS2->NbPoles()-1).Y());
888 Herm(3)=BS2->Pole(BS2->NbPoles()).Y();
891 PolyTest(Herm,BS,Utol1,Utol2,boucle,TolPoles,TolKnots,Uint2,0.0);
895 PolyTest(Herm,BS,Utol1,Utol2,boucle,TolPoles,TolKnots,Uint1,0.0);
897 InsertKnots(BS2,Utol1,Utol2);
899 if ((BS2->Knot(2)<TolKnots)||(BS2->Knot(BS2->NbKnots()-1)>(1-TolKnots))) //checking of the knots tolerance
900 Standard_DimensionError::Raise("Hermit Impossible Tolerance");
902 if ((Upos2==1.0)&&(Utol2==1.0)&&(Uint2==1.0)) //test on the final inserted knots
903 Knotmin=BS2->Knot(2);
905 if ((Upos1==0.0)&&(Utol1==0.0)&&(Uint1==0.0))
906 Knotmax=BS2->Knot(BS2->NbKnots()-1);
908 Knotmin=BS2->Knot(2);
909 Knotmax=BS2->Knot(BS2->NbKnots()-1);