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() |
30 | : myLowBorder(1,2), |
31 | myUppBorder(1,2), |
32 | myDone(Standard_False) |
7fd59977 |
33 | { |
34 | } |
35 | |
5493d334 |
36 | //======================================================================= |
37 | //function : Extrema_GenExtCC |
38 | //purpose : |
39 | //======================================================================= |
40 | Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1, |
41 | const Curve2& C2) |
4bbaf12b |
42 | : myLowBorder(1,2), |
43 | myUppBorder(1,2), |
44 | myDone(Standard_False) |
7fd59977 |
45 | { |
4bbaf12b |
46 | myC[0] = (Standard_Address)&C1; |
47 | myC[1] = (Standard_Address)&C2; |
48 | myLowBorder(1) = C1.FirstParameter(); |
49 | myLowBorder(2) = C2.FirstParameter(); |
50 | myUppBorder(1) = C1.LastParameter(); |
51 | myUppBorder(2) = C2.LastParameter(); |
5493d334 |
52 | myCurveMinTol = 1.0e-9; |
7fd59977 |
53 | } |
54 | |
5493d334 |
55 | //======================================================================= |
56 | //function : Extrema_GenExtCC |
57 | //purpose : |
58 | //======================================================================= |
59 | Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1, |
60 | const Curve2& C2, |
61 | const Standard_Real Uinf, |
62 | const Standard_Real Usup, |
63 | const Standard_Real Vinf, |
64 | const Standard_Real Vsup) |
4bbaf12b |
65 | : myLowBorder(1,2), |
66 | myUppBorder(1,2), |
67 | myDone(Standard_False) |
7fd59977 |
68 | { |
4bbaf12b |
69 | myC[0] = (Standard_Address)&C1; |
70 | myC[1] = (Standard_Address)&C2; |
71 | myLowBorder(1) = Uinf; |
72 | myLowBorder(2) = Vinf; |
73 | myUppBorder(1) = Usup; |
74 | myUppBorder(2) = Vsup; |
5493d334 |
75 | myCurveMinTol = 1.0e-9; |
7fd59977 |
76 | } |
77 | |
5493d334 |
78 | //======================================================================= |
79 | //function : SetParams |
80 | //purpose : |
81 | //======================================================================= |
82 | void Extrema_GenExtCC::SetParams(const Curve1& C1, |
83 | const Curve2& C2, |
84 | const Standard_Real Uinf, |
85 | const Standard_Real Usup, |
86 | const Standard_Real Vinf, |
87 | const Standard_Real Vsup) |
7fd59977 |
88 | { |
4bbaf12b |
89 | myC[0] = (Standard_Address)&C1; |
90 | myC[1] = (Standard_Address)&C2; |
91 | myLowBorder(1) = Uinf; |
92 | myLowBorder(2) = Vinf; |
93 | myUppBorder(1) = Usup; |
94 | myUppBorder(2) = Vsup; |
7fd59977 |
95 | } |
96 | |
5493d334 |
97 | //======================================================================= |
98 | //function : SetTolerance |
99 | //purpose : |
100 | //======================================================================= |
101 | void Extrema_GenExtCC::SetTolerance(Standard_Real theTol) |
102 | { |
103 | myCurveMinTol = theTol; |
104 | } |
105 | |
106 | //======================================================================= |
107 | //function : Perform |
108 | //purpose : |
109 | //======================================================================= |
110 | void Extrema_GenExtCC::Perform() |
7fd59977 |
111 | { |
112 | myDone = Standard_False; |
113 | |
4bbaf12b |
114 | Curve1 &C1 = *(Curve1*)myC[0]; |
115 | Curve2 &C2 = *(Curve2*)myC[1]; |
116 | |
117 | Standard_Integer aNbInter[2]; |
118 | aNbInter[0] = C1.NbIntervals(GeomAbs_C2); |
119 | aNbInter[1] = C2.NbIntervals(GeomAbs_C2); |
120 | TColStd_Array1OfReal anIntervals1(1, aNbInter[0] + 1); |
121 | TColStd_Array1OfReal anIntervals2(1, aNbInter[1] + 1); |
122 | C1.Intervals(anIntervals1, GeomAbs_C2); |
123 | C2.Intervals(anIntervals2, GeomAbs_C2); |
124 | |
125 | math_MultipleVarFunction *aFunc = new Extrema_GlobOptFuncCCC2(C1, C2); |
126 | math_GlobOptMin aFinder(aFunc, myLowBorder, myUppBorder); |
5493d334 |
127 | Standard_Real aDiscTol = 1.0e-2; |
128 | Standard_Real aValueTol = 1.0e-2; |
129 | Standard_Real aSameTol = myCurveMinTol / (aDiscTol); |
130 | aFinder.SetTol(aDiscTol, aSameTol); |
4bbaf12b |
131 | |
132 | Standard_Integer i,j,k; |
133 | math_Vector aFirstBorderInterval(1,2); |
134 | math_Vector aSecondBorderInterval(1,2); |
135 | Standard_Real aF = RealLast(); // best functional value |
136 | Standard_Real aCurrF = RealLast(); // current functional value computed on current interval |
137 | for(i = 1; i <= aNbInter[0]; i++) |
138 | { |
139 | for(j = 1; j <= aNbInter[1]; j++) |
140 | { |
141 | aFirstBorderInterval(1) = anIntervals1(i); |
142 | aFirstBorderInterval(2) = anIntervals2(j); |
143 | aSecondBorderInterval(1) = anIntervals1(i + 1); |
144 | aSecondBorderInterval(2) = anIntervals2(j + 1); |
145 | |
146 | aFinder.SetLocalParams(aFirstBorderInterval, aSecondBorderInterval); |
147 | aFinder.Perform(); |
148 | |
149 | aCurrF = aFinder.GetF(); |
5493d334 |
150 | if (aCurrF < aF + aSameTol * aValueTol) |
4bbaf12b |
151 | { |
5493d334 |
152 | if (aCurrF > aF - aSameTol * aValueTol) |
4bbaf12b |
153 | { |
5493d334 |
154 | if (aCurrF < aF) |
155 | aF = aCurrF; |
156 | |
4bbaf12b |
157 | math_Vector sol(1,2); |
5493d334 |
158 | Standard_Integer myTmpSolCount = aFinder.NbExtrema(); |
4bbaf12b |
159 | for(k = 1; k <= myTmpSolCount; k++) |
160 | { |
161 | aFinder.Points(k, sol); |
162 | myPoints1.Append(sol(1)); |
163 | myPoints2.Append(sol(2)); |
164 | } |
165 | mySolCount += myTmpSolCount; |
5493d334 |
166 | } // if (aCurrF > aF - aSameTol * aValueTol) |
4bbaf12b |
167 | else |
168 | { |
169 | aF = aCurrF; |
170 | mySolCount = aFinder.NbExtrema(); |
171 | myPoints1.Clear(); |
172 | myPoints2.Clear(); |
173 | math_Vector sol(1,2); |
174 | for(k = 1; k <= mySolCount; k++) |
175 | { |
176 | aFinder.Points(k, sol); |
177 | myPoints1.Append(sol(1)); |
178 | myPoints2.Append(sol(2)); |
179 | } |
180 | } // else |
5493d334 |
181 | } //if (aCurrF < aF + aSameTol * aValueTol) |
7fd59977 |
182 | } |
183 | } |
184 | |
4bbaf12b |
185 | // Clear solutions clusters if it is necessary. |
186 | for(i = 1; i <= mySolCount - 1; i++) |
187 | { |
188 | for(j = i + 1; j <= mySolCount; j++) |
189 | { |
5493d334 |
190 | if (Abs(myPoints1(i) - myPoints1(j)) < (myUppBorder(1) - myLowBorder(1)) * Precision::Confusion() && |
191 | Abs(myPoints2(i) - myPoints2(j)) < (myUppBorder(2) - myLowBorder(2)) * Precision::Confusion()) |
4bbaf12b |
192 | { |
5493d334 |
193 | // Points with indexes i and j is in same cluster, delete j point from extrema array. |
4bbaf12b |
194 | myPoints1.Remove(j); |
195 | myPoints2.Remove(j); |
196 | j--; |
197 | mySolCount--; |
198 | } |
7fd59977 |
199 | } |
4bbaf12b |
200 | } |
7fd59977 |
201 | |
4bbaf12b |
202 | delete aFunc; |
7fd59977 |
203 | myDone = Standard_True; |
204 | } |
7fd59977 |
205 | |
5493d334 |
206 | //======================================================================= |
207 | //function : IsDone |
208 | //purpose : |
209 | //======================================================================= |
210 | Standard_Boolean Extrema_GenExtCC::IsDone() const |
4bbaf12b |
211 | { |
212 | return myDone; |
213 | } |
7fd59977 |
214 | |
5493d334 |
215 | //======================================================================= |
216 | //function : NbExt |
217 | //purpose : |
218 | //======================================================================= |
219 | Standard_Integer Extrema_GenExtCC::NbExt() const |
7fd59977 |
220 | { |
221 | StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::NbExt()") |
4bbaf12b |
222 | |
223 | return mySolCount; |
7fd59977 |
224 | } |
7fd59977 |
225 | |
5493d334 |
226 | //======================================================================= |
227 | //function : SquareDistance |
228 | //purpose : |
229 | //======================================================================= |
230 | Standard_Real Extrema_GenExtCC::SquareDistance(const Standard_Integer N) const |
7fd59977 |
231 | { |
232 | StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::SquareDistance()") |
233 | Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::SquareDistance()") |
4bbaf12b |
234 | |
235 | return Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)).SquareDistance(Tool2::Value(*((Curve2*)myC[1]), myPoints2(N))); |
7fd59977 |
236 | } |
7fd59977 |
237 | |
5493d334 |
238 | //======================================================================= |
239 | //function : Points |
240 | //purpose : |
241 | //======================================================================= |
242 | void Extrema_GenExtCC::Points(const Standard_Integer N, |
243 | POnC& P1, |
244 | POnC& P2) const |
7fd59977 |
245 | { |
4bbaf12b |
246 | StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::Points()") |
247 | Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::Points()") |
248 | |
249 | P1.SetValues(myPoints1(N), Tool1::Value(*((Curve1*)myC[0]), myPoints1(N))); |
250 | P2.SetValues(myPoints2(N), Tool2::Value(*((Curve2*)myC[1]), myPoints2(N))); |
251 | } |