// File: IntAna_Curve.cxx // Created: Tue Jun 30 10:40:07 1992 // Author: Laurent BUCHARD // #ifndef DEB #define No_Standard_RangeError #define No_Standard_OutOfRange #endif //---------------------------------------------------------------------- //-- Differents constructeurs sont proposes qui correspondent aux //-- polynomes en Z : //-- A(Sin(Theta),Cos(Theta)) Z**2 //-- + B(Sin(Theta),Cos(Theta)) Z //-- + C(Sin(Theta),Cos(Theta)) //-- //-- Une Courbe est definie sur un domaine //-- //-- Value retourne le point de parametre U(Theta),V(Theta) //-- ou V est la solution du polynome A V**2 + B V + C //-- (Selon les cas, on prend V+ ou V-) //-- //-- D1u calcule le vecteur tangent a la courbe //-- et retourne le booleen Standard_False si ce calcul ne peut //-- pas etre mene a bien. //---------------------------------------------------------------------- #include #include #include #include #include #include //======================================================================= //function : IntAna_Curve //purpose : //======================================================================= IntAna_Curve::IntAna_Curve() { typequadric=GeomAbs_OtherSurface; firstbounded=Standard_False; lastbounded=Standard_False; } //======================================================================= //function : SetConeQuadValues //purpose : Description de l intersection Cone Quadrique //======================================================================= void IntAna_Curve::SetConeQuadValues(const gp_Cone& Cone, const Standard_Real Qxx, const Standard_Real Qyy, const Standard_Real Qzz, const Standard_Real Qxy, const Standard_Real Qxz, const Standard_Real Qyz, const Standard_Real Qx, const Standard_Real Qy, const Standard_Real Qz, const Standard_Real Q1, const Standard_Real TOL, const Standard_Real DomInf, const Standard_Real DomSup, const Standard_Boolean twocurves, const Standard_Boolean takezpositive) { Ax3 = Cone.Position(); RCyl = Cone.RefRadius(); Angle = Cone.SemiAngle(); Standard_Real UnSurTgAngle = 1.0/(Tan(Cone.SemiAngle())); typequadric= GeomAbs_Cone; TwoCurves = twocurves; //-- deux Z pour un meme parametre TakeZPositive = takezpositive; //-- Prendre sur la courbe le Z Positif //-- ( -B + Sqrt()) et non (-B - Sqrt()) Z0Cte = Q1; //-- Attention On a Z?Cos Cos(t) Z0Sin = 0.0; //-- et Non 2 Z?Cos Cos(t) !!! Z0Cos = 0.0; //-- Ce pour tous les Parametres Z0CosCos = 0.0; //-- ie pas de Coefficient 2 Z0SinSin = 0.0; //-- devant les termes CS C S Z0CosSin = 0.0; Z1Cte = 2.0*(UnSurTgAngle)*Qz; Z1Sin = Qy+Qy; Z1Cos = Qx+Qx; Z1CosCos = 0.0; Z1SinSin = 0.0; Z1CosSin = 0.0; Z2Cte = Qzz * UnSurTgAngle*UnSurTgAngle; Z2Sin = (UnSurTgAngle+UnSurTgAngle)*Qyz; Z2Cos = (UnSurTgAngle+UnSurTgAngle)*Qxz; Z2CosCos = Qxx; Z2SinSin = Qyy; Z2CosSin = Qxy+Qxy; Tolerance = TOL; DomainInf = DomInf; DomainSup = DomSup; RestrictedInf = RestrictedSup = Standard_True; //-- Le Domaine est Borne firstbounded = lastbounded = Standard_False; } //======================================================================= //function : SetCylinderQuadValues //purpose : Description de l intersection Cylindre Quadrique //======================================================================= void IntAna_Curve::SetCylinderQuadValues(const gp_Cylinder& Cyl, const Standard_Real Qxx, const Standard_Real Qyy, const Standard_Real Qzz, const Standard_Real Qxy, const Standard_Real Qxz, const Standard_Real Qyz, const Standard_Real Qx, const Standard_Real Qy, const Standard_Real Qz, const Standard_Real Q1, const Standard_Real TOL, const Standard_Real DomInf, const Standard_Real DomSup, const Standard_Boolean twocurves, const Standard_Boolean takezpositive) { Ax3 = Cyl.Position(); RCyl = Cyl.Radius(); typequadric= GeomAbs_Cylinder; TwoCurves = twocurves; //-- deux Z pour un meme parametre TakeZPositive = takezpositive; //-- Prendre sur la courbe le Z Positif Standard_Real RCylmul2 = RCyl+RCyl; //-- ( -B + Sqrt()) Z0Cte = Q1; Z0Sin = RCylmul2*Qy; Z0Cos = RCylmul2*Qx; Z0CosCos = Qxx*RCyl*RCyl; Z0SinSin = Qyy*RCyl*RCyl; Z0CosSin = RCylmul2*RCyl*Qxy; Z1Cte = Qz+Qz; Z1Sin = RCylmul2*Qyz; Z1Cos = RCylmul2*Qxz; Z1CosCos = 0.0; Z1SinSin = 0.0; Z1CosSin = 0.0; Z2Cte = Qzz; Z2Sin = 0.0; Z2Cos = 0.0; Z2CosCos = 0.0; Z2SinSin = 0.0; Z2CosSin = 0.0; Tolerance = TOL; DomainInf = DomInf; DomainSup = DomSup; RestrictedInf = RestrictedSup = Standard_True; firstbounded = lastbounded = Standard_False; } //======================================================================= //function : IsOpen //purpose : //======================================================================= Standard_Boolean IntAna_Curve::IsOpen() const { return(RestrictedInf && RestrictedSup); } //======================================================================= //function : Domain //purpose : //======================================================================= void IntAna_Curve::Domain(Standard_Real& DInf, Standard_Real& DSup) const { if(RestrictedInf && RestrictedSup) { DInf=DomainInf; DSup=DomainSup; if(TwoCurves) { DSup+=DSup-DInf; } } else { Standard_DomainError::Raise("IntAna_Curve::Domain"); } } //======================================================================= //function : IsConstant //purpose : //======================================================================= Standard_Boolean IntAna_Curve::IsConstant() const { //-- ??? Pas facile de decider a la seule vue des Param. return(Standard_False); } //======================================================================= //function : IsFirstOpen //purpose : //======================================================================= Standard_Boolean IntAna_Curve::IsFirstOpen() const { return(firstbounded); } //======================================================================= //function : IsLastOpen //purpose : //======================================================================= Standard_Boolean IntAna_Curve::IsLastOpen() const { return(lastbounded); } //======================================================================= //function : SetIsFirstOpen //purpose : //======================================================================= void IntAna_Curve::SetIsFirstOpen(const Standard_Boolean Flag) { firstbounded = Flag; } //======================================================================= //function : SetIsLastOpen //purpose : //======================================================================= void IntAna_Curve::SetIsLastOpen(const Standard_Boolean Flag) { lastbounded = Flag; } //======================================================================= //function : InternalUVValue //purpose : //======================================================================= void IntAna_Curve::InternalUVValue(const Standard_Real theta, Standard_Real& Param1, Standard_Real& Param2, Standard_Real& A, Standard_Real& B, Standard_Real& C, Standard_Real& cost, Standard_Real& sint, Standard_Real& SigneSqrtDis) const { Standard_Real Theta=theta; Standard_Boolean SecondSolution=Standard_False; if((ThetaDomainSup) && (!TwoCurves)) || (Theta>(DomainSup+DomainSup-DomainInf+0.00000000000001))) { Standard_DomainError::Raise("IntAna_Curve::Domain"); } if(Theta>DomainSup) { Theta=DomainSup+DomainSup-Theta; SecondSolution=Standard_True; } Param1=Theta; if(!TwoCurves) { SecondSolution=TakeZPositive; } // cost = Cos(Theta); sint = Sin(Theta); Standard_Real costsint = cost*sint; A=Z2Cte+sint*(Z2Sin+sint*Z2SinSin)+cost*(Z2Cos+cost*Z2CosCos) +Z2CosSin*costsint; B=Z1Cte+sint*(Z1Sin+sint*Z1SinSin)+cost*(Z1Cos+cost*Z1CosCos) +Z1CosSin*costsint; C=Z0Cte+sint*(Z0Sin+sint*Z0SinSin)+cost*(Z0Cos+cost*Z0CosCos) +Z0CosSin*costsint; Standard_Real Discriminant = B*B-4.0*A*C; if(Abs(A)<=0.000000001) { //-- cout<<" IntAna_Curve:: Internal UV Value : A="< Abs(A)="<DomainSup) && (!TwoCurves)) || (theta2>(DomainSup+DomainSup-DomainInf+0.00000000000001))) { dtheta = -dtheta; theta2 = theta+dtheta; } gp_Pnt P2 = Value(theta2); dtheta = 1.0/dtheta; Vec.SetCoord((P2.X()-Pt.X())*dtheta, (P2.Y()-Pt.Y())*dtheta, (P2.Z()-Pt.Z())*dtheta); return(Standard_True); } //======================================================================= //function : FindParameter //purpose : Para est en sortie le parametre sur la courbe //======================================================================= Standard_Boolean IntAna_Curve::FindParameter (const gp_Pnt& P, Standard_Real& Para) const { Standard_Real theta = 0.0 ,z = 0.0, aTolPrecision=0.0001; Standard_Real PIpPI = Standard_PI+Standard_PI; // switch (typequadric) { case GeomAbs_Cylinder: { ElSLib::CylinderParameters(Ax3,RCyl,P,theta,z); } break; case GeomAbs_Cone : { ElSLib::ConeParameters(Ax3,RCyl,Angle,P,theta,z); } break; default: break; } // Standard_Real epsAng = 1.e-8; Standard_Real tmin = DomainInf; Standard_Real tmax = DomainSup; Standard_Real U,V,A,B,C,sint,cost,SigneSqrtDis; Standard_Real z1,z2; A=0.0; B=0.0; C=0.0; U=0.0; V=0.0; sint=0.0; cost=0.0; SigneSqrtDis=0.0; //U=V=A=B=C=sint=cost=SigneSqrtDis=0.0; // if (!firstbounded && tmin > theta && (tmin-theta) <= epsAng) { theta = tmin; } else if (!lastbounded && theta > tmax && (theta-tmax) <= epsAng) { theta = tmax; } // if (theta < tmin ) { theta = theta + PIpPI; } else if (theta > tmax) { theta = theta - PIpPI; } if (theta < tmin || theta > tmax) { if(theta>tmax) { InternalUVValue(tmax,U,V,A,B,C,cost,sint,SigneSqrtDis); gp_Pnt PMax(InternalValue(U,V)); if(PMax.Distance(P) < aTolPrecision) { Para = tmax; return(Standard_True); } } if(theta tmax) theta = tmax; if(theta < tmin) theta = tmin; InternalUVValue(theta,U,z1,A,B,C,cost,sint,SigneSqrtDis); A = B = C = sint = cost = SigneSqrtDis = 0.0; InternalUVValue(tmax+tmax - theta,U,z2,A,B,C,cost,sint,SigneSqrtDis); if (Abs(z-z1) <= Abs(z-z2)) { Para = theta; } else { Para = tmax+tmax - theta; } } else { Para = theta; } if((ParaDomainSup) && (!TwoCurves)) || (Para>(DomainSup+DomainSup-DomainInf+0.00000000000001))) { return(Standard_False); } InternalUVValue(Para,U,V,A,B,C,cost,sint,SigneSqrtDis); gp_Pnt PPara = InternalValue(U,V); Standard_Real Dist = PPara.Distance(P); if(Dist > aTolPrecision) { //-- Il y a eu un probleme //-- On teste si le point est un point double InternalUVValue(tmin,U,V,A,B,C,cost,sint,SigneSqrtDis); PPara = InternalValue(U,V); Dist = PPara.Distance(P); if(Dist <= aTolPrecision) { Para = tmin; return(Standard_True); } InternalUVValue(tmax,U,V,A,B,C,cost,sint,SigneSqrtDis); PPara = InternalValue(U,V); Dist = PPara.Distance(P); if(Dist <= aTolPrecision) { Para = tmax; return(Standard_True); } if (TwoCurves) { Standard_Real Theta = DomainSup+DomainSup-DomainInf; InternalUVValue(Theta,U,V,A,B,C,cost,sint,SigneSqrtDis); PPara = InternalValue(U,V); Dist = PPara.Distance(P); if(Dist <= aTolPrecision) { Para = Theta; return(Standard_True); } } return(Standard_False); } return(Standard_True); } //======================================================================= //function : InternalValue //purpose : //======================================================================= gp_Pnt IntAna_Curve::InternalValue(const Standard_Real U, const Standard_Real _V) const { //-- cout<<" ["< 100000.0 ) { V= 100000.0; } if(V < -100000.0 ) { V=-100000.0; } switch(typequadric) { case GeomAbs_Cone: { //------------------------------------------------ //-- Parametrage : X = V * Cos(U) --- //-- Y = V * Sin(U) --- //-- Z = (V-RCyl) / Tan(SemiAngle)-- //------------------------------------------------ //-- Angle Vaut Cone.SemiAngle() return(ElSLib::ConeValue(U,(V-RCyl)/Sin(Angle),Ax3,RCyl,Angle)); } break; case GeomAbs_Cylinder: return(ElSLib::CylinderValue(U,V,Ax3,RCyl)); case GeomAbs_Sphere: return(ElSLib::SphereValue(U,V,Ax3,RCyl)); default: break; } return(gp_Pnt(0.0,0.0,0.0)); } // //======================================================================= //function : SetDomain //purpose : //======================================================================= void IntAna_Curve::SetDomain(const Standard_Real DInf, const Standard_Real DSup) { if(DInf>=DSup) { Standard_DomainError::Raise("IntAna_Curve::Domain"); } // DomainInf=DInf; DomainSup=DSup; }