0031687: Draw Harness, ViewerTest - extend command vrenderparams with option updating...
[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
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
42cf5bc1 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>
7fd59977 27#include <math_DirectPolynomialRoots.hxx>
28#include <math_TrigonometricFunctionRoots.hxx>
42cf5bc1 29#include <Precision.hxx>
7fd59977 30#include <Standard_NotImplemented.hxx>
42cf5bc1 31#include <Standard_OutOfRange.hxx>
32#include <StdFail_NotDone.hxx>
7fd59977 33
42cf5bc1 34//=============================================================================
638ad7f3 35Extrema_ExtPElC2d::Extrema_ExtPElC2d()
36{
37 myDone = Standard_False;
38 myNbExt = 0;
39
40 for (Standard_Integer i = 0; i < 4; i++)
41 {
42 mySqDist[i] = RealLast();
43 myIsMin[i] = Standard_False;
44 }
45}
46
7fd59977 47//=============================================================================
48
49Extrema_ExtPElC2d::Extrema_ExtPElC2d
50 (const gp_Pnt2d& P,
73cd8a8a 51 const gp_Lin2d& L,
52 const Standard_Real Tol,
53 const Standard_Real Uinf,
54 const Standard_Real Usup)
7fd59977 55{
56 Perform(P, L, Tol, Uinf, Usup);
57}
58
59void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
73cd8a8a 60 const gp_Lin2d& L,
61 const Standard_Real Tol,
62 const Standard_Real Uinf,
63 const Standard_Real Usup)
7fd59977 64{
65 myDone = Standard_True;
66 gp_Pnt2d OR, MyP;
67 myNbExt = 0;
68
69 gp_Vec2d V1 = gp_Vec2d(L.Direction());
70 OR = L.Location();
71 gp_Vec2d V(OR, P);
72 Standard_Real Mydist = V1.Dot(V);
73 if ((Mydist >= Uinf -Tol) &&
73cd8a8a 74 (Mydist <= Usup+ Tol)){
75 myNbExt = 1;
76 MyP = OR.Translated(Mydist*V1);
77 Extrema_POnCurv2d MyPOnCurve(Mydist, MyP);
78 mySqDist[0] = P.SquareDistance(MyP);
79 myPoint[0] = MyPOnCurve;
80 myIsMin[0] = Standard_True;
7fd59977 81 }
82}
83
84//=============================================================================
85
86Extrema_ExtPElC2d::Extrema_ExtPElC2d
87 (const gp_Pnt2d& P,
73cd8a8a 88 const gp_Circ2d& C,
89 const Standard_Real Tol,
90 const Standard_Real Uinf,
91 const Standard_Real Usup)
7fd59977 92{
93 Perform(P, C, Tol, Uinf, Usup);
94}
95
96void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
73cd8a8a 97 const gp_Circ2d& C,
98 const Standard_Real Tol,
99 const Standard_Real Uinf,
100 const Standard_Real Usup)
7fd59977 101{
73cd8a8a 102 // gp_Pnt2d OC, P1, P2, OL;
103 gp_Pnt2d OC(C.Location());
7fd59977 104 myNbExt = 0;
73cd8a8a 105
7fd59977 106 if (OC.IsEqual(P, Precision::Confusion())) {
107 myDone = Standard_False;
108 }
73cd8a8a 109 else
110 {
111 Standard_Real radius, U1, U2;
112 gp_Pnt2d P1, P2;
113
7fd59977 114 myDone = Standard_True;
115 gp_Dir2d V(gp_Vec2d(P, OC));
116 radius = C.Radius();
117 P1 = OC.Translated(radius*V);
118 U1 = ElCLib::Parameter(C, P1);
c6541a0c 119 U2 = U1 + M_PI;
7fd59977 120 P2 = OC.Translated(-radius*V);
121 Standard_Real myuinf = Uinf;
c6541a0c
D
122 ElCLib::AdjustPeriodic(Uinf, Uinf+2*M_PI, Precision::PConfusion(), myuinf, U1);
123 ElCLib::AdjustPeriodic(Uinf, Uinf+2*M_PI, Precision::PConfusion(), myuinf, U2);
73cd8a8a 124 if (((U1-2*M_PI-Uinf) < Tol) && ((U1-2*M_PI-Uinf) > -Tol))
125 {
126 U1 = Uinf;
127 P1 = OC.XY() + radius * (cos(U1) * C.XAxis().Direction().XY() + sin(U1) * C.YAxis().Direction().XY());
128 }
7fd59977 129
73cd8a8a 130 if (((U2-2*M_PI-Uinf) < Tol) && ((U2-2*M_PI-Uinf) > -Tol))
131 {
132 U2 = Uinf;
133 P2 = OC.XY() + radius * (cos(U2) * C.XAxis().Direction().XY() + sin(U2) * C.YAxis().Direction().XY());
134 }
135
136 if (((Uinf-U1) < Tol) && ((U1-Usup) < Tol))
137 {
7fd59977 138 Extrema_POnCurv2d MyPOnCurve(U1, P1);
139 mySqDist[0] = P.SquareDistance(P1);
140 myPoint[0] = MyPOnCurve;
141 myIsMin[0] = Standard_True;
142 myNbExt++;
143 }
73cd8a8a 144
145 if (((Uinf-U2) < Tol) && ((U2-Usup) < Tol))
146 {
7fd59977 147 Extrema_POnCurv2d MyPOnCurve(U2, P2);
148 mySqDist[myNbExt] = P.SquareDistance(P2);
149 myPoint[myNbExt] = MyPOnCurve;
150 myIsMin[myNbExt] = Standard_True;
151 myNbExt++;
152 }
153 }
154}
155
156//=============================================================================
157
158
159Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P,
73cd8a8a 160 const gp_Elips2d& E,
161 const Standard_Real Tol,
162 const Standard_Real Uinf,
163 const Standard_Real Usup)
7fd59977 164{
165 Perform(P, E, Tol, Uinf, Usup);
166}
167
168
169
170void Extrema_ExtPElC2d::Perform (const gp_Pnt2d& P,
73cd8a8a 171 const gp_Elips2d& E,
172 const Standard_Real Tol,
173 const Standard_Real Uinf,
174 const Standard_Real Usup)
7fd59977 175{
638ad7f3 176 myDone = Standard_False;
177 myNbExt = 0;
73cd8a8a 178 // gp_Pnt2d OR, P1, P2;
7fd59977 179 gp_Pnt2d OR;
180 OR = E.Location();
73cd8a8a 181
7fd59977 182 Standard_Integer NoSol, NbSol;
183 Standard_Real A = E.MajorRadius();
184 Standard_Real B = E.MinorRadius();
185 gp_Vec2d V(OR,P);
186
187 if (OR.IsEqual(P, Precision::Confusion()) &&
73cd8a8a 188 (Abs(A-B) <= Tol)) {
638ad7f3 189 return;
7fd59977 190 }
191 else {
7fd59977 192 Standard_Real X = V.Dot(gp_Vec2d(E.XAxis().Direction()));
193 Standard_Real Y = V.Dot(gp_Vec2d(E.YAxis().Direction()));
194
195 math_TrigonometricFunctionRoots Sol(0.,(B*B-A*A)/2.,-B*Y,A*X,0.,Uinf,Usup);
196
197 if (!Sol.IsDone()) { return; }
198 gp_Pnt2d Cu;
199 Standard_Real Us;
200 NbSol = Sol.NbSolutions();
201 myNbExt = 0;
202 for (NoSol = 1; NoSol <= NbSol; NoSol++) {
203 Us = Sol.Value(NoSol);
204 Cu = ElCLib::Value(Us, E);
205 mySqDist[myNbExt] = Cu.SquareDistance(P);
206 myIsMin[myNbExt] = (NoSol == 0);
207 myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
208 myNbExt++;
209 }
210 myDone = Standard_True;
211 }
212}
213//=============================================================================
214
215Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P,
73cd8a8a 216 const gp_Hypr2d& C,
217 const Standard_Real Tol,
218 const Standard_Real Uinf,
219 const Standard_Real Usup)
7fd59977 220{
221 Perform(P, C, Tol, Uinf, Usup);
222}
223
224
225void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
73cd8a8a 226 const gp_Hypr2d& H,
227 const Standard_Real Tol,
228 const Standard_Real Uinf,
229 const Standard_Real Usup)
7fd59977 230{
231 gp_Pnt2d O = H.Location();
232 myDone = Standard_False;
233 myNbExt = 0;
234
235 Standard_Real R = H.MajorRadius();
236 Standard_Real r = H.MinorRadius();
237 gp_Vec2d OPp(O,P);
7fd59977 238 Standard_Real Tol2 = Tol * Tol;
239 Standard_Real X = OPp.Dot(gp_Vec2d(H.XAxis().Direction()));
240 Standard_Real Y = OPp.Dot(gp_Vec2d(H.YAxis().Direction()));
241 Standard_Real C1 = (R*R+r*r)/4.;
242 math_DirectPolynomialRoots Sol(C1,-(X*R+Y*r)/2.,0.,(X*R-Y*r)/2.,-C1);
243 if (!Sol.IsDone()) { return; }
244 gp_Pnt2d Cu;
245 Standard_Real Us, Vs;
246 Standard_Integer NbSol = Sol.NbSolutions();
247 Standard_Boolean DejaEnr;
248 Standard_Integer NoExt;
249 gp_Pnt2d TbExt[4];
250 for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) {
251 Vs = Sol.Value(NoSol);
252 if (Vs > 0.) {
253 Us = Log(Vs);
254 if ((Us >= Uinf) && (Us <= Usup)) {
73cd8a8a 255 Cu = ElCLib::Value(Us,H);
256 DejaEnr = Standard_False;
257 for (NoExt = 0; NoExt < myNbExt; NoExt++) {
258 if (TbExt[NoExt].SquareDistance(Cu) < Tol2) {
259 DejaEnr = Standard_True;
260 break;
261 }
262 }
263 if (!DejaEnr) {
264 TbExt[myNbExt] = Cu;
265 mySqDist[myNbExt] = Cu.SquareDistance(P);
266 myIsMin[myNbExt] = (NoSol == 0);
267 myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
268 myNbExt++;
269 }
7fd59977 270 } // if ((Us >= Uinf) && (Us <= Usup))
271 } // if (Vs > 0.)
272 } // for (Standard_Integer NoSol = 1; ...
273 myDone = Standard_True;
274}
275
276//=============================================================================
277
278Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P,
73cd8a8a 279 const gp_Parab2d& C,
280 const Standard_Real Tol,
281 const Standard_Real Uinf,
282 const Standard_Real Usup)
7fd59977 283{
284 Perform(P, C, Tol, Uinf, Usup);
285}
286
287
288void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
73cd8a8a 289 const gp_Parab2d& C,
290 const Standard_Real Tol,
291 const Standard_Real Uinf,
292 const Standard_Real Usup)
7fd59977 293{
294 myDone = Standard_False;
295 myNbExt = 0;
296 gp_Pnt2d O = C.Location();
297
298 Standard_Real Tol2 = Tol * Tol;
299 Standard_Real F = C.Focal();
300 gp_Vec2d OPp (O,P);
7fd59977 301 Standard_Real X = OPp.Dot(gp_Vec2d(C.MirrorAxis().Direction()));
302 Standard_Real Y = OPp.Dot(gp_Vec2d(C.Axis().YAxis().Direction()));
303
304 math_DirectPolynomialRoots Sol(1./(4.*F),0.,2.*F-X,-2.*F*Y);
305 if (!Sol.IsDone()) { return; }
306 gp_Pnt2d Cu;
307 Standard_Real Us;
308 Standard_Integer NbSol = Sol.NbSolutions();
309 Standard_Boolean DejaEnr;
310 Standard_Integer NoExt;
311 gp_Pnt2d TbExt[3];
312 for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) {
313 Us = Sol.Value(NoSol);
314 if ((Us >= Uinf) && (Us <= Usup)) {
315 Cu = ElCLib::Value(Us,C);
316 DejaEnr = Standard_False;
317 for (NoExt = 0; NoExt < myNbExt; NoExt++) {
73cd8a8a 318 if (TbExt[NoExt].SquareDistance(Cu) < Tol2) {
319 DejaEnr = Standard_True;
320 break;
321 }
7fd59977 322 }
323 if (!DejaEnr) {
73cd8a8a 324 TbExt[myNbExt] = Cu;
325 mySqDist[myNbExt] = Cu.SquareDistance(P);
326 myIsMin[myNbExt] = (NoSol == 0);
327 myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu);
328 myNbExt++;
7fd59977 329 }
330 } // if ((Us >= Uinf) && (Us <= Usup))
331 } // for (Standard_Integer NoSol = 1; ...
332 myDone = Standard_True;
333}
334//=============================================================================
335
336Standard_Boolean Extrema_ExtPElC2d::IsDone () const { return myDone; }
337//=============================================================================
338
339Standard_Integer Extrema_ExtPElC2d::NbExt () const
340{
9775fa61 341 if (!IsDone()) { throw StdFail_NotDone(); }
7fd59977 342 return myNbExt;
343}
344//=============================================================================
345
346Standard_Real Extrema_ExtPElC2d::SquareDistance (const Standard_Integer N) const
347{
9775fa61 348 if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); }
7fd59977 349 return mySqDist[N-1];
350}
351//=============================================================================
352
353Standard_Boolean Extrema_ExtPElC2d::IsMin (const Standard_Integer N) const
354{
9775fa61 355 if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); }
7fd59977 356 return myIsMin[N-1];
357}
358//=============================================================================
359
5d99f2c8 360const Extrema_POnCurv2d& Extrema_ExtPElC2d::Point (const Standard_Integer N) const
7fd59977 361{
9775fa61 362 if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); }
7fd59977 363 return myPoint[N-1];
364}
365//=============================================================================