0023964: Extrema_ExtXX::Point methods might return constant reference instead of...
[occt.git] / src / Extrema / Extrema_ExtPSOfRev.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 #include <StdFail_NotDone.hxx>
20 #include <Standard_OutOfRange.hxx>
21 //=============================================================================
22
23 Extrema_ExtPSOfRev::Extrema_ExtPSOfRev (const gp_Pnt& P,
24                               const SurfaceOfRevolution& S,
25                               const Standard_Real Tol,
26                               const Standard_Integer NbV, const Standard_Real TolV)
27 /*-----------------------------------------------------------------------------
28 Fonction:
29    Recherche de toutes les distances extremales entre le point P et la surface
30   de revolution S.
31
32 Methode:
33    Soit Pp la projection du point P dans le plan XOY de la surface S;
34   2 cas sont consideres:
35   1- distance(Pp,O) < Tol:
36      Il existe 0 ou une infinite de solutions; IsDone() = Standard_False;
37   2- distance(Pp,O) > Tol:
38      Soit U1 = angle(OX,OPp) avec 0. < U1 < 2.*M_PI,
39           U2 = U1 + M_PI       avec 0. < U2 < 2.*M_PI,
40           M1 le meridien S(U1),
41           M2 le meridien S(U2);
42      On recherche les distances minimales entre P et M1 et les distances
43      maximales entre P et M2. Soit {V1i,i=1,n} et {V2j, j=1,m} ces solutions;
44      alors les (U1,V1i) correspondent a des distances minimales
45      et    les (U2,V2j) correspondent a des distances maximales.
46 -----------------------------------------------------------------------------*/
47 {
48   myDone = Standard_False;
49
50 // Projection de P dans le plan XOY de la surface de revolution ...
51   gp_Ax3 Pos = Tool::Position(S);
52   gp_Pnt O = Pos.Location();
53   gp_Vec OZ (Pos.Direction());
54   gp_Pnt Pp = P.Translated(OZ.Multiplied(-(gp_Vec(O,P).Dot(OZ))));
55   gp_Vec OPp (O,Pp);
56   if (OPp.Magnitude() < Tol) { return; }
57
58   Standard_Real U1 = gp_Vec(Pos.XDirection()).AngleWithRef(OPp,OZ);
59   Standard_Real U2 = U1 + M_PI;
60   if (U1 < 0.) { U1 += 2. * M_PI; }
61   Curve M1 = Tool::Meridian(S, U1);
62   Curve M2 = Tool::Meridian(S, U2);
63   TheExtPC ExtPM1 (P,M1,NbV,TolV,Tol);
64   TheExtPC ExtPM2 (P,M2,NbV,TolV,Tol);
65   if ((ExtPM1.IsDone()) && (ExtPM2.IsDone())) {
66     Standard_Integer NbExt1 = ExtPM1.NbExt();
67     Standard_Integer NbExt2 = ExtPM2.NbExt();
68     Extrema_POnCurv ExtPM;
69     for (Standard_Integer NoExt = 1; NoExt <= NbExt1; NoExt++) {
70       if (ExtPM1.IsMin(NoExt)) {
71         ExtPM = ExtPM1.Point(NoExt);
72         mySqDist.Append(ExtPM1.SquareDistance(NoExt));
73         myPoint.Append(Extrema_POnSurf(U1,ExtPM.Parameter(),ExtPM.SquareDistance()));
74       }
75     }
76     for (NoExt = 1; NoExt <= NbExt2; NoExt++) {
77       if (!ExtPM2.IsMin(NoExt)) {
78         ExtPM = ExtPM2.Point(NoExt);
79         mySqDist.Append(ExtPM2.SquareDistance(NoExt));
80         myPoint.Append(Extrema_POnSurf(U2,ExtPM.Parameter(),ExtPM.SquareDistance()));
81       }
82     }
83     myDone = Standard_True;
84   }
85 }
86 //=============================================================================
87
88 Standard_Boolean Extrema_ExtPSOfRev::IsDone () const { return myDone; }
89 //=============================================================================
90
91 Standard_Integer Extrema_ExtPSOfRev::NbExt () const
92 {
93   if (!IsDone()) { StdFail_NotDone::Raise(); }
94   return mySqDist.Length();
95 }
96 //=============================================================================
97
98 Standard_Real Extrema_ExtPSOfRev::SquareDistance (const Standard_Integer N) const
99 {
100   if (!IsDone()) { StdFail_NotDone::Raise(); }
101   return mySqDist.Value(N);
102 }
103 //=============================================================================
104
105 const Extrema_POnSurf& Extrema_ExtPSOfRev::Point (const Standard_Integer N) const
106 {
107   if (!IsDone()) { StdFail_NotDone::Raise(); }
108   return myPoint.Value(N);
109 }
110 //=============================================================================