Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/LProp_CLProps.gxx is written in an unsupported language. File is not indexed.

0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #include <LProp_Status.hxx>
0016 #include <LProp_NotDefined.hxx>
0017 #include <Standard_OutOfRange.hxx>
0018 
0019 static const Standard_Real MinStep   = 1.0e-7;
0020 
0021 
0022 
0023 LProp_CLProps::LProp_CLProps (const Curve& C,
0024                               const Standard_Real U,
0025                               const Standard_Integer N, 
0026                               const Standard_Real Resolution) 
0027       : myCurve(C), myDerOrder(N), myCN(4), 
0028         myLinTol(Resolution), myTangentStatus (LProp_Undecided)
0029 {
0030   Standard_OutOfRange_Raise_if (N < 0 || N > 3,
0031                           "LProp_CLProps::LProp_CLProps()");
0032 
0033   SetParameter(U);
0034 }
0035 
0036 LProp_CLProps::LProp_CLProps (const Curve& C, const Standard_Integer N, 
0037                                     const Standard_Real Resolution) 
0038         : myCurve(C), myU(RealLast()), myDerOrder(N), myCN(4), 
0039             myLinTol(Resolution), myTangentStatus (LProp_Undecided)
0040 {
0041   Standard_OutOfRange_Raise_if (N < 0 || N > 3, 
0042                           "LProp_CLProps::LProp_CLProps()");  
0043 }
0044 
0045 LProp_CLProps::LProp_CLProps (const Standard_Integer N, 
0046                               const Standard_Real Resolution) 
0047         : myU(RealLast()), myDerOrder(N), myCN(0), myLinTol(Resolution),
0048                             myTangentStatus (LProp_Undecided)
0049 {
0050   Standard_OutOfRange_Raise_if (N < 0 || N > 3, "LProp_CLProps() - invalid input");
0051 }
0052 
0053 void LProp_CLProps::SetParameter(const Standard_Real U)
0054 {
0055   myU = U;
0056   switch (myDerOrder)
0057   {
0058   case 0:
0059     Tool::Value(myCurve, myU, myPnt);
0060     break;
0061   case 1:
0062     Tool::D1(myCurve, myU, myPnt, myDerivArr[0]);
0063     break;
0064   case 2:
0065     Tool::D2(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1]);
0066     break;
0067   case 3:
0068     Tool::D3(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1], myDerivArr[2]);
0069     break;
0070   }
0071 
0072   myTangentStatus = LProp_Undecided;
0073 }
0074 
0075 void LProp_CLProps::SetCurve(const Curve& C)
0076 {
0077   myCurve = C ; 
0078   myCN = 4; // Tool::Continuity(C); RLE
0079 }
0080 
0081 const Pnt& LProp_CLProps::Value () const
0082 {
0083   return myPnt;
0084 }
0085 
0086 const Vec& LProp_CLProps::D1 ()
0087 {
0088   if (myDerOrder < 1)
0089   {
0090     myDerOrder = 1;
0091     Tool::D1(myCurve, myU, myPnt, myDerivArr[0]);
0092   }
0093 
0094   return myDerivArr[0];
0095 }
0096 
0097 const Vec& LProp_CLProps::D2 ()
0098 {
0099   if (myDerOrder < 2)
0100   {
0101     myDerOrder = 2;
0102     Tool::D2(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1]);
0103   }
0104 
0105   return myDerivArr[1];
0106 }
0107 
0108 const Vec& LProp_CLProps::D3 ()
0109 {
0110   if (myDerOrder < 3)
0111   {
0112     myDerOrder = 3;
0113     Tool::D3(myCurve, myU, myPnt, myDerivArr[0], myDerivArr[1], myDerivArr[2]);
0114   }
0115 
0116   return myDerivArr[2];
0117 }
0118 
0119 Standard_Boolean LProp_CLProps::IsTangentDefined ()
0120 {
0121   if (myTangentStatus == LProp_Undefined)
0122     return Standard_False;
0123   else if (myTangentStatus >= LProp_Defined)
0124     return Standard_True;
0125 
0126   // tangentStatus == Lprop_Undecided 
0127   // we have to calculate the first non null derivative
0128   const Standard_Real Tol = myLinTol * myLinTol;
0129   
0130   Vec V;
0131   
0132   Standard_Integer Order = 0;
0133   while (Order++ < 4)
0134   {
0135     if(myCN >= Order)
0136     {
0137       switch(Order)
0138       {
0139       case 1:
0140         V = D1();
0141         break;
0142       case 2:
0143         V = D2();
0144         break;
0145       case 3:
0146         V = D3();
0147         break;
0148       }//switch(Order)
0149 
0150       if(V.SquareMagnitude() > Tol)
0151       {
0152         mySignificantFirstDerivativeOrder = Order;
0153         myTangentStatus = LProp_Defined;
0154         return Standard_True;
0155       }//if(V.SquareMagnitude() > Tol)
0156     }//if(cn >= Order)
0157     else
0158     {
0159       myTangentStatus = LProp_Undefined;
0160       return Standard_False;
0161     }// else of "if(cn >= Order)" condition
0162   }//while (Order < 4)
0163 
0164   return Standard_False;
0165 }
0166 
0167 void  LProp_CLProps::Tangent (Dir& D)
0168 {
0169   if(!IsTangentDefined())
0170     throw LProp_NotDefined();
0171   
0172   if(mySignificantFirstDerivativeOrder == 1)
0173     D = Dir(myDerivArr[0]);
0174   else if (mySignificantFirstDerivativeOrder > 1)
0175   {
0176     const Standard_Real DivisionFactor = 1.e-3;
0177     const Standard_Real anUsupremum = Tool::LastParameter(myCurve), 
0178                         anUinfium = Tool::FirstParameter(myCurve);
0179                         
0180     Standard_Real du;
0181     if((anUsupremum >= RealLast()) || (anUinfium <= RealFirst()))
0182       du = 0.0;
0183     else
0184       du = anUsupremum-anUinfium;
0185     
0186     const Standard_Real aDelta = Max(du*DivisionFactor,MinStep);
0187 
0188     Vec V = myDerivArr[mySignificantFirstDerivativeOrder - 1];
0189     
0190     Standard_Real u;
0191           
0192     if(myU-anUinfium < aDelta)
0193       u = myU+aDelta;
0194     else
0195       u = myU-aDelta;
0196     
0197     Pnt P1, P2;
0198     Tool::Value(myCurve, Min(myU, u),P1);
0199     Tool::Value(myCurve, Max(myU, u),P2);
0200     
0201     Vec V1(P1,P2);
0202     Standard_Real aDirFactor = V.Dot(V1);
0203     
0204     if(aDirFactor < 0.0)
0205       V = -V;
0206       
0207     D = Dir(V);
0208   }//else if (mySignificantFirstDerivativeOrder > 1)
0209 }
0210 
0211 Standard_Real LProp_CLProps::Curvature ()
0212 {
0213   Standard_Boolean isDefined = IsTangentDefined();
0214   (void)isDefined; // trick to avoid compiler warning on variable unised in Release mode; note that IsTangentDefined() must be called always
0215   LProp_NotDefined_Raise_if(!isDefined,
0216           "LProp_CLProps::CurvatureNotDefined()");
0217 
0218   // if the first derivative is null the curvature is infinite.
0219   if(mySignificantFirstDerivativeOrder > 1)
0220     return RealLast();
0221 
0222   Standard_Real Tol = myLinTol * myLinTol;
0223   Standard_Real DD1 = myDerivArr[0].SquareMagnitude();
0224   Standard_Real DD2 = myDerivArr[1].SquareMagnitude();
0225   
0226   // if the second derivative is null the curvature is null.
0227   if (DD2 <= Tol)
0228   {
0229     myCurvature = 0.0;
0230   }
0231   else
0232   {
0233     Standard_Real N = myDerivArr[0].CrossSquareMagnitude(myDerivArr[1]);
0234     // if d[0] and d[1] are colinear the curvature is null.
0235     //Standard_Real t = N/(DD1*DD2);
0236     Standard_Real t = N / DD1 / DD2;
0237     if (t<=Tol)
0238     {
0239       myCurvature = 0.0;
0240     }
0241     else
0242     {
0243       myCurvature = sqrt(N) / DD1 / sqrt(DD1);
0244     }
0245   }
0246 
0247   return myCurvature;
0248 }
0249 
0250 void  LProp_CLProps::Normal (Dir& D)
0251 {
0252   Standard_Real c = Curvature();
0253   if(c==RealLast() || Abs(c) <= myLinTol)
0254   {
0255     throw LProp_NotDefined("LProp_CLProps::Normal(...):"
0256         "Curvature is null or infinity"); 
0257   }
0258 
0259   // we used here the following vector relation 
0260   // a ^ (b ^ c) = b(ac) - c(ab)
0261   // Norm = d[0] ^ (d[1] ^ d[0])
0262   
0263   Vec Norm = myDerivArr[1] * (myDerivArr[0] * myDerivArr[0]) - myDerivArr[0] * (myDerivArr[0] * myDerivArr[1]);
0264   D = Dir(Norm);
0265 }
0266 
0267 void  LProp_CLProps::CentreOfCurvature (Pnt& P)
0268 {
0269   if(Abs(Curvature()) <= myLinTol)
0270   {
0271     throw LProp_NotDefined();
0272   }
0273 
0274   // we used here the following vector relation 
0275   // a ^ (b ^ c) = b(ac) - c(ab)
0276   // Norm = d[0] ^ (d[1] ^ d[0])
0277 
0278   Vec Norm = myDerivArr[1] * (myDerivArr[0] * myDerivArr[0]) - myDerivArr[0] * (myDerivArr[0] * myDerivArr[1]);
0279   Norm.Normalize();
0280   Norm.Divide(myCurvature);
0281   P= myPnt.Translated(Norm);
0282 }