// Created on: 1992-06-29 // Created by: Laurent BUCHARD // Copyright (c) 1992-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #ifndef OCCT_DEBUG #define No_Standard_RangeError #define No_Standard_OutOfRange #endif //====================================================================== //== I n t e r s e c t i o n C O N E Q U A D R I Q U E //== C Y L I N D R E Q U A D R I Q U E //====================================================================== #include #include #include #include #include #include #include #include #include #include #include #include #include //======================================================================= //function : AddSpecialPoints //purpose : Sometimes the boundaries theTheta1 and theTheta2 are // computed with some inaccuracy. At that, some special points // (cone apex or sphere pole(s)), which are true intersection // points lie out of the domain [theTheta1, theTheta2] of the ALine. // This function corrects these boundaries to make them be included // in the domain of the ALine. // Parameters Theta1 and Theta2 must be initialized // before calling this function. //======================================================================= template static void AddSpecialPoints(const IntAna_Quadric& theQuad, const gpSmth& theGpObj, Standard_Real& theTheta1, Standard_Real& theTheta2) { const Standard_Real aPeriod = M_PI + M_PI; const NCollection_List &aLSP = theQuad.SpecialPoints(); if (aLSP.IsEmpty()) return; Standard_Real aU = 0.0, aV = 0.0; Standard_Real aMaxDelta = 0.0; for (NCollection_List::Iterator anItr(aLSP); anItr.More(); anItr.Next()) { const gp_Pnt &aPt = anItr.Value(); ElSLib::Parameters(theGpObj, aPt, aU, aV); const gp_Pnt aPProj(ElSLib::Value(aU, aV, theGpObj)); if (aPt.SquareDistance(aPProj) > Precision::SquareConfusion()) { // aPt is not an intersection point continue; } Standard_Real aDelta1 = Min(aU - theTheta1, 0.0), aDelta2 = Max(aU - theTheta2, 0.0); if (aDelta1 < -M_PI) { // Must be aDelta1 = Min(aU - theTheta1 + aPeriod, 0.0). // But aU - theTheta1 + aPeriod >= 0 always. aDelta1 = 0.0; } if (aDelta2 > M_PI) { // Must be aDelta2 = Max(aU - theTheta2 - aPeriod, 0.0). // But aU - theTheta2 - aPeriod <= 0 always. aDelta2 = 0.0; } const Standard_Real aDelta = Max(-aDelta1, aDelta2); aMaxDelta = Max(aMaxDelta, aDelta); } if(aMaxDelta != 0.0) { theTheta1 -= aMaxDelta; theTheta2 += aMaxDelta; if ((theTheta2 - theTheta1) > aPeriod) { theTheta2 = theTheta1 + aPeriod; } } } //======================================================================= //class : TrigonometricRoots //purpose: Classe Interne (Donne des racines classees d un polynome trigo) //====================================================================== class TrigonometricRoots { private: Standard_Real Roots[4]; Standard_Boolean done; Standard_Integer NbRoots; Standard_Boolean infinite_roots; public: TrigonometricRoots(const Standard_Real CC, const Standard_Real SC, const Standard_Real C, const Standard_Real S, const Standard_Real Cte, const Standard_Real Binf, const Standard_Real Bsup); //IsDone Standard_Boolean IsDone() { return done; } //IsARoot Standard_Boolean IsARoot(Standard_Real u) { Standard_Integer i; Standard_Real aEps=RealEpsilon(); Standard_Real PIpPI = M_PI + M_PI; // for(i=0 ; iNbRoots)) { throw StdFail_NotDone(); } return Roots[n-1]; } }; //======================================================================= //function : TrigonometricRoots::TrigonometricRoots //purpose : //======================================================================= TrigonometricRoots::TrigonometricRoots(const Standard_Real CC, const Standard_Real SC, const Standard_Real C, const Standard_Real S, const Standard_Real Cte, const Standard_Real Binf, const Standard_Real Bsup) { Standard_Integer i, j, SvNbRoots; Standard_Boolean Triee; Standard_Real PIpPI = M_PI + M_PI; // done=Standard_False; // //-- F= AA*CN*CN+2*BB*CN*SN+CC*CN+DD*SN+EE; math_TrigonometricFunctionRoots MTFR(CC, SC, C, S, Cte, Binf, Bsup); if(!MTFR.IsDone()) { return; } // done=Standard_True; if(MTFR.InfiniteRoots()) { infinite_roots=Standard_True; return; } // NbRoots=MTFR.NbSolutions(); // for(i=0; iPIpPI) { Roots[i]-=PIpPI; } } // //-- La recherche directe donne n importe quoi. SvNbRoots=NbRoots; for(i=0; i1e-8) { done=Standard_False; return; //-- le 1er avril 98 } } // do { Triee=Standard_True; for(i=1,j=0; i Ax2 //---------------------------------------------------------------------- Quad.NewCoefficients(Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,Cyl.Position()); //---------------------------------------------------------------------- //-- Parametrage du Cylindre Cyl : //-- X = Rcyl * Cos(Theta) //-- Y = Rcyl * Sin(Theta) //-- Z = Z //---------------------------------------------------------------------- //-- Donne une Equation de la forme : //-- F(Sin(Theta),Cos(Theta),ZCyl) = 0 //-- (Equation du second degre en ZCyl) //-- ZCyl**2 CoeffZ2(Theta) + ZCyl CoeffZ1(Theta) + CoeffZ0(Theta) //---------------------------------------------------------------------- //-- CoeffZ0 = Q1 + 2*Qx*RCyl*Cos[Theta] + Qxx*RCyl^2*Cos[Theta]^2 //-- 2*RCyl*Sin[Theta]* ( Qy + Qxy*RCyl*Cos[Theta]); //-- Qyy*RCyl^2*Sin[Theta]^2; //-- CoeffZ1 =2.0 * ( Qz + RCyl*(Qxz*Cos[Theta] + Sin[Theta]*Qyz)) ; //-- CoeffZ2 = Qzz; //-- !!!! Attention , si on norme sur Qzz pour detecter le cas 1er degre //---------------------------------------------------------------------- //-- On Cherche Les Racines en Theta du discriminant de cette equation : //-- DIS(Theta) = C_1 + C_SS Sin()**2 + C_CC Cos()**2 + 2 C_SC Sin() Cos() //-- + 2 C_S Sin() + 2 C_C Cos() //-- //-- Si Qzz = 0 Alors On Resout Z=Fct(Theta) sur le domaine de Theta //---------------------------------------------------------------------- if(Abs(Qzz) 2 Courbes //-- Sinon ---> Pas de solution //-------------------------------------------------------------- if(MTF.Value(M_PI) >= -aRealEpsilon) { TheCurve[0].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon,0.0,PIpPI, UN_SEUL_Z_PAR_THETA, Z_POSITIF); TheCurve[1].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon,0.0,PIpPI, UN_SEUL_Z_PAR_THETA, Z_NEGATIF); NbCurves=2; } else { //------------------------------------------------------------ //-- Le Discriminant est toujours Negatif //------------------------------------------------------------ NbCurves=0; } } else { //#2 //------------------------------------------------------------ //-- Le Discriminant a des racines //-- (Le Discriminant est une fonction periodique donc ... ) //------------------------------------------------------------ if( nbsolDIS==1 ) { //------------------------------------------------------------ //-- Point de Tangence pour ce Theta Solution //-- Si Signe de Discriminant >=0 pour tout Theta //-- Alors //-- Courbe Solution pour la partie Positive //-- entre les 2 racines ( Ici Tout le domaine ) //-- Sinon Seulement un point Tangent //------------------------------------------------------------ if(MTF.Value(PolDIS.Value(1)+M_PI) >= -aRealEpsilon ) { //------------------------------------------------------------ //-- On a Un Point de Tangence + Une Courbe Solution //------------------------------------------------------------ TheCurve[0].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon,0.0,PIpPI, UN_SEUL_Z_PAR_THETA, Z_POSITIF); TheCurve[1].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon,0.0,PIpPI, UN_SEUL_Z_PAR_THETA, Z_NEGATIF); NbCurves=2; } else { //------------------------------------------------------------ //-- On a simplement un Point de tangence //------------------------------------------------------------ //--Standard_Real Theta = PolDIS(1); //--Standard_Real SecPar= -0.5 * MTFZ1.Value(Theta) / MTFZ2.Value(Theta); //--Thepoints[Nbpoints] = ElSLib::CylinderValue(Theta,SecPar,Cyl.Position(),Cyl.Radius()); //--Nbpoints++; NbCurves=0; } } else { // #3 //------------------------------------------------------------ //-- On detecte : Les racines double //-- : Les Zones Positives [Modulo 2 PI] //-- Les Courbes solutions seront obtenues pour les valeurs //-- de Theta ou Discriminant(Theta) > 0 (>=0? en limite) //-- Par la resolution de l equation implicite avec Theta fixe //------------------------------------------------------------ //-- Si tout est solution, Alors on est sur une iso //-- Ce cas devrait etre traite en amont //------------------------------------------------------------ //-- On construit la fonction permettant connaissant un Theta //-- de calculer les Z+ et Z- Correspondants. //------------------------------------------------------------- //------------------------------------------------------------- //-- Calcul des Intervalles ou Discriminant >=0 //-- On a au plus nbsol intervalles ( en fait 2 ) //-- (1,2) (2,3) .. (nbsol,1+2PI) //------------------------------------------------------------- Standard_Integer i; Standard_Real Theta1, Theta2, Theta3, autrepar, qwet; Standard_Boolean UnPtTg = Standard_False; // NbCurves=0; if(nbsolDIS == 2) { for(i=1; i<=nbsolDIS ; i++) { Theta1=PolDIS.Value(i); Theta2=(i=0.) { Standard_Real aParam = Theta1 + PIpPI; AddSpecialPoints(Quad, Cyl, Theta1, aParam); TheCurve[NbCurves].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon,Theta1,aParam, UN_SEUL_Z_PAR_THETA, Z_POSITIF); NbCurves++; TheCurve[NbCurves].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon,Theta1,aParam, UN_SEUL_Z_PAR_THETA, Z_NEGATIF); NbCurves++; } } } } for(i=1; UnPtTg == (Standard_False) && (i<=nbsolDIS) ; i++) { Theta1=PolDIS.Value(i); Theta2=(i Pol // // The function D(t) is just a formula that has sense for quadratic // equation above. // For cases when A(t)=0 (say at t=ti, t=tj. etc) the equation // will be // // f(z,t)=B(t)*z + C(t)=0, where B(t)!=0, // // and the D(t) is nonsense for it. // C_1 = TgAngle*TgAngle * ( Qz * Qz - Qzz * Q1); C_SS = Qy * Qy - Qyy * Q1; C_CC = Qx * Qx - Qxx * Q1; C_S = TgAngle*( Qy * Qz - Qyz * Q1); C_C = TgAngle*( Qx * Qz - Qxz * Q1); C_SC = Qx * Qy - Qxy * Q1; // TrigonometricRoots Pol(C_CC-C_SS, C_SC, C_C+C_C,C_S+C_S, C_1+C_SS,0.,PIpPI); if(!Pol.IsDone()) { done=!done; return; } // nbsol=Pol.NbSolutions(); MyTrigonometricFunction MTF(C_CC,C_SS,C_SC,C_C,C_S,C_1); // if(Pol.InfiniteRoots()) { // 2 // f(z,t)= (z(t)-zo(t)) = 0 Discriminant(t)=0 pour tout t // TheCurve[0].SetConeQuadValues(Cone,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon, 0.,PIpPI, UN_SEUL_Z_PAR_THETA, Z_POSITIF); TheCurve[1].SetConeQuadValues(Cone,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon, 0.,PIpPI, UN_SEUL_Z_PAR_THETA, Z_NEGATIF); NbCurves=2; return; } //else {//#4 // 2 // f(z,t)=A(t)*z + B(t)*z + C(t) Discriminant(t) != 0 // if(!nbsol && (MTF.Value(M_PI)<0.) ) { //-- Discriminant signe constant negatif return; } //else {//# 3 // //-- On Traite le cas : Discriminant(t) > 0 pour tout t en simulant 1 // racine double en 0 Standard_Boolean DiscriminantConstantPositif = Standard_False; if(!nbsol) { nbsol=1; DiscriminantConstantPositif = Standard_True; } //---------------------------------------------------------------------- //-- Le discriminant admet au moins une racine ( -> Point de Tangence ) //-- ou est constant positif. //---------------------------------------------------------------------- for(i=1; i<=nbsol; ++i) { if(DiscriminantConstantPositif) { Theta1 = 0.; Theta2 = PIpPI-myEpsilon; } else { Theta1=Pol.Value(i); Theta2=(iTheta2 //-- en Theta1-->t1 t1--->t2 ... tn--->Theta2 //-- ou t1,t2,...tn sont des racines de A(t) //-- //-- Seule la courbe Z_NEGATIF est affectee //---------------------------------------------------------------------- Standard_Boolean RacinesdePolZ2DansTheta1Theta2; Standard_Integer i2; Standard_Real r; // //nbsolZ2=PolZ2.NbSolutions(); RacinesdePolZ2DansTheta1Theta2=Standard_False; for(i2=1; i2<=nbsolZ2 && !RacinesdePolZ2DansTheta1Theta2; ++i2) { r=PolZ2.Value(i2); if(r>Theta1 && rTheta1 && rnbsolZ2) { to=PolZ2.Value(i2-nbsolZ2) + PIpPI; } else { to=PolZ2.Value(i2); } // // to is value of the parameter t where A(t)=0, i.e. // f(z,to)=B(to)*z + C(to)=0, B(to)!=0. // // z=-C(to)/B(to) is one and only // solution inspite of the fact that D(t)>0 for any value of t. // if(toNewMin) { //----------------------------------------------------------------- //-- On coupe au moins une fois le domaine Theta1 Theta2 //----------------------------------------------------------------- NoChanges=Standard_False; TheCurve[NbCurves].SetConeQuadValues(Cone,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon, NewMin,to, UN_SEUL_Z_PAR_THETA, Z_NEGATIF); // NbCurves++; TheCurve[NbCurves].SetConeQuadValues(Cone,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon, NewMin,to, UN_SEUL_Z_PAR_THETA, Z_POSITIF); //------------------------------------------------------------ //-- A == 0 //-- Si B < 0 Alors Infini sur Z+ //-- Sinon Infini sur Z- //------------------------------------------------------------ if(PolZ2.IsARoot(NewMin)) { if(MTFZ1.Value(NewMin) < 0.) { TheCurve[NbCurves].SetIsFirstOpen(Standard_True); } else { TheCurve[NbCurves-1].SetIsFirstOpen(Standard_True); } } if(MTFZ1.Value(to) < 0.) { TheCurve[NbCurves].SetIsLastOpen(Standard_True); } else { TheCurve[NbCurves-1].SetIsLastOpen(Standard_True); } //------------------------------------------------------------ NbCurves++; NewMin=to; }//if(toNewMin) }// for(i2=1; i2<= (nbsolZ2+nbsolZ2) ; ++i2) // if(NoChanges) { TheCurve[NbCurves].SetConeQuadValues(Cone,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon, Theta1,Theta2, UN_SEUL_Z_PAR_THETA, Z_NEGATIF); NbCurves++; TheCurve[NbCurves].SetConeQuadValues(Cone,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon, Theta1,Theta2, UN_SEUL_Z_PAR_THETA, Z_POSITIF); //------------------------------------------------------------ //-- A == 0 //-- Si B < 0 Alors Infini sur Z+ //-- Sinon Infini sur Z- //------------------------------------------------------------ if(PolZ2.IsARoot(Theta1)) { if(MTFZ1.Value(Theta1) < 0.) { TheCurve[NbCurves].SetIsFirstOpen(Standard_True); } else { TheCurve[NbCurves-1].SetIsFirstOpen(Standard_True); } } if(PolZ2.IsARoot(Theta2)) { if(MTFZ1.Value(Theta2) < 0.) { TheCurve[NbCurves].SetIsLastOpen(Standard_True); } else { TheCurve[NbCurves-1].SetIsLastOpen(Standard_True); } } //------------------------------------------------------------ NbCurves++; }//if(NoChanges) { else {// #0 TheCurve[NbCurves].SetConeQuadValues(Cone,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon, NewMin,Theta2, UN_SEUL_Z_PAR_THETA, Z_NEGATIF); NbCurves++; TheCurve[NbCurves].SetConeQuadValues(Cone,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, myEpsilon, NewMin,Theta2, UN_SEUL_Z_PAR_THETA, Z_POSITIF); //------------------------------------------------------------ //-- A == 0 //-- Si B < 0 Alors Infini sur Z+ //-- Sinon Infini sur Z- //------------------------------------------------------------ if(PolZ2.IsARoot(NewMin)) { if(MTFZ1.Value(NewMin) < 0.) { TheCurve[NbCurves].SetIsFirstOpen(Standard_True); } else { TheCurve[NbCurves-1].SetIsFirstOpen(Standard_True); } } if(PolZ2.IsARoot(Theta2)) { if(MTFZ1.Value(Theta2) < 0.) { TheCurve[NbCurves].SetIsLastOpen(Standard_True); } else { TheCurve[NbCurves-1].SetIsLastOpen(Standard_True); } } //------------------------------------------------------------ NbCurves++; }//else {// #0 }//else { //#1 }//for(i=1; i<=nbsol ; i++) { //}//else { //#5 InternalSetNextAndPrevious(); } //======================================================================= //function :InternalSetNextAndPrevious //purpose : //-- Raccordement des courbes bout a bout //-- - Utilisation du champ : IsFirstOpen //-- - IsLastOpen //-- Pas de verification si ces champs retournent Vrai. //-- //-- //-- 1: Test de Fin(C1) = Debut(C2) ->N(C1) et P(C2) //-- 2: Debut(C1) = Fin(C2) ->P(C1) et N(C2) //======================================================================= void IntAna_IntQuadQuad::InternalSetNextAndPrevious() { Standard_Boolean NotLastOpenC2, NotFirstOpenC2; Standard_Integer c1,c2; Standard_Real aEps, aEPSILON_DISTANCE; Standard_Real DInfC1,DSupC1, DInfC2,DSupC2; // aEps=0.0000001; aEPSILON_DISTANCE=0.0000000001; // for(c1=0; c1NbCurves)||(I<=0)) { throw Standard_OutOfRange("Incorrect Curve Number 'HasPrevious Curve'"); } if(previouscurve[I-1]) { return Standard_True; } return Standard_False; } //======================================================================= //function :HasNextCurve //purpose : //======================================================================= Standard_Boolean IntAna_IntQuadQuad::HasNextCurve(const Standard_Integer I) const { if(!done) { throw StdFail_NotDone("IntQuadQuad Not done"); } if (identical) { throw Standard_DomainError("IntQuadQuad identical"); } if((I>NbCurves)||(I<=0)) { throw Standard_OutOfRange("Incorrect Curve Number 'HasNextCurve'"); } if(nextcurve[I-1]) { return Standard_True; } return(Standard_False); } //======================================================================= //function :PreviousCurve //purpose : //======================================================================= Standard_Integer IntAna_IntQuadQuad::PreviousCurve (const Standard_Integer I, Standard_Boolean& theOpposite) const { if(HasPreviousCurve(I)) { if(previouscurve[I-1]>0) { theOpposite = Standard_False; return(previouscurve[I-1]); } else { theOpposite = Standard_True; return( - previouscurve[I-1]); } } else { throw Standard_DomainError("Incorrect Curve Number 'PreviousCurve'"); } } //======================================================================= //function :NextCurve //purpose : //======================================================================= Standard_Integer IntAna_IntQuadQuad::NextCurve (const Standard_Integer I, Standard_Boolean& theOpposite) const { if(HasNextCurve(I)) { if(nextcurve[I]>0) { theOpposite = Standard_False; return(nextcurve[I-1]); } else { theOpposite = Standard_True; return( - nextcurve[I-1]); } } else { throw Standard_DomainError("Incorrect Curve Number 'NextCurve'"); } } //======================================================================= //function :Curve //purpose : //======================================================================= const IntAna_Curve& IntAna_IntQuadQuad::Curve(const Standard_Integer i) const { if(!done) { throw StdFail_NotDone("IntQuadQuad Not done"); } if (identical) { throw Standard_DomainError("IntQuadQuad identical"); } if((i <= 0) || (i>NbCurves)) { throw Standard_OutOfRange("Incorrect Curve Number"); } return TheCurve[i-1]; } //======================================================================= //function :Point //purpose : //======================================================================= const gp_Pnt& IntAna_IntQuadQuad::Point (const Standard_Integer i) const { if(!done) { throw StdFail_NotDone("IntQuadQuad Not done"); } if (identical) { throw Standard_DomainError("IntQuadQuad identical"); } if((i <= 0) || (i>Nbpoints)) { throw Standard_OutOfRange("Incorrect Point Number"); } return Thepoints[i-1]; } //======================================================================= //function :Parameters //purpose : //======================================================================= void IntAna_IntQuadQuad::Parameters (const Standard_Integer, //i, Standard_Real& , Standard_Real& ) const { cout << "IntAna_IntQuadQuad::Parameters(...) is not yet implemented" << endl; } /********************************************************************************* Mathematica Pour Cone Quadrique In[6]:= y[r_,t_]:=r*Sin[t] In[7]:= x[r_,t_]:=r*Cos[t] In[8]:= z[r_,t_]:=r*d In[14]:= Quad[x_,y_,z_]:=Qxx x x + Qyy y y + Qzz z z + 2 (Qxy x y + Qxz x z + Qyz y z + Qx x + Qy y + Qz z ) + Q1 In[15]:= Quad[x[r,t],y[r,t],z[r,t]] 2 2 2 2 2 2 Out[15]= Q1 + d Qzz r + Qxx r Cos[t] + Qyy r Sin[t] + 2 > 2 (d Qz r + Qx r Cos[t] + d Qxz r Cos[t] + Qy r Sin[t] + 2 2 > d Qyz r Sin[t] + Qxy r Cos[t] Sin[t]) In[16]:= QQ=% In[17]:= Collect[QQ,r] Collect[QQ,r] Out[17]= Q1 + r (2 d Qz + 2 Qx Cos[t] + 2 Qy Sin[t]) + 2 2 2 > r (d Qzz + 2 d Qxz Cos[t] + Qxx Cos[t] + 2 d Qyz Sin[t] + 2 > 2 Qxy Cos[t] Sin[t] + Qyy Sin[t] ) ********************************************************************************/ //********************************************************************** //*** C O N E - Q U A D R I Q U E *** //*** 2 2 2 *** //*** R ( d Qzz + 2 d Qxz Cos[t] + Qxx Cos[t] + 2 d Qyz Sin[t] + *** //*** *** //*** 2 Qxy Cos[t] Sin[t] + Qyy Sin[t] ) *** //*** *** //*** + R ( 2 d Qz + 2 Qx Cos[t] + 2 Qy Sin[t] ) *** //*** *** //*** + Q1 *** //********************************************************************** //FortranForm= ( DIS = QQ1 QQ1 - 4 QQ0 QQ2 ) / 4 // - d**2*Qz**2 - d**2*Qzz*Q1 + (Qx**2 - Qxx*Q1)*Cos(t)**2 + // - (2*d*Qy*Qz - 2*d*Qyz*Q1)*Sin(t) + (Qy**2 - Qyy*Q1)*Sin(t)**2 + // - Cos(t)*(2*d*Qx*Qz - 2*d*Qxz*Q1 + (2*Qx*Qy - 2*Qxy*Q1)*Sin(t)) //********************************************************************** //modified by NIZNHY-PKV Fri Dec 2 10:56:03 2005f /* static void DumpCurve(const Standard_Integer aIndex, IntAna_Curve& aC); //======================================================================= //function : DumpCurve //purpose : //======================================================================= void DumpCurve(const Standard_Integer aIndex, IntAna_Curve& aC) { Standard_Boolean bIsOpen, bIsConstant, bIsFirstOpen, bIsLastOpen; Standard_Integer i, aNb; Standard_Real aT1, aT2, aT, dT; gp_Pnt aP; // aC.Domain(aT1, aT2); bIsOpen=aC.IsOpen(); bIsConstant=aC.IsConstant(); bIsFirstOpen=aC.IsFirstOpen(); bIsLastOpen=aC.IsLastOpen(); // printf("\n"); printf(" * IntAna_Curve #%d*\n", aIndex); printf(" Domain: [ %lf, %lf ]\n", aT1, aT2); printf(" IsOpen=%d\n", bIsOpen); printf(" IsConstant=%d\n", bIsConstant); printf(" IsFirstOpen =%d\n", bIsFirstOpen); printf(" IsLastOpen =%d\n", bIsLastOpen); // aNb=11; dT=(aT2-aT1)/(aNb-1); for (i=0; i