1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-06 18:26:22 +03:00
occt/src/IntAna/IntAna_IntQuadQuad.cxx
mkrylova d533dafb56 0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
Added initialization of fields that had not initialization
Added default constructors to classes without constructors
2020-07-23 16:08:20 +03:00

1353 lines
43 KiB
C++

// 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 <stdio.h>
#include <Standard_Stream.hxx>
#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 <ElSLib.hxx>
#include <gp_Ax2.hxx>
#include <gp_Ax3.hxx>
#include <gp_Cone.hxx>
#include <gp_Cylinder.hxx>
#include <gp_Pnt.hxx>
#include <IntAna_Curve.hxx>
#include <IntAna_IntQuadQuad.hxx>
#include <IntAna_Quadric.hxx>
#include <math_TrigonometricFunctionRoots.hxx>
#include <Standard_DomainError.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
//=======================================================================
//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 <class gpSmth>
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<gp_Pnt> &aLSP = theQuad.SpecialPoints();
if (aLSP.IsEmpty())
return;
Standard_Real aU = 0.0, aV = 0.0;
Standard_Real aMaxDelta = 0.0;
for (NCollection_List<gp_Pnt>::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 ; i<NbRoots; ++i) {
if(Abs(u - Roots[i])<=aEps) {
return Standard_True;
}
if(Abs(u - Roots[i]-PIpPI)<=aEps) {
return Standard_True;
}
}
return Standard_False;
}
//NbSolutions
Standard_Integer NbSolutions() {
if(!done) {
throw StdFail_NotDone();
}
return NbRoots;
}
//InfiniteRoots
Standard_Boolean InfiniteRoots() {
if(!done) {
throw StdFail_NotDone();
}
return infinite_roots;
}
//Value
Standard_Real Value(const Standard_Integer n) {
if((!done)||(n>NbRoots)) {
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)
: infinite_roots(Standard_False)
{
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; i<NbRoots; ++i) {
Roots[i]=MTFR.Value(i+1);
if(Roots[i]<0.){
Roots[i]+=PIpPI;
}
if(Roots[i]>PIpPI) {
Roots[i]-=PIpPI;
}
}
//
//-- La recherche directe donne n importe quoi.
SvNbRoots=NbRoots;
for(i=0; i<SvNbRoots; ++i) {
Standard_Real y;
Standard_Real co=cos(Roots[i]);
Standard_Real si=sin(Roots[i]);
y=co*(CC*co + (SC+SC)*si + C) + S*si + Cte;
if(Abs(y)>1e-8) {
done=Standard_False;
return; //-- le 1er avril 98
}
}
//
do {
Triee=Standard_True;
for(i=1,j=0; i<SvNbRoots; ++i,++j) {
if(Roots[i]<Roots[j]) {
Triee=Standard_False;
Standard_Real t=Roots[i];
Roots[i]=Roots[j];
Roots[j]=t;
}
}
}
while(!Triee);
//
infinite_roots=Standard_False;
//
if(!NbRoots) {//--!!!!! Detection du cas Pol = Cte ( 1e-50 ) !!!!
if((Abs(CC) + Abs(SC) + Abs(C) + Abs(S)) < 1e-10) {
if(Abs(Cte) < 1e-10) {
infinite_roots=Standard_True;
}
}
}
}
//=======================================================================
//class : MyTrigonometricFunction
//purpose :
// Classe interne : Donne Value et Derivative sur un polynome
// trigonometrique
//======================================================================
class MyTrigonometricFunction {
private:
Standard_Real CC,SS,SC,S,C,Cte;
public:
//
MyTrigonometricFunction(const Standard_Real xCC,
const Standard_Real xSS,
const Standard_Real xSC,
const Standard_Real xC,
const Standard_Real xS,
const Standard_Real xCte) {
CC=xCC;
SS=xSS;
SC=xSC;
S=xS;
C=xC;
Cte=xCte;
}
Standard_Real Value(const Standard_Real& U) {
Standard_Real sinus, cosinus, aRet;
//
sinus=sin(U);
cosinus=cos(U);
aRet= CC*cosinus*cosinus +
SS*sinus*sinus +
2.0*(sinus*(SC*cosinus+S)+cosinus*C)+
Cte;
//
return aRet;
}
//
Standard_Real Derivative(const Standard_Real& U) {
Standard_Real sinus, cosinus;
//
sinus=sin(U);
cosinus=cos(U);
//
return(2.0*((sinus*cosinus)*(SS-CC)
+S*cosinus
-C*sinus
+SC*(cosinus*cosinus-sinus*sinus)));
}
};
//////////
//=======================================================================
//function : IntAna_IntQuadQuad::IntAna_IntQuadQuad
//purpose : C o n s t r u c t e u r v i d e
//=======================================================================
IntAna_IntQuadQuad::IntAna_IntQuadQuad(void) {
done=Standard_False;
identical = Standard_False;
NbCurves=0;
Nbpoints=0;
myNbMaxCurves=12;
myEpsilon=0.00000001;
myEpsilonCoeffPolyNull=0.00000001;
memset (nextcurve, 0, sizeof (nextcurve));
memset (previouscurve, 0, sizeof (previouscurve));
}
//=======================================================================
//function : IntAna_IntQuadQuad::IntAna_IntQuadQuad
//purpose : I n t e r s e c t i o n C y l i n d r e Q u a d r i q u e
//=======================================================================
IntAna_IntQuadQuad::IntAna_IntQuadQuad(const gp_Cylinder& Cyl,
const IntAna_Quadric& Quad,
const Standard_Real Tol) {
myNbMaxCurves=12;
myEpsilon=0.00000001;
myEpsilonCoeffPolyNull=0.00000001;
Perform(Cyl,Quad,Tol);
}
//=======================================================================
//function : Perform
//purpose : I n t e r s e c t i o n C y l i n d r e Q u a d r i q u e
//=======================================================================
void IntAna_IntQuadQuad::Perform(const gp_Cylinder& Cyl,
const IntAna_Quadric& Quad,
const Standard_Real)
{
done = Standard_True;
identical= Standard_False;
NbCurves=0;
Nbpoints=0;
//
Standard_Boolean UN_SEUL_Z_PAR_THETA, DEUX_Z_PAR_THETA,
Z_POSITIF, Z_INDIFFERENT, Z_NEGATIF;
//
UN_SEUL_Z_PAR_THETA=Standard_False;
DEUX_Z_PAR_THETA=Standard_True;
Z_POSITIF=Standard_True;
Z_INDIFFERENT=Standard_True;
Z_NEGATIF=Standard_False;
//
Standard_Real Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1, aRealEpsilon, RCyl, R2;
Standard_Real PIpPI = M_PI + M_PI;
//
for(Standard_Integer raz = 0 ; raz < myNbMaxCurves ; raz++) {
previouscurve[raz] = nextcurve[raz] = 0;
}
//
RCyl=Cyl.Radius();
aRealEpsilon=RealEpsilon();
//----------------------------------------------------------------------
//-- Coefficients de la quadrique :
//-- 2 2 2
//-- Qxx x + Qyy y + Qzz z + 2 ( Qxy x y + Qxz x z + Qyz y z )
//-- + 2 ( Qx x + Qy y + Qz z ) + Q1
//----------------------------------------------------------------------
Quad.Coefficients(Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1);
//----------------------------------------------------------------------
//-- Ecriture des Coefficients de la Quadrique dans le repere liee
//-- au Cylindre
//-- Cyl.Position() -> 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)<myEpsilonCoeffPolyNull) {
done=Standard_False; //-- le 12 mars 98
return;
}
else { //#0
//----------------------------------------------------------------------
//--- Cas ou F(Z,Theta) est du second degre en Z ----
//----------------------------------------------------------------------
R2 = RCyl*RCyl;
Standard_Real C_1 = Qz*Qz - Qzz*Q1;
Standard_Real C_SS = R2 * ( Qyz*Qyz - Qyy*Qzz );
Standard_Real C_CC = R2 * ( Qxz*Qxz - Qxx*Qzz );
Standard_Real C_S = RCyl * ( Qyz*Qz - Qy*Qzz );
Standard_Real C_C = RCyl * ( Qxz*Qz - Qx*Qzz );
Standard_Real C_SC = R2 * ( Qxz*Qyz - Qxy*Qzz );
//
MyTrigonometricFunction MTF(C_CC,C_SS,C_SC,C_C,C_S,C_1);
TrigonometricRoots PolDIS(C_CC-C_SS,
C_SC,
C_C+C_C,
C_S+C_S,
C_1+C_SS, 0., PIpPI);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if(PolDIS.IsDone()==Standard_False) {
done=Standard_False;
return;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
if(PolDIS.InfiniteRoots()) {
TheCurve[0].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,
myEpsilon,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.,PIpPI,
UN_SEUL_Z_PAR_THETA,
Z_NEGATIF);
NbCurves=2;
}
else { //#1
//---------------------------------------------------------------
//-- La Recherche des Zero de DIS a reussi
//---------------------------------------------------------------
Standard_Integer nbsolDIS=PolDIS.NbSolutions();
if(nbsolDIS==0) {
//--------------------------------------------------------------
//-- Le Discriminant a un signe constant :
//--
//-- Si Positif ---> 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<nbsolDIS)? PolDIS.Value(i+1) : (PolDIS.Value(1)+PIpPI);
//----------------------------------------------------------------
//-- On detecte les racines doubles
//-- Si il n y a que 2 racines alors on prend tout l interval
//----------------------------------------------------------------
if(Abs(Theta2-Theta1)<=aRealEpsilon) {
UnPtTg = Standard_True;
autrepar=Theta1-0.1;
if(autrepar<0.) {
autrepar=Theta1+0.1;
}
//
qwet=MTF.Value(autrepar);
if(qwet>=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<nbsolDIS)? PolDIS.Value(i+1) : (PolDIS.Value(1)+PIpPI);
//----------------------------------------------------------------
//-- On detecte les racines doubles
//-- Si il n y a que 2 racines alors on prend tout l interval
//----------------------------------------------------------------
if(Abs(Theta2-Theta1)<=1e-12) {
//-- std::cout<<"\n####### Un Point de Tangence en Theta = "<<Theta1<<std::endl;
//-- i++;
}
else { //-- On evite les pbs numeriques (Tout est du meme signe entre les racines)
qwet=MTF.Value(0.5*(Theta1+Theta2))
+MTF.Value(0.4*Theta1+0.6*Theta2)
+MTF.Value(0.6*Theta1+0.4*Theta2);
if(qwet >= 0.) {
//------------------------------------------------------------
//-- On est positif a partir de Theta1
//-- L intervalle Theta1,Theta2 est retenu
//------------------------------------------------------------
//-- le 8 octobre 1997 :
//-- PB: Racine en 0 pi/2 pi/2 et 2pi
//-- On cree 2 courbes : 0 -> pi/2 2zpartheta
//-- pi/2 -> 2pi 2zpartheta
//--
//-- la courbe 0 pi/2 passe par le double pt de tangence pi/2
//-- il faut donc couper cette courbe en 2
//--
Theta3 = ((i+1)<nbsolDIS)? PolDIS.Value(i+2) : (PolDIS.Value(1)+PIpPI);
//ft
if((Theta3-Theta2)<5.e-8) {
//
AddSpecialPoints(Quad, Cyl, Theta1, Theta2);
TheCurve[NbCurves].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,
myEpsilon,Theta1,Theta2,
UN_SEUL_Z_PAR_THETA,
Z_POSITIF);
NbCurves++;
TheCurve[NbCurves].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,
myEpsilon,Theta1,Theta2,
UN_SEUL_Z_PAR_THETA,
Z_NEGATIF);
NbCurves++;
}
else {
AddSpecialPoints(Quad, Cyl, Theta1, Theta2);
TheCurve[NbCurves].SetCylinderQuadValues(Cyl,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,
myEpsilon,Theta1,Theta2,
DEUX_Z_PAR_THETA,
Z_INDIFFERENT);
NbCurves++;
}
}//if(qwet >= 0.)
}//else { //-- On evite les pbs numerique ...
} //for(i=1; UnPtTg == (Standard_False) && (i<=nbsolDIS) ; i++) {
}//else { // #3
}//else { //#2
}//else { //#1
}//else { //#0
}
//=======================================================================
//function :IntAna_IntQuadQuad::IntAna_IntQuadQuad
//purpose :
//=======================================================================
IntAna_IntQuadQuad::IntAna_IntQuadQuad(const gp_Cone& Cone,
const IntAna_Quadric& Quad,
const Standard_Real Tol)
{
myNbMaxCurves=12;
myEpsilon=0.00000001;
myEpsilonCoeffPolyNull=0.00000001;
Perform(Cone,Quad,Tol);
}
//=======================================================================
//function :Perform
//purpose :
//=======================================================================
void IntAna_IntQuadQuad::Perform(const gp_Cone& Cone,
const IntAna_Quadric& Quad,
const Standard_Real)
{
//
Standard_Boolean UN_SEUL_Z_PAR_THETA,
Z_POSITIF, Z_NEGATIF;
//
UN_SEUL_Z_PAR_THETA=Standard_False;
Z_POSITIF=Standard_True;
Z_NEGATIF=Standard_False;
//
Standard_Integer i;
Standard_Real Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1;
Standard_Real Theta1, Theta2, TgAngle;
Standard_Real PIpPI = M_PI + M_PI;
//
done=Standard_True;
identical = Standard_False;
NbCurves=0;
Nbpoints=0;
//
for(i=0 ; i<myNbMaxCurves ; ++i) {
previouscurve[i]=0;
nextcurve[i]=0;
}
//
Quad.Coefficients(Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1);
//
gp_Ax3 tAx3(Cone.Position());
tAx3.SetLocation(Cone.Apex());
Quad.NewCoefficients(Qxx,Qyy,Qzz,
Qxy,Qxz,Qyz,
Qx,Qy,Qz,Q1,
tAx3);
//
TgAngle=1./(Tan(Cone.SemiAngle()));
//
// The parametrization of the Cone
//
// x= z*tan(beta)*cos(t)
// y= z*tan(beta)*sin(t)
// z=z
//
// The intersection curves are defined by the equation
//
// 2
// f(z,t)= A(t)*z + B(t)*z + C(t)=0
//
//
// 1. Try to solve A(t)=0 -> PolZ2
//
Standard_Integer nbsol, nbsol1, nbsolZ2;
Standard_Real Z2CC, Z2SS, Z2Cte, Z2SC, Z2C, Z2S;
Standard_Real Z1CC, Z1SS, Z1Cte, Z1SC, Z1C, Z1S;
Standard_Real C_1,C_SS, C_CC, C_S, C_C, C_SC;
//
Z2CC = Qxx;
Z2SS = Qyy;
Z2Cte= Qzz * TgAngle*TgAngle;
Z2SC = Qxy;
Z2C = (TgAngle)*Qxz;
Z2S = (TgAngle)*Qyz;
//
TrigonometricRoots PolZ2(Z2CC-Z2SS,Z2SC,Z2C+Z2C,Z2S+Z2S,Z2Cte+Z2SS,0.,PIpPI);
if(!PolZ2.IsDone()) {
done=!done;
return;
}
//
//MyTrigonometricFunction MTF2(Z2CC,Z2SS,Z2SC,Z2C,Z2S,Z2Cte);
nbsolZ2 = PolZ2.NbSolutions();
//
// 2. Try to solve B(t)=0 -> PolZ1
//
Z1Cte = 2.*(TgAngle)*Qz;
Z1SS = 0.;
Z1CC = 0.;
Z1S = Qy;
Z1C = Qx;
Z1SC = 0.;
//
TrigonometricRoots PolZ1(Z1CC-Z1SS,Z1SC, Z1C+Z1C,Z1S+Z1S, Z1Cte+Z1SS,0.,PIpPI);
if(!PolZ1.IsDone()) {
done=!done;
return;
}
MyTrigonometricFunction MTFZ1(Z1CC,Z1SS,Z1SC,Z1C,Z1S,Z1Cte);
//
nbsol1=PolZ1.NbSolutions();
if(PolZ2.InfiniteRoots()) { // i.e A(t)=0 for any t
if(!PolZ1.InfiniteRoots()) {
if(!nbsol1) {
//-- B(t)*z + C(t) = 0 avec C(t) != 0
TheCurve[0].SetConeQuadValues(Cone,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,
myEpsilon,0.,PIpPI,
UN_SEUL_Z_PAR_THETA,
Z_POSITIF);
NbCurves=1;
}
else {
/*
Standard_Integer ii;
for(ii=1; ii<= nbsol1 ; ++ii) {
Standard_Real Theta=PolZ1.Value(ii);
if(Abs(MTFZ1.Value(Theta))<=myEpsilon) {
//-- Une droite Solution Z= -INF -> +INF pour Theta
//-- std::cout<<"######## Droite Solution Pour Theta = "<<Theta<<std::endl;
}
else {
//-- std::cout<<"\n#### _+_+_+_+_+ CAS A(t) Z + B = 0 avec A et B ==0 "<<std::endl;
}
}
*/
}
}
else {
if(Abs(Q1)<=myEpsilon) {
done=!done;
return;
}
else {
//-- Pas de Solutions
}
}
return;
}
//
//else { //#5
//
// 2
//-- f(z,t)=A(t)*z + B(t)*z + C(t)=0 avec A n est pas toujours nul
//
// 2
// 3. Try to explore s.c. Discriminant: D(t)=B(t)-4*A(t)*C(t) => 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=(i<nbsol)? Pol.Value(i+1) : (Pol.Value(1)+PIpPI);
}
//
if(Abs(Theta2-Theta1)<=myEpsilon){
done=Standard_False;
return;// !!! pkv
}
//else {// #2
Standard_Real qwet =MTF.Value(0.5*(Theta1+Theta2))+
MTF.Value(0.4*Theta1+0.6*Theta2)+
MTF.Value(0.6*Theta1+0.4*Theta2);
if(qwet < 0.) {
continue;
}
//---------------------------------------------------------------------
//-- On a des Solutions entre Theta1 et Theta 2
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//-- On Subdivise si necessaire Theta1-->Theta2
//-- 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 && r<Theta2) {
RacinesdePolZ2DansTheta1Theta2=Standard_True;
}
else {
r+=PIpPI;
if(r>Theta1 && r<Theta2){
RacinesdePolZ2DansTheta1Theta2=Standard_True;
}
}
}
//
if(!RacinesdePolZ2DansTheta1Theta2) {
//--------------------------------------------------------------------
//-- Pas de Branches Infinies
TheCurve[NbCurves].SetConeQuadValues(Cone,Qxx,Qyy,Qzz,Qxy,Qxz,Qyz,Qx,Qy,Qz,Q1,myEpsilon,
Theta1,Theta2,
UN_SEUL_Z_PAR_THETA,Z_POSITIF);
NbCurves++;
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++;
}
else { //#1
Standard_Boolean NoChanges;
Standard_Real NewMin, NewMax, to;
//
NewMin=Theta1;
NewMax=Theta2;
NoChanges=Standard_True;
//
for(i2=1; i2<= (nbsolZ2+nbsolZ2) ; ++i2) {
if(i2>nbsolZ2) {
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(to<NewMax && to>NewMin) {
//-----------------------------------------------------------------
//-- 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(to<NewMax && to>NewMin)
}// 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; c1<NbCurves; c1++) {
nextcurve[c1] =0;
previouscurve[c1] = 0;
}
//
for(c1=0; c1 < NbCurves; c1++) {
TheCurve[c1].Domain(DInfC1,DSupC1);
for(c2 = 0; (c2 < NbCurves) && (c2!=c1) ; c2++) {
NotLastOpenC2 = ! TheCurve[c2].IsLastOpen();
NotFirstOpenC2 = ! TheCurve[c2].IsFirstOpen();
TheCurve[c2].Domain(DInfC2,DSupC2);
if(TheCurve[c1].IsFirstOpen() == Standard_False) {
if(NotLastOpenC2) {
if(Abs(DInfC1-DSupC2)<=aEps &&
(TheCurve[c1].Value(DInfC1)
.Distance(TheCurve[c2].Value(DSupC2))<aEPSILON_DISTANCE)) {
previouscurve[c1] = c2+1;
nextcurve[c2] = c1+1;
}
}
if(NotFirstOpenC2) {
if(Abs(DInfC1-DInfC2)<=aEps
&& (TheCurve[c1].Value(DInfC1)
.Distance(TheCurve[c2].Value(DInfC2))<aEPSILON_DISTANCE)) {
previouscurve[c1] = -(c2+1);
previouscurve[c2] = -(c1+1);
}
}
}
if(TheCurve[c1].IsLastOpen() == Standard_False) {
if(NotLastOpenC2) {
if(Abs(DSupC1-DSupC2)<=aEps
&& (TheCurve[c1].Value(DSupC1)
.Distance(TheCurve[c2].Value(DSupC2))<aEPSILON_DISTANCE)) {
nextcurve[c1] = -(c2+1);
nextcurve[c2] = -(c1+1);
}
}
if(NotFirstOpenC2) {
if(Abs(DSupC1-DInfC2)<=aEps
&& (TheCurve[c1].Value(DSupC1)
.Distance(TheCurve[c2].Value(DInfC2))<aEPSILON_DISTANCE)) {
nextcurve[c1] = c2+1;
previouscurve[c2] = c1+1;
}
}
}
}
}
}
//=======================================================================
//function :HasPreviousCurve
//purpose :
//=======================================================================
Standard_Boolean IntAna_IntQuadQuad::HasPreviousCurve(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 '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
{
std::cout << "IntAna_IntQuadQuad::Parameters(...) is not yet implemented" << std::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<aNb; ++i) {
aT=aT1+i*dT;
if (i==(aNb-1)){
aT=aT2;
}
//
aP=aC.Value(aT);
printf("point p%d_%d %lf %lf %lf\n",
aIndex, i, aP.X(), aP.Y(), aP.Z());
}
printf(" ---- end of curve ----\n");
}
*/
//modified by NIZNHY-PKV Fri Dec 2 10:42:16 2005t