1 // Created on: 1995-07-18
2 // Created by: Modelistation
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <Extrema_GlobOptFuncCC.hxx>
18 #include <math_GlobOptMin.hxx>
19 #include <Standard_NullObject.hxx>
20 #include <Standard_OutOfRange.hxx>
21 #include <StdFail_NotDone.hxx>
22 #include <TColStd_Array1OfReal.hxx>
23 #include <Precision.hxx>
25 //=======================================================================
26 //function : Extrema_GenExtCC
28 //=======================================================================
29 Extrema_GenExtCC::Extrema_GenExtCC()
30 : myCurveMinTol(Precision::PConfusion()),
33 myDone(Standard_False)
38 //=======================================================================
39 //function : Extrema_GenExtCC
41 //=======================================================================
42 Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
44 : myCurveMinTol(Precision::PConfusion()),
47 myDone(Standard_False)
49 myC[0] = (Standard_Address)&C1;
50 myC[1] = (Standard_Address)&C2;
51 myLowBorder(1) = C1.FirstParameter();
52 myLowBorder(2) = C2.FirstParameter();
53 myUppBorder(1) = C1.LastParameter();
54 myUppBorder(2) = C2.LastParameter();
57 //=======================================================================
58 //function : Extrema_GenExtCC
60 //=======================================================================
61 Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
63 const Standard_Real Uinf,
64 const Standard_Real Usup,
65 const Standard_Real Vinf,
66 const Standard_Real Vsup)
67 : myCurveMinTol(Precision::PConfusion()),
70 myDone(Standard_False)
72 myC[0] = (Standard_Address)&C1;
73 myC[1] = (Standard_Address)&C2;
74 myLowBorder(1) = Uinf;
75 myLowBorder(2) = Vinf;
76 myUppBorder(1) = Usup;
77 myUppBorder(2) = Vsup;
80 //=======================================================================
81 //function : SetParams
83 //=======================================================================
84 void Extrema_GenExtCC::SetParams(const Curve1& C1,
86 const Standard_Real Uinf,
87 const Standard_Real Usup,
88 const Standard_Real Vinf,
89 const Standard_Real Vsup)
91 myC[0] = (Standard_Address)&C1;
92 myC[1] = (Standard_Address)&C2;
93 myLowBorder(1) = Uinf;
94 myLowBorder(2) = Vinf;
95 myUppBorder(1) = Usup;
96 myUppBorder(2) = Vsup;
99 //=======================================================================
100 //function : SetTolerance
102 //=======================================================================
103 void Extrema_GenExtCC::SetTolerance(Standard_Real theTol)
105 myCurveMinTol = theTol;
108 //=======================================================================
111 //=======================================================================
112 void Extrema_GenExtCC::Perform()
114 myDone = Standard_False;
116 Curve1 &C1 = *(Curve1*)myC[0];
117 Curve2 &C2 = *(Curve2*)myC[1];
119 Standard_Integer aNbInter[2];
120 aNbInter[0] = C1.NbIntervals(GeomAbs_C2);
121 aNbInter[1] = C2.NbIntervals(GeomAbs_C2);
122 TColStd_Array1OfReal anIntervals1(1, aNbInter[0] + 1);
123 TColStd_Array1OfReal anIntervals2(1, aNbInter[1] + 1);
124 C1.Intervals(anIntervals1, GeomAbs_C2);
125 C2.Intervals(anIntervals2, GeomAbs_C2);
127 Extrema_GlobOptFuncCCC2 aFunc (C1, C2);
128 math_GlobOptMin aFinder(&aFunc, myLowBorder, myUppBorder);
129 Standard_Real aDiscTol = 1.0e-2;
130 Standard_Real aValueTol = 1.0e-2;
131 Standard_Real aSameTol = myCurveMinTol / (aDiscTol);
132 aFinder.SetTol(aDiscTol, aSameTol);
134 Standard_Real anEps1 = (myUppBorder(1) - myLowBorder(1)) * Precision::Confusion();
135 Standard_Real anEps2 = (myUppBorder(2) - myLowBorder(2)) * Precision::Confusion();
137 Standard_Integer i,j,k;
138 math_Vector aFirstBorderInterval(1,2);
139 math_Vector aSecondBorderInterval(1,2);
140 Standard_Real aF = RealLast(); // best functional value
141 Standard_Real aCurrF = RealLast(); // current functional value computed on current interval
142 for(i = 1; i <= aNbInter[0]; i++)
144 for(j = 1; j <= aNbInter[1]; j++)
146 aFirstBorderInterval(1) = anIntervals1(i);
147 aFirstBorderInterval(2) = anIntervals2(j);
148 aSecondBorderInterval(1) = anIntervals1(i + 1);
149 aSecondBorderInterval(2) = anIntervals2(j + 1);
151 aFinder.SetLocalParams(aFirstBorderInterval, aSecondBorderInterval);
154 // check that solution found on current interval is not worse than previous
155 aCurrF = aFinder.GetF();
156 if (aCurrF >= aF + aSameTol * aValueTol)
161 // clean previously computed solution if current one is better
162 if (aCurrF > aF - aSameTol * aValueTol)
174 // save found solutions avoiding repetitions
175 math_Vector sol(1,2);
176 for(k = 1; k <= aFinder.NbExtrema(); k++)
178 aFinder.Points(k, sol);
180 // avoid duplicated points
181 Standard_Boolean isNew = Standard_True;
182 for (Standard_Integer iSol = 1; isNew && iSol <= myPoints1.Length(); iSol++)
184 if (Abs(myPoints1(iSol) - sol(1)) < anEps1 &&
185 Abs(myPoints2(iSol) - sol(2)) < anEps2)
186 isNew = Standard_False;
190 myPoints1.Append(sol(1));
191 myPoints2.Append(sol(2));
197 myDone = Standard_True;
200 //=======================================================================
203 //=======================================================================
204 Standard_Boolean Extrema_GenExtCC::IsDone() const
209 //=======================================================================
212 //=======================================================================
213 Standard_Integer Extrema_GenExtCC::NbExt() const
215 StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::NbExt()")
217 return myPoints1.Length();
220 //=======================================================================
221 //function : SquareDistance
223 //=======================================================================
224 Standard_Real Extrema_GenExtCC::SquareDistance(const Standard_Integer N) const
226 StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::SquareDistance()")
227 Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::SquareDistance()")
229 return Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)).SquareDistance(Tool2::Value(*((Curve2*)myC[1]), myPoints2(N)));
232 //=======================================================================
235 //=======================================================================
236 void Extrema_GenExtCC::Points(const Standard_Integer N,
240 StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::Points()")
241 Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::Points()")
243 P1.SetValues(myPoints1(N), Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)));
244 P2.SetValues(myPoints2(N), Tool2::Value(*((Curve2*)myC[1]), myPoints2(N)));