1 // File: Convert_PolynomialCosAndSin.cxx
2 // Created: Tue Oct 10 15:56:28 1995
3 // Author: Jacques GOUSSARD
7 #include <Convert_PolynomialCosAndSin.hxx>
9 #include <TColgp_Array1OfPnt2d.hxx>
10 #include <gp_Trsf2d.hxx>
11 #include <gp_Pnt2d.hxx>
12 #include <gp_Vec2d.hxx>
16 #include <Precision.hxx>
18 #include <BSplCLib.hxx>
20 #include <Standard_ConstructionError.hxx>
22 static Standard_Real Locate(const Standard_Real Angfin,
23 const TColgp_Array1OfPnt2d& TPoles,
24 const Standard_Real Umin,
25 const Standard_Real Umax)
27 Standard_Real umin = Umin;
28 Standard_Real umax = Umax;
29 Standard_Real Ptol = Precision::Angular();
30 Standard_Real Utol = Precision::PConfusion();
31 while (Abs(umax-umin)>= Utol) {
32 Standard_Real ptest = (umax+umin)/2.;
34 BSplCLib::D0(ptest,TPoles,BSplCLib::NoWeights(),valP);
35 Standard_Real theta = ATan2(valP.Y(),valP.X());
39 if (Abs(theta - Angfin) < Ptol) {
45 else if (theta > Angfin) {
49 return (umin+umax)/2.;
53 void BuildPolynomialCosAndSin
54 (const Standard_Real UFirst,
55 const Standard_Real ULast,
56 const Standard_Integer num_poles,
57 Handle(TColStd_HArray1OfReal)& CosNumeratorPtr,
58 Handle(TColStd_HArray1OfReal)& SinNumeratorPtr,
59 Handle(TColStd_HArray1OfReal)& DenominatorPtr)
73 Standard_Integer ii, degree = num_poles -1 ;
76 // Return UFirst in [-2PI; 2PI]
77 // to make rotations without risk
78 while (locUFirst > PI2) {
81 while (locUFirst < - PI2) {
85 // Return to the arc [0, Delta]
86 Delta = ULast - UFirst;
87 middle = 0.5e0 * Delta ;
89 // coincide the required bisector of the angular sector with
90 // axis -Ox definition of the circle in Bezier of degree 7 so that
91 // parametre 1/2 of Bezier was exactly a point of the bissectrice
92 // of the required angular sector.
94 Angle = middle - M_PI ;
96 // Circle of radius 1. See Euclid
99 TColgp_Array1OfPnt2d TPoles(1,8),
101 TPoles(1).SetCoord(1.,0.);
102 TPoles(2).SetCoord(1.,1.013854);
103 TPoles(3).SetCoord(-0.199043,1.871905);
104 TPoles(4).SetCoord(-1.937729,1.057323);
105 TPoles(5).SetCoord(-1.937729,-1.057323);
106 TPoles(6).SetCoord(-0.199043,-1.871905);
107 TPoles(7).SetCoord(1.,-1.013854);
108 TPoles(8).SetCoord(1.,0.);
110 T.SetRotation(gp::Origin2d(),Angle);
111 for (ii=1; ii<=num_poles; ii++) {
112 TPoles(ii).Transform(T);
116 t_min = 1.0e0 - (Delta * 1.3e0 / M_PI) ;
118 t_min = Max(t_min,0.0e0) ;
119 t_max = 1.0e0 + (Delta * 1.3e0 / M_PI) ;
121 t_max = Min(t_max,1.0e0) ;
122 trim_max = Locate(Delta,
127 // as Bezier is symmetric correspondingly to the bissector
128 // of the angular sector ...
130 trim_min = 1.0e0 - trim_max ;
132 Standard_Real knot_array[2] ;
133 Standard_Integer mults_array[2] ;
134 knot_array[0] = 0.0e0 ;
135 knot_array[1] = 1.0e0 ;
136 mults_array[0] = degree + 1 ;
137 mults_array[1] = degree + 1 ;
139 TColStd_Array1OfReal the_knots(knot_array[0],1,2),
140 the_new_knots(knot_array[0],1,2);
141 TColStd_Array1OfInteger the_mults(mults_array[0],1,2),
142 the_new_mults(mults_array[0],1,2) ;
144 BSplCLib::Trimming(degree,
149 BSplCLib::NoWeights(),
155 BSplCLib::NoWeights());
157 // readjustment is obviously redundant
158 Standard_Real SinD = Sin(Delta), CosD = Cos(Delta);
159 gp_Pnt2d Pdeb(1., 0.);
160 gp_Pnt2d Pfin(CosD, SinD);
162 Standard_Real dtg = NewTPoles(1).Distance(NewTPoles(2));
165 Pdeb.ChangeCoord() += theXY;
168 // readjustment to Euclid
169 dtg = NewTPoles(num_poles).Distance(NewTPoles(num_poles-1));
170 NewTPoles(num_poles) = Pfin;
171 theXY.SetCoord(dtg*SinD,-dtg*CosD);
172 Pfin.ChangeCoord() += theXY;
173 NewTPoles(num_poles-1) = Pfin;
175 // Rotation to return to the arc [LocUFirst, LocUFirst+Delta]
176 T.SetRotation(gp::Origin2d(), locUFirst);
177 for (ii=1; ii<=num_poles; ii++) {
178 NewTPoles(ii).Transform(T);
181 for (ii=1; ii<=num_poles; ii++) {
182 CosNumeratorPtr->SetValue(ii,NewTPoles(ii).X());
183 SinNumeratorPtr->SetValue(ii,NewTPoles(ii).Y());
184 DenominatorPtr->SetValue(ii,1.);
189 void BuildHermitePolynomialCosAndSin
190 (const Standard_Real UFirst,
191 const Standard_Real ULast,
192 const Standard_Integer num_poles,
193 Handle(TColStd_HArray1OfReal)& CosNumeratorPtr,
194 Handle(TColStd_HArray1OfReal)& SinNumeratorPtr,
195 Handle(TColStd_HArray1OfReal)& DenominatorPtr)
198 if (num_poles%2 != 0) {
199 Standard_ConstructionError::Raise();
202 Standard_Integer ordre_deriv = num_poles/2;
203 Standard_Real ang = ULast - UFirst;
204 Standard_Real Cd = Cos(UFirst);
205 Standard_Real Sd = Sin(UFirst);
206 Standard_Real Cf = Cos(ULast);
207 Standard_Real Sf = Sin(ULast);
209 Standard_Integer Degree = num_poles-1;
210 TColStd_Array1OfReal FlatKnots(1,2*num_poles);
211 TColStd_Array1OfReal Parameters(1,num_poles);
212 TColStd_Array1OfInteger ContactOrderArray(1,num_poles);
213 TColgp_Array1OfPnt2d Poles(1,num_poles);
214 TColgp_Array1OfPnt2d TPoles(1,num_poles);
217 for (ii=1; ii<=num_poles; ii++) {
219 FlatKnots(ii+num_poles) = 1.;
222 Standard_Real coef = 1.;
223 Standard_Real xd,yd,xf,yf;
225 for (ii=1; ii<=ordre_deriv; ii++) {
227 Parameters(ii+ordre_deriv) = 1.;
229 ContactOrderArray(ii) = ContactOrderArray(num_poles-ii+1) = ii-1;
268 Poles(num_poles-ii+1).SetX(xf);
269 Poles(num_poles-ii+1).SetY(yf);
274 Standard_Integer InversionPb;
275 BSplCLib::Interpolate(Degree,FlatKnots,Parameters,
276 ContactOrderArray,Poles,InversionPb);
278 if (InversionPb !=0) {
279 Standard_ConstructionError::Raise();
281 for (ii=1; ii<=num_poles; ii++) {
282 CosNumeratorPtr->SetValue(ii,Poles(ii).X());
283 SinNumeratorPtr->SetValue(ii,Poles(ii).Y());
284 DenominatorPtr->SetValue(ii,1.);