b311480e |
1 | // Created on: 1995-07-18 |
2 | // Created by: Modelistation |
3 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
4bbaf12b |
17 | #include <Extrema_GlobOptFuncCC.hxx> |
18 | #include <math_GlobOptMin.hxx> |
7fd59977 |
19 | #include <Standard_NullObject.hxx> |
20 | #include <Standard_OutOfRange.hxx> |
4bbaf12b |
21 | #include <StdFail_NotDone.hxx> |
22 | #include <TColStd_Array1OfReal.hxx> |
7fd59977 |
23 | #include <Precision.hxx> |
24 | |
5493d334 |
25 | //======================================================================= |
26 | //function : Extrema_GenExtCC |
27 | //purpose : |
28 | //======================================================================= |
4bbaf12b |
29 | Extrema_GenExtCC::Extrema_GenExtCC() |
6ca1fa70 |
30 | : myCurveMinTol(Precision::PConfusion()), |
31 | myLowBorder(1,2), |
4bbaf12b |
32 | myUppBorder(1,2), |
33 | myDone(Standard_False) |
7fd59977 |
34 | { |
6ca1fa70 |
35 | myC[0] = myC[1] = 0; |
7fd59977 |
36 | } |
37 | |
5493d334 |
38 | //======================================================================= |
39 | //function : Extrema_GenExtCC |
40 | //purpose : |
41 | //======================================================================= |
42 | Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1, |
43 | const Curve2& C2) |
6ca1fa70 |
44 | : myCurveMinTol(Precision::PConfusion()), |
45 | myLowBorder(1,2), |
4bbaf12b |
46 | myUppBorder(1,2), |
47 | myDone(Standard_False) |
7fd59977 |
48 | { |
4bbaf12b |
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(); |
7fd59977 |
55 | } |
56 | |
5493d334 |
57 | //======================================================================= |
58 | //function : Extrema_GenExtCC |
59 | //purpose : |
60 | //======================================================================= |
61 | Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1, |
62 | const Curve2& C2, |
63 | const Standard_Real Uinf, |
64 | const Standard_Real Usup, |
65 | const Standard_Real Vinf, |
66 | const Standard_Real Vsup) |
6ca1fa70 |
67 | : myCurveMinTol(Precision::PConfusion()), |
68 | myLowBorder(1,2), |
4bbaf12b |
69 | myUppBorder(1,2), |
70 | myDone(Standard_False) |
7fd59977 |
71 | { |
4bbaf12b |
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; |
7fd59977 |
78 | } |
79 | |
5493d334 |
80 | //======================================================================= |
81 | //function : SetParams |
82 | //purpose : |
83 | //======================================================================= |
84 | void Extrema_GenExtCC::SetParams(const Curve1& C1, |
85 | const Curve2& C2, |
86 | const Standard_Real Uinf, |
87 | const Standard_Real Usup, |
88 | const Standard_Real Vinf, |
89 | const Standard_Real Vsup) |
7fd59977 |
90 | { |
4bbaf12b |
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; |
7fd59977 |
97 | } |
98 | |
5493d334 |
99 | //======================================================================= |
100 | //function : SetTolerance |
101 | //purpose : |
102 | //======================================================================= |
103 | void Extrema_GenExtCC::SetTolerance(Standard_Real theTol) |
104 | { |
105 | myCurveMinTol = theTol; |
106 | } |
107 | |
108 | //======================================================================= |
109 | //function : Perform |
110 | //purpose : |
111 | //======================================================================= |
112 | void Extrema_GenExtCC::Perform() |
7fd59977 |
113 | { |
114 | myDone = Standard_False; |
115 | |
4bbaf12b |
116 | Curve1 &C1 = *(Curve1*)myC[0]; |
117 | Curve2 &C2 = *(Curve2*)myC[1]; |
118 | |
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); |
126 | |
6ca1fa70 |
127 | Extrema_GlobOptFuncCCC2 aFunc (C1, C2); |
128 | math_GlobOptMin aFinder(&aFunc, myLowBorder, myUppBorder); |
5493d334 |
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); |
4bbaf12b |
133 | |
6ca1fa70 |
134 | Standard_Real anEps1 = (myUppBorder(1) - myLowBorder(1)) * Precision::Confusion(); |
135 | Standard_Real anEps2 = (myUppBorder(2) - myLowBorder(2)) * Precision::Confusion(); |
136 | |
4bbaf12b |
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++) |
143 | { |
144 | for(j = 1; j <= aNbInter[1]; j++) |
145 | { |
146 | aFirstBorderInterval(1) = anIntervals1(i); |
147 | aFirstBorderInterval(2) = anIntervals2(j); |
148 | aSecondBorderInterval(1) = anIntervals1(i + 1); |
149 | aSecondBorderInterval(2) = anIntervals2(j + 1); |
150 | |
151 | aFinder.SetLocalParams(aFirstBorderInterval, aSecondBorderInterval); |
152 | aFinder.Perform(); |
153 | |
6ca1fa70 |
154 | // check that solution found on current interval is not worse than previous |
4bbaf12b |
155 | aCurrF = aFinder.GetF(); |
6ca1fa70 |
156 | if (aCurrF >= aF + aSameTol * aValueTol) |
4bbaf12b |
157 | { |
6ca1fa70 |
158 | continue; |
159 | } |
160 | |
161 | // clean previously computed solution if current one is better |
162 | if (aCurrF > aF - aSameTol * aValueTol) |
163 | { |
164 | if (aCurrF < aF) |
4bbaf12b |
165 | aF = aCurrF; |
6ca1fa70 |
166 | } |
167 | else |
168 | { |
169 | aF = aCurrF; |
170 | myPoints1.Clear(); |
171 | myPoints2.Clear(); |
172 | } |
7fd59977 |
173 | |
6ca1fa70 |
174 | // save found solutions avoiding repetitions |
175 | math_Vector sol(1,2); |
176 | for(k = 1; k <= aFinder.NbExtrema(); k++) |
4bbaf12b |
177 | { |
6ca1fa70 |
178 | aFinder.Points(k, sol); |
179 | |
180 | // avoid duplicated points |
181 | Standard_Boolean isNew = Standard_True; |
182 | for (Standard_Integer iSol = 1; isNew && iSol <= myPoints1.Length(); iSol++) |
183 | { |
184 | if (Abs(myPoints1(iSol) - sol(1)) < anEps1 && |
185 | Abs(myPoints2(iSol) - sol(2)) < anEps2) |
186 | isNew = Standard_False; |
187 | } |
188 | if (isNew) |
189 | { |
190 | myPoints1.Append(sol(1)); |
191 | myPoints2.Append(sol(2)); |
192 | } |
4bbaf12b |
193 | } |
7fd59977 |
194 | } |
4bbaf12b |
195 | } |
7fd59977 |
196 | |
7fd59977 |
197 | myDone = Standard_True; |
198 | } |
7fd59977 |
199 | |
5493d334 |
200 | //======================================================================= |
201 | //function : IsDone |
202 | //purpose : |
203 | //======================================================================= |
204 | Standard_Boolean Extrema_GenExtCC::IsDone() const |
4bbaf12b |
205 | { |
206 | return myDone; |
207 | } |
7fd59977 |
208 | |
5493d334 |
209 | //======================================================================= |
210 | //function : NbExt |
211 | //purpose : |
212 | //======================================================================= |
213 | Standard_Integer Extrema_GenExtCC::NbExt() const |
7fd59977 |
214 | { |
215 | StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::NbExt()") |
4bbaf12b |
216 | |
6ca1fa70 |
217 | return myPoints1.Length(); |
7fd59977 |
218 | } |
7fd59977 |
219 | |
5493d334 |
220 | //======================================================================= |
221 | //function : SquareDistance |
222 | //purpose : |
223 | //======================================================================= |
224 | Standard_Real Extrema_GenExtCC::SquareDistance(const Standard_Integer N) const |
7fd59977 |
225 | { |
226 | StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::SquareDistance()") |
227 | Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::SquareDistance()") |
4bbaf12b |
228 | |
229 | return Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)).SquareDistance(Tool2::Value(*((Curve2*)myC[1]), myPoints2(N))); |
7fd59977 |
230 | } |
7fd59977 |
231 | |
5493d334 |
232 | //======================================================================= |
233 | //function : Points |
234 | //purpose : |
235 | //======================================================================= |
236 | void Extrema_GenExtCC::Points(const Standard_Integer N, |
237 | POnC& P1, |
238 | POnC& P2) const |
7fd59977 |
239 | { |
4bbaf12b |
240 | StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::Points()") |
241 | Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::Points()") |
242 | |
243 | P1.SetValues(myPoints1(N), Tool1::Value(*((Curve1*)myC[0]), myPoints1(N))); |
244 | P2.SetValues(myPoints2(N), Tool2::Value(*((Curve2*)myC[1]), myPoints2(N))); |
245 | } |