1 // Created on: 1995-10-10
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-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.
17 #include <Convert_PolynomialCosAndSin.hxx>
19 #include <TColgp_Array1OfPnt2d.hxx>
20 #include <gp_Trsf2d.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <gp_Vec2d.hxx>
26 #include <Precision.hxx>
28 #include <BSplCLib.hxx>
30 #include <Standard_ConstructionError.hxx>
32 static Standard_Real Locate(const Standard_Real Angfin,
33 const TColgp_Array1OfPnt2d& TPoles,
34 const Standard_Real Umin,
35 const Standard_Real Umax)
37 Standard_Real umin = Umin;
38 Standard_Real umax = Umax;
39 Standard_Real Ptol = Precision::Angular();
40 Standard_Real Utol = Precision::PConfusion();
41 while (Abs(umax-umin)>= Utol) {
42 Standard_Real ptest = (umax+umin)/2.;
44 BSplCLib::D0(ptest,TPoles,BSplCLib::NoWeights(),valP);
45 Standard_Real theta = ATan2(valP.Y(),valP.X());
49 if (Abs(theta - Angfin) < Ptol) {
55 else if (theta > Angfin) {
59 return (umin+umax)/2.;
63 void BuildPolynomialCosAndSin
64 (const Standard_Real UFirst,
65 const Standard_Real ULast,
66 const Standard_Integer num_poles,
67 Handle(TColStd_HArray1OfReal)& CosNumeratorPtr,
68 Handle(TColStd_HArray1OfReal)& SinNumeratorPtr,
69 Handle(TColStd_HArray1OfReal)& DenominatorPtr)
83 Standard_Integer ii, degree = num_poles -1 ;
86 // Return UFirst in [-2PI; 2PI]
87 // to make rotations without risk
88 while (locUFirst > PI2) {
91 while (locUFirst < - PI2) {
95 // Return to the arc [0, Delta]
96 Delta = ULast - UFirst;
97 middle = 0.5e0 * Delta ;
99 // coincide the required bisector of the angular sector with
100 // axis -Ox definition of the circle in Bezier of degree 7 so that
101 // parametre 1/2 of Bezier was exactly a point of the bissectrice
102 // of the required angular sector.
104 Angle = middle - M_PI ;
106 // Circle of radius 1. See Euclid
109 TColgp_Array1OfPnt2d TPoles(1,8),
111 TPoles(1).SetCoord(1.,0.);
112 TPoles(2).SetCoord(1.,1.013854);
113 TPoles(3).SetCoord(-0.199043,1.871905);
114 TPoles(4).SetCoord(-1.937729,1.057323);
115 TPoles(5).SetCoord(-1.937729,-1.057323);
116 TPoles(6).SetCoord(-0.199043,-1.871905);
117 TPoles(7).SetCoord(1.,-1.013854);
118 TPoles(8).SetCoord(1.,0.);
120 T.SetRotation(gp::Origin2d(),Angle);
121 for (ii=1; ii<=num_poles; ii++) {
122 TPoles(ii).Transform(T);
126 t_min = 1.0e0 - (Delta * 1.3e0 / M_PI) ;
128 t_min = Max(t_min,0.0e0) ;
129 t_max = 1.0e0 + (Delta * 1.3e0 / M_PI) ;
131 t_max = Min(t_max,1.0e0) ;
132 trim_max = Locate(Delta,
137 // as Bezier is symmetric correspondingly to the bissector
138 // of the angular sector ...
140 trim_min = 1.0e0 - trim_max ;
142 Standard_Real knot_array[2] ;
143 Standard_Integer mults_array[2] ;
144 knot_array[0] = 0.0e0 ;
145 knot_array[1] = 1.0e0 ;
146 mults_array[0] = degree + 1 ;
147 mults_array[1] = degree + 1 ;
149 TColStd_Array1OfReal the_knots(knot_array[0],1,2),
150 the_new_knots(knot_array[0],1,2);
151 TColStd_Array1OfInteger the_mults(mults_array[0],1,2),
152 the_new_mults(mults_array[0],1,2) ;
154 BSplCLib::Trimming(degree,
159 BSplCLib::NoWeights(),
165 BSplCLib::NoWeights());
167 // readjustment is obviously redundant
168 Standard_Real SinD = Sin(Delta), CosD = Cos(Delta);
169 gp_Pnt2d Pdeb(1., 0.);
170 gp_Pnt2d Pfin(CosD, SinD);
172 Standard_Real dtg = NewTPoles(1).Distance(NewTPoles(2));
175 Pdeb.ChangeCoord() += theXY;
178 // readjustment to Euclid
179 dtg = NewTPoles(num_poles).Distance(NewTPoles(num_poles-1));
180 NewTPoles(num_poles) = Pfin;
181 theXY.SetCoord(dtg*SinD,-dtg*CosD);
182 Pfin.ChangeCoord() += theXY;
183 NewTPoles(num_poles-1) = Pfin;
185 // Rotation to return to the arc [LocUFirst, LocUFirst+Delta]
186 T.SetRotation(gp::Origin2d(), locUFirst);
187 for (ii=1; ii<=num_poles; ii++) {
188 NewTPoles(ii).Transform(T);
191 for (ii=1; ii<=num_poles; ii++) {
192 CosNumeratorPtr->SetValue(ii,NewTPoles(ii).X());
193 SinNumeratorPtr->SetValue(ii,NewTPoles(ii).Y());
194 DenominatorPtr->SetValue(ii,1.);
199 void BuildHermitePolynomialCosAndSin
200 (const Standard_Real UFirst,
201 const Standard_Real ULast,
202 const Standard_Integer num_poles,
203 Handle(TColStd_HArray1OfReal)& CosNumeratorPtr,
204 Handle(TColStd_HArray1OfReal)& SinNumeratorPtr,
205 Handle(TColStd_HArray1OfReal)& DenominatorPtr)
208 if (num_poles%2 != 0) {
209 Standard_ConstructionError::Raise();
212 Standard_Integer ordre_deriv = num_poles/2;
213 Standard_Real ang = ULast - UFirst;
214 Standard_Real Cd = Cos(UFirst);
215 Standard_Real Sd = Sin(UFirst);
216 Standard_Real Cf = Cos(ULast);
217 Standard_Real Sf = Sin(ULast);
219 Standard_Integer Degree = num_poles-1;
220 TColStd_Array1OfReal FlatKnots(1,2*num_poles);
221 TColStd_Array1OfReal Parameters(1,num_poles);
222 TColStd_Array1OfInteger ContactOrderArray(1,num_poles);
223 TColgp_Array1OfPnt2d Poles(1,num_poles);
224 TColgp_Array1OfPnt2d TPoles(1,num_poles);
227 for (ii=1; ii<=num_poles; ii++) {
229 FlatKnots(ii+num_poles) = 1.;
232 Standard_Real coef = 1.;
233 Standard_Real xd,yd,xf,yf;
235 for (ii=1; ii<=ordre_deriv; ii++) {
237 Parameters(ii+ordre_deriv) = 1.;
239 ContactOrderArray(ii) = ContactOrderArray(num_poles-ii+1) = ii-1;
278 Poles(num_poles-ii+1).SetX(xf);
279 Poles(num_poles-ii+1).SetY(yf);
284 Standard_Integer InversionPb;
285 BSplCLib::Interpolate(Degree,FlatKnots,Parameters,
286 ContactOrderArray,Poles,InversionPb);
288 if (InversionPb !=0) {
289 Standard_ConstructionError::Raise();
291 for (ii=1; ii<=num_poles; ii++) {
292 CosNumeratorPtr->SetValue(ii,Poles(ii).X());
293 SinNumeratorPtr->SetValue(ii,Poles(ii).Y());
294 DenominatorPtr->SetValue(ii,1.);