0026937: Eliminate NO_CXX_EXCEPTION macro support
[occt.git] / src / Extrema / Extrema_ExtPElC2d.cxx
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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <ElCLib.hxx>
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>
33
34 //=============================================================================
35 Extrema_ExtPElC2d::Extrema_ExtPElC2d () { myDone = Standard_False; }
36 //=============================================================================
37
38 Extrema_ExtPElC2d::Extrema_ExtPElC2d 
39   (const gp_Pnt2d&     P, 
40   const gp_Lin2d&     L,
41   const Standard_Real Tol,
42   const Standard_Real Uinf, 
43   const Standard_Real Usup)
44 {
45   Perform(P, L, Tol, Uinf, Usup);
46 }
47
48 void Extrema_ExtPElC2d::Perform(const gp_Pnt2d&     P, 
49   const gp_Lin2d&     L,
50   const Standard_Real Tol,
51   const Standard_Real Uinf, 
52   const Standard_Real Usup)
53 {
54   myDone = Standard_True;
55   gp_Pnt2d OR, MyP;
56   myNbExt = 0;
57
58   gp_Vec2d V1 = gp_Vec2d(L.Direction());
59   OR = L.Location();
60   gp_Vec2d V(OR, P);
61   Standard_Real Mydist = V1.Dot(V);
62   if ((Mydist >= Uinf -Tol) && 
63     (Mydist <= Usup+ Tol)){ 
64       myNbExt = 1;
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;
70   }
71 }
72
73 //=============================================================================
74
75 Extrema_ExtPElC2d::Extrema_ExtPElC2d 
76   (const gp_Pnt2d&     P, 
77   const gp_Circ2d&    C,
78   const Standard_Real Tol,
79   const Standard_Real Uinf, 
80   const Standard_Real Usup)
81 {
82   Perform(P, C, Tol, Uinf, Usup);
83 }
84
85 void Extrema_ExtPElC2d::Perform(const gp_Pnt2d&     P, 
86   const gp_Circ2d&    C,
87   const Standard_Real Tol,
88   const Standard_Real Uinf, 
89   const Standard_Real Usup)
90 {
91   //  gp_Pnt2d OC, P1, P2, OL;
92   gp_Pnt2d OC(C.Location());
93   myNbExt = 0;
94
95   if (OC.IsEqual(P, Precision::Confusion())) {
96     myDone = Standard_False;
97   }
98   else
99   {
100     Standard_Real radius, U1, U2;
101     gp_Pnt2d P1, P2;
102
103     myDone = Standard_True;
104     gp_Dir2d V(gp_Vec2d(P, OC));
105     radius = C.Radius();
106     P1 = OC.Translated(radius*V);
107     U1 = ElCLib::Parameter(C, P1);
108     U2 = U1 + M_PI;
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))
114     {
115       U1 = Uinf;
116       P1 = OC.XY() + radius * (cos(U1) * C.XAxis().Direction().XY() + sin(U1) * C.YAxis().Direction().XY());
117     }
118
119     if (((U2-2*M_PI-Uinf) < Tol) && ((U2-2*M_PI-Uinf) > -Tol))
120     {
121       U2 = Uinf;
122       P2 = OC.XY() + radius * (cos(U2) * C.XAxis().Direction().XY() + sin(U2) * C.YAxis().Direction().XY());
123     }
124
125     if (((Uinf-U1) < Tol) && ((U1-Usup) < Tol))
126     {
127       Extrema_POnCurv2d MyPOnCurve(U1, P1);
128       mySqDist[0] = P.SquareDistance(P1);
129       myPoint[0] = MyPOnCurve;
130       myIsMin[0] = Standard_True;
131       myNbExt++;
132     }
133
134     if (((Uinf-U2) < Tol) && ((U2-Usup) < Tol))
135     {
136       Extrema_POnCurv2d MyPOnCurve(U2, P2);
137       mySqDist[myNbExt] = P.SquareDistance(P2);
138       myPoint[myNbExt] = MyPOnCurve;
139       myIsMin[myNbExt] = Standard_True;
140       myNbExt++;
141     }
142   }
143 }
144
145 //=============================================================================
146
147
148 Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d&     P, 
149   const gp_Elips2d&   E,
150   const Standard_Real Tol,
151   const Standard_Real Uinf, 
152   const Standard_Real Usup)
153 {
154   Perform(P, E, Tol, Uinf, Usup);
155 }
156
157
158
159 void Extrema_ExtPElC2d::Perform (const gp_Pnt2d&     P, 
160   const gp_Elips2d&   E,
161   const Standard_Real Tol,
162   const Standard_Real Uinf, 
163   const Standard_Real Usup)
164 {
165   //  gp_Pnt2d OR, P1, P2;
166   gp_Pnt2d OR;
167   OR = E.Location();
168
169   Standard_Integer NoSol, NbSol;
170   Standard_Real A = E.MajorRadius();
171   Standard_Real B = E.MinorRadius();
172   gp_Vec2d V(OR,P);
173
174   if (OR.IsEqual(P, Precision::Confusion()) &&
175     (Abs(A-B) <= Tol)) {
176       myDone = Standard_False;
177   }
178   else {
179     Standard_Real X = V.Dot(gp_Vec2d(E.XAxis().Direction()));
180     Standard_Real Y = V.Dot(gp_Vec2d(E.YAxis().Direction()));
181
182     math_TrigonometricFunctionRoots Sol(0.,(B*B-A*A)/2.,-B*Y,A*X,0.,Uinf,Usup);
183
184     if (!Sol.IsDone()) { return; }
185     gp_Pnt2d Cu;
186     Standard_Real Us;
187     NbSol = Sol.NbSolutions();
188     myNbExt = 0;
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);
195       myNbExt++;
196     }
197     myDone = Standard_True;
198   }
199 }
200 //=============================================================================
201
202 Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d&     P, 
203   const gp_Hypr2d&    C,
204   const Standard_Real Tol,
205   const Standard_Real Uinf, 
206   const Standard_Real Usup)
207 {
208   Perform(P, C, Tol, Uinf, Usup);
209 }
210
211
212 void Extrema_ExtPElC2d::Perform(const gp_Pnt2d&     P, 
213   const gp_Hypr2d&    H,
214   const Standard_Real Tol,
215   const Standard_Real Uinf,
216   const Standard_Real Usup)
217 {
218   gp_Pnt2d O = H.Location();
219   myDone = Standard_False;
220   myNbExt = 0;
221
222   Standard_Real R = H.MajorRadius();
223   Standard_Real r = H.MinorRadius();
224   gp_Vec2d OPp(O,P);
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; }
231   gp_Pnt2d Cu;
232   Standard_Real Us, Vs;
233   Standard_Integer NbSol = Sol.NbSolutions();
234   Standard_Boolean DejaEnr;
235   Standard_Integer NoExt;
236   gp_Pnt2d TbExt[4];
237   for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) {
238     Vs = Sol.Value(NoSol);
239     if (Vs > 0.) {
240       Us = Log(Vs);
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;
247             break;
248           }
249         }
250         if (!DejaEnr) {
251           TbExt[myNbExt] = Cu;
252           mySqDist[myNbExt] = Cu.SquareDistance(P);
253           myIsMin[myNbExt] = (NoSol == 0);
254           myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
255           myNbExt++;
256         }
257       } // if ((Us >= Uinf) && (Us <= Usup))
258     } // if (Vs > 0.)
259   } // for (Standard_Integer NoSol = 1; ...
260   myDone = Standard_True;
261 }
262
263 //=============================================================================
264
265 Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d&     P, 
266   const gp_Parab2d&   C,
267   const Standard_Real Tol,
268   const Standard_Real Uinf, 
269   const Standard_Real Usup)
270 {
271   Perform(P, C, Tol, Uinf, Usup);
272 }
273
274
275 void Extrema_ExtPElC2d::Perform(const gp_Pnt2d&     P,
276   const gp_Parab2d&   C,
277   const Standard_Real Tol,
278   const Standard_Real Uinf, 
279   const Standard_Real Usup)
280 {
281   myDone = Standard_False;
282   myNbExt = 0;
283   gp_Pnt2d O = C.Location();
284
285   Standard_Real Tol2 = Tol * Tol;
286   Standard_Real F = C.Focal();
287   gp_Vec2d OPp (O,P);
288   Standard_Real X = OPp.Dot(gp_Vec2d(C.MirrorAxis().Direction()));
289   Standard_Real Y = OPp.Dot(gp_Vec2d(C.Axis().YAxis().Direction()));
290
291   math_DirectPolynomialRoots Sol(1./(4.*F),0.,2.*F-X,-2.*F*Y);
292   if (!Sol.IsDone()) { return; }
293   gp_Pnt2d Cu;
294   Standard_Real Us;
295   Standard_Integer NbSol = Sol.NbSolutions();
296   Standard_Boolean DejaEnr;
297   Standard_Integer NoExt;
298   gp_Pnt2d TbExt[3];
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;
307           break;
308         }
309       }
310       if (!DejaEnr) {
311         TbExt[myNbExt] = Cu;
312         mySqDist[myNbExt] = Cu.SquareDistance(P);
313         myIsMin[myNbExt] = (NoSol == 0);
314         myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
315         myNbExt++;
316       }
317     } // if ((Us >= Uinf) && (Us <= Usup))
318   } // for (Standard_Integer NoSol = 1; ...
319   myDone = Standard_True;
320 }
321 //=============================================================================
322
323 Standard_Boolean Extrema_ExtPElC2d::IsDone () const { return myDone; }
324 //=============================================================================
325
326 Standard_Integer Extrema_ExtPElC2d::NbExt () const
327 {
328   if (!IsDone()) { throw StdFail_NotDone(); }
329   return myNbExt;
330 }
331 //=============================================================================
332
333 Standard_Real Extrema_ExtPElC2d::SquareDistance (const Standard_Integer N) const
334 {
335   if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); }
336   return mySqDist[N-1];
337 }
338 //=============================================================================
339
340 Standard_Boolean Extrema_ExtPElC2d::IsMin (const Standard_Integer N) const
341 {
342   if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); }
343   return myIsMin[N-1];
344 }
345 //=============================================================================
346
347 const Extrema_POnCurv2d& Extrema_ExtPElC2d::Point (const Standard_Integer N) const
348 {
349   if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); }
350   return myPoint[N-1];
351 }
352 //=============================================================================