// File: Convert_PolynomialCosAndSin.cxx // Created: Tue Oct 10 15:56:28 1995 // Author: Jacques GOUSSARD // //PMN 4/12/1997 On se ramene toujours sur [0, Delta] pour eviter les cas tordus #include #include #include #include #include #include #include #include #include #include #include static Standard_Real Locate(const Standard_Real Angfin, const TColgp_Array1OfPnt2d& TPoles, const Standard_Real Umin, const Standard_Real Umax) { Standard_Real umin = Umin; Standard_Real umax = Umax; Standard_Real Ptol = Precision::Angular(); Standard_Real Utol = Precision::PConfusion(); while (Abs(umax-umin)>= Utol) { Standard_Real ptest = (umax+umin)/2.; gp_Pnt2d valP; BSplCLib::D0(ptest,TPoles,BSplCLib::NoWeights(),valP); Standard_Real theta = ATan2(valP.Y(),valP.X()); if (theta < 0.) { theta +=2.*PI; } if (Abs(theta - Angfin) < Ptol) { return ptest; } if (theta < Angfin) { umin = ptest; } else if (theta > Angfin) { umax = ptest; } } return (umin+umax)/2.; } void BuildPolynomialCosAndSin (const Standard_Real UFirst, const Standard_Real ULast, const Standard_Integer num_poles, Handle(TColStd_HArray1OfReal)& CosNumeratorPtr, Handle(TColStd_HArray1OfReal)& SinNumeratorPtr, Handle(TColStd_HArray1OfReal)& DenominatorPtr) { Standard_Real Delta, locUFirst, // locULast, // temp_value, t_min, t_max, trim_min, trim_max, middle, Angle, PI2 = 2*PI ; Standard_Integer ii, degree = num_poles -1 ; locUFirst = UFirst ; // On Rammene le UFirst dans [-2PI; 2PI] // afin de faire des rotation sans risque while (locUFirst > PI2) { locUFirst -= PI2; } while (locUFirst < - PI2) { locUFirst += PI2; } // on se ramene a l'arc [0, Delta] Delta = ULast - UFirst; middle = 0.5e0 * Delta ; // // on fait coincider la bisectrice du secteur angulaire que l on desire avec // l axe -Ox de definition du cercle en Bezier de degree 7 de sorte que le // parametre 1/2 de la Bezier soit exactement un point de la bissectrice du // secteur angulaire que l on veut. // Angle = middle - PI ; // // Cercle de rayon 1. Voir Euclid // TColgp_Array1OfPnt2d TPoles(1,8), NewTPoles(1,8) ; TPoles(1).SetCoord(1.,0.); TPoles(2).SetCoord(1.,1.013854); TPoles(3).SetCoord(-0.199043,1.871905); TPoles(4).SetCoord(-1.937729,1.057323); TPoles(5).SetCoord(-1.937729,-1.057323); TPoles(6).SetCoord(-0.199043,-1.871905); TPoles(7).SetCoord(1.,-1.013854); TPoles(8).SetCoord(1.,0.); gp_Trsf2d T; T.SetRotation(gp::Origin2d(),Angle); for (ii=1; ii<=num_poles; ii++) { TPoles(ii).Transform(T); } t_min = 1.0e0 - (Delta * 1.3e0 / PI) ; t_min *= 0.5e0 ; t_min = Max(t_min,0.0e0) ; t_max = 1.0e0 + (Delta * 1.3e0 / PI) ; t_max *= 0.5e0 ; t_max = Min(t_max,1.0e0) ; trim_max = Locate(Delta, TPoles, t_min, t_max); // // puisque la Bezier est symetrique par rapport a la bissectrice du // secteur angulaire ... trim_min = 1.0e0 - trim_max ; // Standard_Real knot_array[2] ; Standard_Integer mults_array[2] ; knot_array[0] = 0.0e0 ; knot_array[1] = 1.0e0 ; mults_array[0] = degree + 1 ; mults_array[1] = degree + 1 ; TColStd_Array1OfReal the_knots(knot_array[0],1,2), the_new_knots(knot_array[0],1,2); TColStd_Array1OfInteger the_mults(mults_array[0],1,2), the_new_mults(mults_array[0],1,2) ; BSplCLib::Trimming(degree, Standard_False, the_knots, the_mults, TPoles, BSplCLib::NoWeights(), trim_min, trim_max, the_new_knots, the_new_mults, NewTPoles, BSplCLib::NoWeights()); // recalage sans doute superflu Standard_Real SinD = Sin(Delta), CosD = Cos(Delta); gp_Pnt2d Pdeb(1., 0.); gp_Pnt2d Pfin(CosD, SinD); Standard_Real dtg = NewTPoles(1).Distance(NewTPoles(2)); NewTPoles(1) = Pdeb; gp_XY theXY(0.,dtg); Pdeb.ChangeCoord() += theXY; NewTPoles(2) = Pdeb; // Recalages a la Euclid dtg = NewTPoles(num_poles).Distance(NewTPoles(num_poles-1)); NewTPoles(num_poles) = Pfin; theXY.SetCoord(dtg*SinD,-dtg*CosD); Pfin.ChangeCoord() += theXY; NewTPoles(num_poles-1) = Pfin; // Rotation pour se ramener a l'arc [LocUFirst, LocUFirst+Delta] T.SetRotation(gp::Origin2d(), locUFirst); for (ii=1; ii<=num_poles; ii++) { NewTPoles(ii).Transform(T); } for (ii=1; ii<=num_poles; ii++) { CosNumeratorPtr->SetValue(ii,NewTPoles(ii).X()); SinNumeratorPtr->SetValue(ii,NewTPoles(ii).Y()); DenominatorPtr->SetValue(ii,1.); } } /* void BuildHermitePolynomialCosAndSin (const Standard_Real UFirst, const Standard_Real ULast, const Standard_Integer num_poles, Handle(TColStd_HArray1OfReal)& CosNumeratorPtr, Handle(TColStd_HArray1OfReal)& SinNumeratorPtr, Handle(TColStd_HArray1OfReal)& DenominatorPtr) { if (num_poles%2 != 0) { Standard_ConstructionError::Raise(); } Standard_Integer ii; Standard_Integer ordre_deriv = num_poles/2; Standard_Real ang = ULast - UFirst; Standard_Real Cd = Cos(UFirst); Standard_Real Sd = Sin(UFirst); Standard_Real Cf = Cos(ULast); Standard_Real Sf = Sin(ULast); Standard_Integer Degree = num_poles-1; TColStd_Array1OfReal FlatKnots(1,2*num_poles); TColStd_Array1OfReal Parameters(1,num_poles); TColStd_Array1OfInteger ContactOrderArray(1,num_poles); TColgp_Array1OfPnt2d Poles(1,num_poles); TColgp_Array1OfPnt2d TPoles(1,num_poles); for (ii=1; ii<=num_poles; ii++) { FlatKnots(ii) = 0.; FlatKnots(ii+num_poles) = 1.; } Standard_Real coef = 1.; Standard_Real xd,yd,xf,yf; for (ii=1; ii<=ordre_deriv; ii++) { Parameters(ii) = 0.; Parameters(ii+ordre_deriv) = 1.; ContactOrderArray(ii) = ContactOrderArray(num_poles-ii+1) = ii-1; switch ((ii-1)%4) { case 0: { xd = Cd*coef; yd = Sd*coef; xf = Cf*coef; yf = Sf*coef; } break; case 1: { xd = -Sd*coef; yd = Cd*coef; xf = -Sf*coef; yf = Cf*coef; } break; case 2: { xd = -Cd*coef; yd = -Sd*coef; xf = -Cf*coef; yf = -Sf*coef; } break; case 3: { xd = Sd*coef; yd = -Cd*coef; xf = Sf*coef; yf = -Cf*coef; } break; } Poles(ii).SetX(xd); Poles(ii).SetY(yd); Poles(num_poles-ii+1).SetX(xf); Poles(num_poles-ii+1).SetY(yf); coef *= ang; } Standard_Integer InversionPb; BSplCLib::Interpolate(Degree,FlatKnots,Parameters, ContactOrderArray,Poles,InversionPb); if (InversionPb !=0) { Standard_ConstructionError::Raise(); } for (ii=1; ii<=num_poles; ii++) { CosNumeratorPtr->SetValue(ii,Poles(ii).X()); SinNumeratorPtr->SetValue(ii,Poles(ii).Y()); DenominatorPtr->SetValue(ii,1.); } } */