0023964: Extrema_ExtXX::Point methods might return constant reference instead of...
[occt.git] / src / Extrema / Extrema_ExtPElC2d.cxx
CommitLineData
b311480e 1// Created on: 1993-12-13
2// Created by: Christophe MARION
3// Copyright (c) 1993-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21
22#include <Precision.hxx>
23#include <Extrema_ExtPElC2d.ixx>
24#include <StdFail_NotDone.hxx>
25#include <math_DirectPolynomialRoots.hxx>
26#include <math_TrigonometricFunctionRoots.hxx>
27#include <ElCLib.hxx>
28#include <Standard_OutOfRange.hxx>
29#include <Standard_NotImplemented.hxx>
30//=============================================================================
31
32Extrema_ExtPElC2d::Extrema_ExtPElC2d () { myDone = Standard_False; }
33//=============================================================================
34
35Extrema_ExtPElC2d::Extrema_ExtPElC2d
36 (const gp_Pnt2d& P,
37 const gp_Lin2d& L,
38 const Standard_Real Tol,
39 const Standard_Real Uinf,
40 const Standard_Real Usup)
41{
42 Perform(P, L, Tol, Uinf, Usup);
43}
44
45void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
46 const gp_Lin2d& L,
47 const Standard_Real Tol,
48 const Standard_Real Uinf,
49 const Standard_Real Usup)
50{
51 myDone = Standard_True;
52 gp_Pnt2d OR, MyP;
53 myNbExt = 0;
54
55 gp_Vec2d V1 = gp_Vec2d(L.Direction());
56 OR = L.Location();
57 gp_Vec2d V(OR, P);
58 Standard_Real Mydist = V1.Dot(V);
59 if ((Mydist >= Uinf -Tol) &&
60 (Mydist <= Usup+ Tol)){
61 myNbExt = 1;
62 MyP = OR.Translated(Mydist*V1);
63 Extrema_POnCurv2d MyPOnCurve(Mydist, MyP);
64 mySqDist[0] = P.SquareDistance(MyP);
65 myPoint[0] = MyPOnCurve;
66 myIsMin[0] = Standard_True;
67 }
68}
69
70//=============================================================================
71
72Extrema_ExtPElC2d::Extrema_ExtPElC2d
73 (const gp_Pnt2d& P,
74 const gp_Circ2d& C,
75 const Standard_Real Tol,
76 const Standard_Real Uinf,
77 const Standard_Real Usup)
78{
79 Perform(P, C, Tol, Uinf, Usup);
80}
81
82void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
83 const gp_Circ2d& C,
84 const Standard_Real Tol,
85 const Standard_Real Uinf,
86 const Standard_Real Usup)
87{
88 Standard_Real radius, U1, U2;
89// gp_Pnt2d OC, P1, P2, OL;
90 gp_Pnt2d OC, P1, P2;
91 OC = C.Location();
92 myNbExt = 0;
93
94 if (OC.IsEqual(P, Precision::Confusion())) {
95 myDone = Standard_False;
96 }
97 else {
98 myDone = Standard_True;
99 gp_Dir2d V(gp_Vec2d(P, OC));
100 radius = C.Radius();
101 P1 = OC.Translated(radius*V);
102 U1 = ElCLib::Parameter(C, P1);
c6541a0c 103 U2 = U1 + M_PI;
7fd59977 104 P2 = OC.Translated(-radius*V);
105 Standard_Real myuinf = Uinf;
c6541a0c
D
106 ElCLib::AdjustPeriodic(Uinf, Uinf+2*M_PI, Precision::PConfusion(), myuinf, U1);
107 ElCLib::AdjustPeriodic(Uinf, Uinf+2*M_PI, Precision::PConfusion(), myuinf, U2);
108 if (((U1-2*M_PI-Uinf) < Tol) && ((U1-2*M_PI-Uinf) > -Tol)) U1 = Uinf;
109 if (((U2-2*M_PI-Uinf) < Tol) && ((U2-2*M_PI-Uinf) > -Tol)) U2 = Uinf;
7fd59977 110
111 if (((Uinf-U1) < Tol) && ((U1-Usup) < Tol)) {
112 Extrema_POnCurv2d MyPOnCurve(U1, P1);
113 mySqDist[0] = P.SquareDistance(P1);
114 myPoint[0] = MyPOnCurve;
115 myIsMin[0] = Standard_True;
116 myNbExt++;
117 }
118
119 if (((Uinf-U2) < Tol) && ((U2-Usup) < Tol)) {
120 Extrema_POnCurv2d MyPOnCurve(U2, P2);
121 mySqDist[myNbExt] = P.SquareDistance(P2);
122 myPoint[myNbExt] = MyPOnCurve;
123 myIsMin[myNbExt] = Standard_True;
124 myNbExt++;
125 }
126 }
127}
128
129//=============================================================================
130
131
132Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P,
133 const gp_Elips2d& E,
134 const Standard_Real Tol,
135 const Standard_Real Uinf,
136 const Standard_Real Usup)
137{
138 Perform(P, E, Tol, Uinf, Usup);
139}
140
141
142
143void Extrema_ExtPElC2d::Perform (const gp_Pnt2d& P,
144 const gp_Elips2d& E,
145 const Standard_Real Tol,
146 const Standard_Real Uinf,
147 const Standard_Real Usup)
148{
149// gp_Pnt2d OR, P1, P2;
150 gp_Pnt2d OR;
151 OR = E.Location();
152
153 Standard_Integer NoSol, NbSol;
154 Standard_Real A = E.MajorRadius();
155 Standard_Real B = E.MinorRadius();
156 gp_Vec2d V(OR,P);
157
158 if (OR.IsEqual(P, Precision::Confusion()) &&
159 (Abs(A-B) <= Tol)) {
160 myDone = Standard_False;
161 }
162 else {
7fd59977 163 Standard_Real X = V.Dot(gp_Vec2d(E.XAxis().Direction()));
164 Standard_Real Y = V.Dot(gp_Vec2d(E.YAxis().Direction()));
165
166 math_TrigonometricFunctionRoots Sol(0.,(B*B-A*A)/2.,-B*Y,A*X,0.,Uinf,Usup);
167
168 if (!Sol.IsDone()) { return; }
169 gp_Pnt2d Cu;
170 Standard_Real Us;
171 NbSol = Sol.NbSolutions();
172 myNbExt = 0;
173 for (NoSol = 1; NoSol <= NbSol; NoSol++) {
174 Us = Sol.Value(NoSol);
175 Cu = ElCLib::Value(Us, E);
176 mySqDist[myNbExt] = Cu.SquareDistance(P);
177 myIsMin[myNbExt] = (NoSol == 0);
178 myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
179 myNbExt++;
180 }
181 myDone = Standard_True;
182 }
183}
184//=============================================================================
185
186Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P,
187 const gp_Hypr2d& C,
188 const Standard_Real Tol,
189 const Standard_Real Uinf,
190 const Standard_Real Usup)
191{
192 Perform(P, C, Tol, Uinf, Usup);
193}
194
195
196void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
197 const gp_Hypr2d& H,
198 const Standard_Real Tol,
199 const Standard_Real Uinf,
200 const Standard_Real Usup)
201{
202 gp_Pnt2d O = H.Location();
203 myDone = Standard_False;
204 myNbExt = 0;
205
206 Standard_Real R = H.MajorRadius();
207 Standard_Real r = H.MinorRadius();
208 gp_Vec2d OPp(O,P);
7fd59977 209 Standard_Real Tol2 = Tol * Tol;
210 Standard_Real X = OPp.Dot(gp_Vec2d(H.XAxis().Direction()));
211 Standard_Real Y = OPp.Dot(gp_Vec2d(H.YAxis().Direction()));
212 Standard_Real C1 = (R*R+r*r)/4.;
213 math_DirectPolynomialRoots Sol(C1,-(X*R+Y*r)/2.,0.,(X*R-Y*r)/2.,-C1);
214 if (!Sol.IsDone()) { return; }
215 gp_Pnt2d Cu;
216 Standard_Real Us, Vs;
217 Standard_Integer NbSol = Sol.NbSolutions();
218 Standard_Boolean DejaEnr;
219 Standard_Integer NoExt;
220 gp_Pnt2d TbExt[4];
221 for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) {
222 Vs = Sol.Value(NoSol);
223 if (Vs > 0.) {
224 Us = Log(Vs);
225 if ((Us >= Uinf) && (Us <= Usup)) {
226 Cu = ElCLib::Value(Us,H);
227 DejaEnr = Standard_False;
228 for (NoExt = 0; NoExt < myNbExt; NoExt++) {
229 if (TbExt[NoExt].SquareDistance(Cu) < Tol2) {
230 DejaEnr = Standard_True;
231 break;
232 }
233 }
234 if (!DejaEnr) {
235 TbExt[myNbExt] = Cu;
236 mySqDist[myNbExt] = Cu.SquareDistance(P);
237 myIsMin[myNbExt] = (NoSol == 0);
238 myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
239 myNbExt++;
240 }
241 } // if ((Us >= Uinf) && (Us <= Usup))
242 } // if (Vs > 0.)
243 } // for (Standard_Integer NoSol = 1; ...
244 myDone = Standard_True;
245}
246
247//=============================================================================
248
249Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P,
250 const gp_Parab2d& C,
251 const Standard_Real Tol,
252 const Standard_Real Uinf,
253 const Standard_Real Usup)
254{
255 Perform(P, C, Tol, Uinf, Usup);
256}
257
258
259void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
260 const gp_Parab2d& C,
261 const Standard_Real Tol,
262 const Standard_Real Uinf,
263 const Standard_Real Usup)
264{
265 myDone = Standard_False;
266 myNbExt = 0;
267 gp_Pnt2d O = C.Location();
268
269 Standard_Real Tol2 = Tol * Tol;
270 Standard_Real F = C.Focal();
271 gp_Vec2d OPp (O,P);
7fd59977 272 Standard_Real X = OPp.Dot(gp_Vec2d(C.MirrorAxis().Direction()));
273 Standard_Real Y = OPp.Dot(gp_Vec2d(C.Axis().YAxis().Direction()));
274
275 math_DirectPolynomialRoots Sol(1./(4.*F),0.,2.*F-X,-2.*F*Y);
276 if (!Sol.IsDone()) { return; }
277 gp_Pnt2d Cu;
278 Standard_Real Us;
279 Standard_Integer NbSol = Sol.NbSolutions();
280 Standard_Boolean DejaEnr;
281 Standard_Integer NoExt;
282 gp_Pnt2d TbExt[3];
283 for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) {
284 Us = Sol.Value(NoSol);
285 if ((Us >= Uinf) && (Us <= Usup)) {
286 Cu = ElCLib::Value(Us,C);
287 DejaEnr = Standard_False;
288 for (NoExt = 0; NoExt < myNbExt; NoExt++) {
289 if (TbExt[NoExt].SquareDistance(Cu) < Tol2) {
290 DejaEnr = Standard_True;
291 break;
292 }
293 }
294 if (!DejaEnr) {
295 TbExt[myNbExt] = Cu;
296 mySqDist[myNbExt] = Cu.SquareDistance(P);
297 myIsMin[myNbExt] = (NoSol == 0);
298 myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
299 myNbExt++;
300 }
301 } // if ((Us >= Uinf) && (Us <= Usup))
302 } // for (Standard_Integer NoSol = 1; ...
303 myDone = Standard_True;
304}
305//=============================================================================
306
307Standard_Boolean Extrema_ExtPElC2d::IsDone () const { return myDone; }
308//=============================================================================
309
310Standard_Integer Extrema_ExtPElC2d::NbExt () const
311{
312 if (!IsDone()) { StdFail_NotDone::Raise(); }
313 return myNbExt;
314}
315//=============================================================================
316
317Standard_Real Extrema_ExtPElC2d::SquareDistance (const Standard_Integer N) const
318{
319 if ((N < 1) || (N > NbExt())) { Standard_OutOfRange::Raise(); }
320 return mySqDist[N-1];
321}
322//=============================================================================
323
324Standard_Boolean Extrema_ExtPElC2d::IsMin (const Standard_Integer N) const
325{
326 if ((N < 1) || (N > NbExt())) { Standard_OutOfRange::Raise(); }
327 return myIsMin[N-1];
328}
329//=============================================================================
330
5d99f2c8 331const Extrema_POnCurv2d& Extrema_ExtPElC2d::Point (const Standard_Integer N) const
7fd59977 332{
333 if ((N < 1) || (N > NbExt())) { Standard_OutOfRange::Raise(); }
334 return myPoint[N-1];
335}
336//=============================================================================