Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Created on: 1993-12-14
0002 // Created by: Christophe MARION
0003 // Copyright (c) 1993-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016 
0017 // 05-Jun-00 : hla : meme type de corr. que xab : dans la methode "Perform",
0018 //             suppression du test mal a propos "myintuinf > myintusup" avec
0019 //             "return" a la suite.
0020 // 05-Sep-95 : xab : correction d'un probleme de determination d'intervalle
0021 //             de recherche
0022 
0023 #include Extrema_ELPC_hxx
0024 #include ThePOnC_hxx
0025 #include ThePoint_hxx
0026 #include TheVector_hxx
0027 #include <StdFail_NotDone.hxx>
0028 #include <Standard_DomainError.hxx>
0029 #include <GeomAbs_CurveType.hxx>
0030 #include <Precision.hxx>
0031 #include <TColStd_Array1OfReal.hxx>
0032 
0033 
0034 //=======================================================================
0035 //function : Extrema_GLocateExtPC
0036 //purpose  : 
0037 //=======================================================================
0038 
0039 Extrema_GLocateExtPC::Extrema_GLocateExtPC()
0040 : myC(NULL),
0041   mydist2(0.0),
0042   myismin(Standard_False),
0043   myDone(Standard_False),
0044   myumin(0.0),
0045   myusup(0.0),
0046   mytol(0.0),
0047   type(GeomAbs_OtherCurve),
0048   numberext(0)
0049 {
0050 }
0051 
0052 
0053 //=======================================================================
0054 //function : Extrema_GLocateExtPC
0055 //purpose  : 
0056 //=======================================================================
0057 
0058 Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint&     P,
0059   const TheCurve&     C,
0060   const Standard_Real U0,
0061   const Standard_Real TolF)
0062 {
0063   Initialize(C, TheCurveTool::FirstParameter(C), TheCurveTool::LastParameter(C), TolF);
0064   Perform(P, U0);
0065 }
0066 
0067 //=======================================================================
0068 //function : Extrema_GLocateExtPC
0069 //purpose  : 
0070 //=======================================================================
0071 
0072 Extrema_GLocateExtPC::Extrema_GLocateExtPC (const ThePoint&     P,
0073   const TheCurve&     C,
0074   const Standard_Real U0, 
0075   const Standard_Real Umin,
0076   const Standard_Real Usup,
0077   const Standard_Real TolF)
0078 {
0079   Initialize(C, Umin, Usup, TolF);
0080   Perform(P, U0);
0081 }
0082 
0083 
0084 
0085 //=======================================================================
0086 //function : Initialize
0087 //purpose  : 
0088 //=======================================================================
0089 
0090 void Extrema_GLocateExtPC::Initialize(const TheCurve&     C, 
0091   const Standard_Real Umin,
0092   const Standard_Real Usup,
0093   const Standard_Real TolF)
0094 {
0095   myC = (Standard_Address)&C;
0096   mytol = TolF;
0097   myumin = Umin;
0098   myusup = Usup;
0099   type = TheCurveTool::GetType(C);
0100   Standard_Real tolu = TheCurveTool::Resolution(C, Precision::Confusion());
0101   if ((type == GeomAbs_BSplineCurve) || 
0102       (type == GeomAbs_BezierCurve)  || 
0103       (type == GeomAbs_OffsetCurve)   ||
0104       (type == GeomAbs_OtherCurve))
0105   {
0106       myLocExtPC.Initialize(C, Umin, Usup, tolu);
0107   }
0108   else {
0109     myExtremPC.Initialize(C, Umin, Usup, tolu);
0110   }
0111 }
0112 
0113 
0114 
0115 
0116 //=======================================================================
0117 //function : Perform
0118 //purpose  : 
0119 //=======================================================================
0120 
0121 void Extrema_GLocateExtPC::Perform(const ThePoint&     P,
0122   const Standard_Real U0)
0123 {
0124   Standard_Integer i, i1, i2, inter;
0125   Standard_Real Par, valU, valU2 = RealLast(),
0126     local_u0 ;
0127   Standard_Real myintuinf=0, myintusup=0;
0128   local_u0 = U0 ;
0129   switch(type)
0130   {
0131   case GeomAbs_OtherCurve:
0132   case GeomAbs_OffsetCurve:
0133   case GeomAbs_BSplineCurve:
0134     {
0135       // La recherche de l extremum est faite intervalle continu C2 par
0136       // intervalle continu C2 de la courbe
0137       Standard_Integer n = TheCurveTool::NbIntervals(*((TheCurve*)myC), GeomAbs_C2);
0138       TColStd_Array1OfReal theInter(1, n+1);
0139       TheCurveTool::Intervals(*((TheCurve*)myC), theInter, GeomAbs_C2);
0140       //
0141       //  be gentle with the caller 
0142       //
0143       if (local_u0 < myumin) {
0144         local_u0 = myumin ; 
0145       }
0146       else if (local_u0 > myusup) {
0147         local_u0  = myusup ;
0148       }
0149       // Recherche de l intervalle ou se trouve U0
0150       Standard_Boolean found = Standard_False;
0151       inter = 1;
0152       while (!found && inter <= n) {
0153         // Intervalle commun a l intervalle C2 courant de la courbe et a
0154         // l intervalle total de recherche de l'extremum (hla : au cas ou
0155         // myintuinf > myintusup, c est que les 2 intervalles ne s intersectent
0156         // pas, mais il n'y avait aucune raison de sortir en "return")
0157         myintuinf = Max(theInter(inter), myumin);
0158         myintusup = Min(theInter(inter+1), myusup);
0159         if ((local_u0 >= myintuinf) && (local_u0 < myintusup)) found = Standard_True;
0160         inter++;
0161       }
0162 
0163       if( found ) inter--; //IFV 16.06.00 - inter is increased after found!
0164 
0165       // Essai sur l intervalle trouve
0166       myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, 
0167         myintusup, mytol);
0168       myLocExtPC.Perform(P, local_u0);
0169       myDone = myLocExtPC.IsDone();
0170       if (myDone) {
0171         mypp = myLocExtPC.Point();
0172         myismin = myLocExtPC.IsMin();
0173         mydist2 = myLocExtPC.SquareDistance();
0174       }
0175       else {
0176         Standard_Integer k = 1;
0177         // Essai sur les intervalles alentours:
0178         i1 = inter;
0179         i2 = inter;
0180         Standard_Real s1inf, s2inf, s1sup, s2sup;
0181         ThePoint P1;
0182         TheVector V1;
0183         TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
0184         s2inf = (TheVector(P, P1)*V1);
0185         TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
0186         s1sup = (TheVector(P, P1)*V1);
0187 
0188 
0189         while (!myDone && (i2 > 0) && (i1 <= n))
0190         {
0191           i1 = inter + k;
0192           i2 = inter - k;
0193           if (i1 <= n)
0194           {
0195             myintuinf = Max(theInter(i1), myumin);
0196             myintusup = Min(theInter(i1+1), myusup);
0197             if (myintuinf < myintusup)
0198             {
0199               TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
0200               s2sup = (TheVector(P, P1)*V1);
0201               if(Precision::IsInfinite(s2sup) || Precision::IsInfinite(s1sup))
0202               {
0203                 break;
0204               }
0205               if (s1sup*s2sup <= RealEpsilon())
0206               {
0207                 // extremum:
0208                 myDone = Standard_True;
0209                 mypp.SetValues(myintuinf, P1);
0210                 myismin = (s1sup <= 0.0);
0211                 mydist2 = P.SquareDistance(P1);
0212                 break;
0213               }
0214 
0215               TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
0216               s1sup = (TheVector(P, P1)*V1);
0217               myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, 
0218                 myintusup, mytol);
0219               myLocExtPC.Perform(P, (myintuinf + myintusup)*0.5);
0220               myDone = myLocExtPC.IsDone();
0221               if (myDone) {
0222                 mypp = myLocExtPC.Point();
0223                 myismin = myLocExtPC.IsMin();
0224                 mydist2 = myLocExtPC.SquareDistance();
0225                 break;
0226               }
0227             }
0228           }
0229 
0230           if (i2 > 0)
0231           {
0232             myintuinf = Max(theInter(i2), myumin);
0233             myintusup = Min(theInter(i2+1), myusup);
0234             if (myintuinf < myintusup)
0235             {
0236               TheCurveTool::D1(*((TheCurve*)myC), myintusup, P1, V1);
0237               s1inf = (TheVector(P, P1)*V1);
0238               if(Precision::IsInfinite(s2inf) || Precision::IsInfinite(s1inf))
0239               {
0240                 break;
0241               }
0242               if (s1inf*s2inf <= RealEpsilon())
0243               {
0244                 // extremum:
0245                 myDone = Standard_True;
0246                 mypp.SetValues(myintusup, P1);
0247                 myismin = (s1inf <= 0.0);
0248                 mydist2 = P.SquareDistance(P1);
0249                 break;
0250               }
0251 
0252               TheCurveTool::D1(*((TheCurve*)myC), myintuinf, P1, V1);
0253               s2inf = (TheVector(P, P1)*V1);
0254               myLocExtPC.Initialize((*((TheCurve*)myC)), myintuinf, 
0255                 myintusup, mytol);
0256               myLocExtPC.Perform(P, (myintuinf+myintusup)*0.5 );
0257               myDone = myLocExtPC.IsDone();
0258             
0259               if (myDone)
0260               {
0261                 mypp = myLocExtPC.Point();
0262                 myismin = myLocExtPC.IsMin();
0263                 mydist2 = myLocExtPC.SquareDistance();
0264                 break;
0265               }
0266             }
0267           }
0268 
0269           k++;
0270         }
0271       }
0272     }
0273 
0274     break;
0275 
0276   case GeomAbs_BezierCurve:
0277     {
0278       myLocExtPC.Perform(P, U0);
0279       myDone = myLocExtPC.IsDone();
0280     }
0281 
0282     break;
0283   default:
0284     {
0285       myExtremPC.Perform(P);
0286       numberext = 0;
0287       if (myExtremPC.IsDone())
0288       {
0289         for (i = 1; i <= myExtremPC.NbExt(); i++)
0290         {
0291           Par = myExtremPC.Point(i).Parameter();
0292           valU = Abs(Par - U0);
0293           if (valU <= valU2)
0294           {
0295             valU2 = valU;
0296             numberext = i;
0297             myDone = Standard_True;
0298           }
0299         }
0300       }
0301 
0302       if (numberext == 0)
0303         myDone = Standard_False;
0304 
0305       break;
0306     }
0307   }
0308 }
0309 
0310 
0311 
0312 
0313 //=======================================================================
0314 //function : IsDone
0315 //purpose  : 
0316 //=======================================================================
0317 
0318 Standard_Boolean Extrema_GLocateExtPC::IsDone () const 
0319 {
0320   return myDone;
0321 }
0322 
0323 
0324 //=======================================================================
0325 //function : Value
0326 //purpose  : 
0327 //=======================================================================
0328 
0329 Standard_Real Extrema_GLocateExtPC::SquareDistance () const 
0330 {
0331   if (!IsDone())
0332   {
0333     throw StdFail_NotDone();
0334   }
0335   Standard_Real d=0;
0336   if ((type == GeomAbs_BezierCurve)) {
0337     d =  myLocExtPC.SquareDistance();
0338   }
0339   else if(type == GeomAbs_BSplineCurve ||
0340           type == GeomAbs_OffsetCurve  ||
0341           type == GeomAbs_OtherCurve) {
0342     d = mydist2;
0343   }
0344   else {
0345     if (numberext != 0) {
0346       d = myExtremPC.SquareDistance(numberext);
0347     }
0348   }
0349   return d;
0350 }
0351 
0352 
0353 //=======================================================================
0354 //function : IsMin
0355 //purpose  : 
0356 //=======================================================================
0357 
0358 Standard_Boolean Extrema_GLocateExtPC::IsMin () const 
0359 {
0360   if (!IsDone())
0361   {
0362     throw StdFail_NotDone();
0363   }
0364   Standard_Boolean b = 0;
0365   if ((type == GeomAbs_BezierCurve)) {
0366     b = myLocExtPC.IsMin();
0367   }
0368   else if(type == GeomAbs_BSplineCurve ||
0369           type == GeomAbs_OffsetCurve  ||
0370           type == GeomAbs_OtherCurve) {
0371     b = myismin;
0372   }
0373   else {
0374     if (numberext != 0) {
0375       b = myExtremPC.IsMin(numberext);
0376     }
0377   }
0378   return b;
0379 }
0380 
0381 
0382 //=======================================================================
0383 //function : Point
0384 //purpose  : 
0385 //=======================================================================
0386 
0387 const ThePOnC & Extrema_GLocateExtPC::Point () const 
0388 {
0389   if (!IsDone())
0390   {
0391     throw StdFail_NotDone();
0392   }
0393   if (type == GeomAbs_BezierCurve)
0394   {
0395     return myLocExtPC.Point();
0396   }
0397   else if(type == GeomAbs_BSplineCurve ||
0398           type == GeomAbs_OffsetCurve  ||
0399           type == GeomAbs_OtherCurve) {
0400     return mypp;
0401   }
0402   return myExtremPC.Point(numberext);
0403 }