1 // Created on: 1993-12-13
2 // Created by: Christophe MARION
3 // Copyright (c) 1993-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.
19 #include <Extrema_ExtPElC2d.hxx>
20 #include <Extrema_POnCurv2d.hxx>
21 #include <gp_Circ2d.hxx>
22 #include <gp_Elips2d.hxx>
23 #include <gp_Hypr2d.hxx>
24 #include <gp_Lin2d.hxx>
25 #include <gp_Parab2d.hxx>
26 #include <gp_Pnt2d.hxx>
27 #include <math_DirectPolynomialRoots.hxx>
28 #include <math_TrigonometricFunctionRoots.hxx>
29 #include <Precision.hxx>
30 #include <Standard_NotImplemented.hxx>
31 #include <Standard_OutOfRange.hxx>
32 #include <StdFail_NotDone.hxx>
34 //=============================================================================
35 Extrema_ExtPElC2d::Extrema_ExtPElC2d () { myDone = Standard_False; }
36 //=============================================================================
38 Extrema_ExtPElC2d::Extrema_ExtPElC2d
41 const Standard_Real Tol,
42 const Standard_Real Uinf,
43 const Standard_Real Usup)
45 Perform(P, L, Tol, Uinf, Usup);
48 void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
50 const Standard_Real Tol,
51 const Standard_Real Uinf,
52 const Standard_Real Usup)
54 myDone = Standard_True;
58 gp_Vec2d V1 = gp_Vec2d(L.Direction());
61 Standard_Real Mydist = V1.Dot(V);
62 if ((Mydist >= Uinf -Tol) &&
63 (Mydist <= Usup+ Tol)){
65 MyP = OR.Translated(Mydist*V1);
66 Extrema_POnCurv2d MyPOnCurve(Mydist, MyP);
67 mySqDist[0] = P.SquareDistance(MyP);
68 myPoint[0] = MyPOnCurve;
69 myIsMin[0] = Standard_True;
73 //=============================================================================
75 Extrema_ExtPElC2d::Extrema_ExtPElC2d
78 const Standard_Real Tol,
79 const Standard_Real Uinf,
80 const Standard_Real Usup)
82 Perform(P, C, Tol, Uinf, Usup);
85 void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
87 const Standard_Real Tol,
88 const Standard_Real Uinf,
89 const Standard_Real Usup)
91 // gp_Pnt2d OC, P1, P2, OL;
92 gp_Pnt2d OC(C.Location());
95 if (OC.IsEqual(P, Precision::Confusion())) {
96 myDone = Standard_False;
100 Standard_Real radius, U1, U2;
103 myDone = Standard_True;
104 gp_Dir2d V(gp_Vec2d(P, OC));
106 P1 = OC.Translated(radius*V);
107 U1 = ElCLib::Parameter(C, P1);
109 P2 = OC.Translated(-radius*V);
110 Standard_Real myuinf = Uinf;
111 ElCLib::AdjustPeriodic(Uinf, Uinf+2*M_PI, Precision::PConfusion(), myuinf, U1);
112 ElCLib::AdjustPeriodic(Uinf, Uinf+2*M_PI, Precision::PConfusion(), myuinf, U2);
113 if (((U1-2*M_PI-Uinf) < Tol) && ((U1-2*M_PI-Uinf) > -Tol))
116 P1 = OC.XY() + radius * (cos(U1) * C.XAxis().Direction().XY() + sin(U1) * C.YAxis().Direction().XY());
119 if (((U2-2*M_PI-Uinf) < Tol) && ((U2-2*M_PI-Uinf) > -Tol))
122 P2 = OC.XY() + radius * (cos(U2) * C.XAxis().Direction().XY() + sin(U2) * C.YAxis().Direction().XY());
125 if (((Uinf-U1) < Tol) && ((U1-Usup) < Tol))
127 Extrema_POnCurv2d MyPOnCurve(U1, P1);
128 mySqDist[0] = P.SquareDistance(P1);
129 myPoint[0] = MyPOnCurve;
130 myIsMin[0] = Standard_True;
134 if (((Uinf-U2) < Tol) && ((U2-Usup) < Tol))
136 Extrema_POnCurv2d MyPOnCurve(U2, P2);
137 mySqDist[myNbExt] = P.SquareDistance(P2);
138 myPoint[myNbExt] = MyPOnCurve;
139 myIsMin[myNbExt] = Standard_True;
145 //=============================================================================
148 Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P,
150 const Standard_Real Tol,
151 const Standard_Real Uinf,
152 const Standard_Real Usup)
154 Perform(P, E, Tol, Uinf, Usup);
159 void Extrema_ExtPElC2d::Perform (const gp_Pnt2d& P,
161 const Standard_Real Tol,
162 const Standard_Real Uinf,
163 const Standard_Real Usup)
165 // gp_Pnt2d OR, P1, P2;
169 Standard_Integer NoSol, NbSol;
170 Standard_Real A = E.MajorRadius();
171 Standard_Real B = E.MinorRadius();
174 if (OR.IsEqual(P, Precision::Confusion()) &&
176 myDone = Standard_False;
179 Standard_Real X = V.Dot(gp_Vec2d(E.XAxis().Direction()));
180 Standard_Real Y = V.Dot(gp_Vec2d(E.YAxis().Direction()));
182 math_TrigonometricFunctionRoots Sol(0.,(B*B-A*A)/2.,-B*Y,A*X,0.,Uinf,Usup);
184 if (!Sol.IsDone()) { return; }
187 NbSol = Sol.NbSolutions();
189 for (NoSol = 1; NoSol <= NbSol; NoSol++) {
190 Us = Sol.Value(NoSol);
191 Cu = ElCLib::Value(Us, E);
192 mySqDist[myNbExt] = Cu.SquareDistance(P);
193 myIsMin[myNbExt] = (NoSol == 0);
194 myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
197 myDone = Standard_True;
200 //=============================================================================
202 Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P,
204 const Standard_Real Tol,
205 const Standard_Real Uinf,
206 const Standard_Real Usup)
208 Perform(P, C, Tol, Uinf, Usup);
212 void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
214 const Standard_Real Tol,
215 const Standard_Real Uinf,
216 const Standard_Real Usup)
218 gp_Pnt2d O = H.Location();
219 myDone = Standard_False;
222 Standard_Real R = H.MajorRadius();
223 Standard_Real r = H.MinorRadius();
225 Standard_Real Tol2 = Tol * Tol;
226 Standard_Real X = OPp.Dot(gp_Vec2d(H.XAxis().Direction()));
227 Standard_Real Y = OPp.Dot(gp_Vec2d(H.YAxis().Direction()));
228 Standard_Real C1 = (R*R+r*r)/4.;
229 math_DirectPolynomialRoots Sol(C1,-(X*R+Y*r)/2.,0.,(X*R-Y*r)/2.,-C1);
230 if (!Sol.IsDone()) { return; }
232 Standard_Real Us, Vs;
233 Standard_Integer NbSol = Sol.NbSolutions();
234 Standard_Boolean DejaEnr;
235 Standard_Integer NoExt;
237 for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) {
238 Vs = Sol.Value(NoSol);
241 if ((Us >= Uinf) && (Us <= Usup)) {
242 Cu = ElCLib::Value(Us,H);
243 DejaEnr = Standard_False;
244 for (NoExt = 0; NoExt < myNbExt; NoExt++) {
245 if (TbExt[NoExt].SquareDistance(Cu) < Tol2) {
246 DejaEnr = Standard_True;
252 mySqDist[myNbExt] = Cu.SquareDistance(P);
253 myIsMin[myNbExt] = (NoSol == 0);
254 myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
257 } // if ((Us >= Uinf) && (Us <= Usup))
259 } // for (Standard_Integer NoSol = 1; ...
260 myDone = Standard_True;
263 //=============================================================================
265 Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P,
267 const Standard_Real Tol,
268 const Standard_Real Uinf,
269 const Standard_Real Usup)
271 Perform(P, C, Tol, Uinf, Usup);
275 void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
277 const Standard_Real Tol,
278 const Standard_Real Uinf,
279 const Standard_Real Usup)
281 myDone = Standard_False;
283 gp_Pnt2d O = C.Location();
285 Standard_Real Tol2 = Tol * Tol;
286 Standard_Real F = C.Focal();
288 Standard_Real X = OPp.Dot(gp_Vec2d(C.MirrorAxis().Direction()));
289 Standard_Real Y = OPp.Dot(gp_Vec2d(C.Axis().YAxis().Direction()));
291 math_DirectPolynomialRoots Sol(1./(4.*F),0.,2.*F-X,-2.*F*Y);
292 if (!Sol.IsDone()) { return; }
295 Standard_Integer NbSol = Sol.NbSolutions();
296 Standard_Boolean DejaEnr;
297 Standard_Integer NoExt;
299 for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) {
300 Us = Sol.Value(NoSol);
301 if ((Us >= Uinf) && (Us <= Usup)) {
302 Cu = ElCLib::Value(Us,C);
303 DejaEnr = Standard_False;
304 for (NoExt = 0; NoExt < myNbExt; NoExt++) {
305 if (TbExt[NoExt].SquareDistance(Cu) < Tol2) {
306 DejaEnr = Standard_True;
312 mySqDist[myNbExt] = Cu.SquareDistance(P);
313 myIsMin[myNbExt] = (NoSol == 0);
314 myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
317 } // if ((Us >= Uinf) && (Us <= Usup))
318 } // for (Standard_Integer NoSol = 1; ...
319 myDone = Standard_True;
321 //=============================================================================
323 Standard_Boolean Extrema_ExtPElC2d::IsDone () const { return myDone; }
324 //=============================================================================
326 Standard_Integer Extrema_ExtPElC2d::NbExt () const
328 if (!IsDone()) { throw StdFail_NotDone(); }
331 //=============================================================================
333 Standard_Real Extrema_ExtPElC2d::SquareDistance (const Standard_Integer N) const
335 if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); }
336 return mySqDist[N-1];
338 //=============================================================================
340 Standard_Boolean Extrema_ExtPElC2d::IsMin (const Standard_Integer N) const
342 if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); }
345 //=============================================================================
347 const Extrema_POnCurv2d& Extrema_ExtPElC2d::Point (const Standard_Integer N) const
349 if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); }
352 //=============================================================================