7dc0a9d4ed6cd59b4a00d0dbadf8e8b9e98064c7
[occt.git] / src / GccGeo / GccGeo_Circ2dTanCen.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <StdFail_NotDone.hxx>
16 #include <Standard_OutOfRange.hxx>
17 #include <Standard_Failure.hxx>
18 #include <gp.hxx>
19 #include <gp_Ax2d.hxx>
20 #include <gp_Vec2d.hxx>
21 #include <TColStd_Array1OfInteger.hxx>
22 #include <TColStd_Array1OfReal.hxx>
23 #include <Extrema_POnCurv2d.hxx>
24
25 //=========================================================================
26 //   Creation d un cercle tangent a une courbe centre en un point.        +
27 //=========================================================================
28
29 GccGeo_Circ2dTanCen::
30    GccGeo_Circ2dTanCen (const TheQualifiedCurve& Qualified1,
31                         const gp_Pnt2d&          Pcenter   ,
32                         const Standard_Real      Tolerance ):
33
34 //========================================================================
35 //   Initialisation des champs.                                          +
36 //========================================================================
37
38    cirsol(1,2)    ,
39    qualifier1(1,2),
40    pnttg1sol(1,2) ,
41    par1sol(1,2)   ,
42    pararg1(1,2)   
43 {
44
45   Standard_Real Tol = Abs(Tolerance);
46   TColgp_Array1OfPnt2d pTan(1,2);
47   TColStd_Array1OfInteger Index(1,2);
48   TColStd_Array1OfReal theDist2(1,2);
49   TColStd_Array1OfReal theParam(1,2);
50   theDist2(1) = RealLast();
51   theDist2(2) = 0.;
52   Standard_Integer i = 1;
53   Standard_Integer nbsol = 0;
54   gp_Dir2d dirx(1.0,0.0);
55   Standard_Real thePar;
56   TheCurve curve = Qualified1.Qualified();
57   TheExtPC distmin(Pcenter,curve,TheCurveTool::NbSamples(curve),
58                    TheCurveTool::EpsX(curve,Tol),Tol);
59   if (!distmin.IsDone() ) { Standard_Failure::Raise(); }
60   Standard_Integer nbext = distmin.NbExt();
61   if(nbext==0) { Standard_Failure::Raise(); }
62   while (i<=nbext) {
63     thePar = distmin.Point(i).Parameter();
64     if (distmin.SquareDistance(i)<theDist2(1) && 
65         thePar>=TheCurveTool::FirstParameter(curve) && 
66         thePar <= TheCurveTool::LastParameter(curve)) {
67       theDist2(1) = distmin.SquareDistance(i);
68       theParam(1) = thePar;
69       pTan(1) = distmin.Point(i).Value();
70     }
71     if (distmin.SquareDistance(i)>theDist2(2) && 
72         thePar>=TheCurveTool::FirstParameter(curve) && 
73         thePar <= TheCurveTool::LastParameter(curve)) {
74       theDist2(2) = distmin.SquareDistance(i);
75       theParam(2) = thePar;
76       pTan(2) = distmin.Point(i).Value();
77     }
78     i++;
79   }
80   if (Index(1) == Index(2)) { nbsol = 1; }
81   else { nbsol = 2; }
82   for (i = 1 ; i <= nbsol; i++) {
83     gp_Pnt2d point1;
84     gp_Vec2d Tan1;
85     TheCurveTool::D1(curve,theParam(i),point1,Tan1);
86     Standard_Real normetan1 = Tan1.Magnitude();
87     gp_Vec2d Vec1(point1,Pcenter);
88     Standard_Real normevec1 = Vec1.Magnitude();
89     Standard_Real dot1;
90     if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
91       dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
92     }
93     else { dot1 = 0.; }
94     Tol = 1.e-12;
95     if (dot1 <= Tol) {
96       Standard_Real Angle1 = Vec1.Angle(Tan1);
97       if (Qualified1.IsUnqualified()||
98           (Qualified1.IsEnclosing()&&Angle1<=0.)||
99           (Qualified1.IsOutside() && Angle1 >= 0.) ||
100           (Qualified1.IsEnclosed() && Angle1 <= 0.)) {
101         NbrSol++;
102         cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),sqrt (theDist2(i)));
103         qualifier1(NbrSol) = Qualified1.Qualifier();
104         pararg1(NbrSol) = theParam(i);
105         par1sol(NbrSol) = 0.;
106         pnttg1sol(NbrSol) = pTan(i);
107         WellDone = Standard_True;
108       }
109     }
110   }
111 }
112
113
114
115 //=========================================================================
116
117
118 Standard_Boolean GccGeo_Circ2dTanCen::
119    IsDone () const { return WellDone; }
120
121 Standard_Integer GccGeo_Circ2dTanCen::
122    NbSolutions () const { return NbrSol; }
123
124 gp_Circ2d GccGeo_Circ2dTanCen::
125    ThisSolution (const Standard_Integer Index) const 
126 {
127   if (Index > NbrSol || Index <= 0) Standard_OutOfRange::Raise();
128
129   return cirsol(Index);
130 }
131
132 void GccGeo_Circ2dTanCen::
133   WhichQualifier(const Standard_Integer Index   ,
134                        GccEnt_Position& Qualif1 ) const
135 {
136   if (!WellDone) { StdFail_NotDone::Raise(); }
137   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
138   else {
139     Qualif1 = qualifier1(Index);
140   }
141 }
142
143 void GccGeo_Circ2dTanCen::
144    Tangency1 (const Standard_Integer Index,
145                     Standard_Real&   ParSol,
146                     Standard_Real&   ParArg,
147               gp_Pnt2d& PntSol) const{
148    if (!WellDone) {
149      StdFail_NotDone::Raise();
150    }
151    else if (Index <= 0 ||Index > NbrSol) {
152      Standard_OutOfRange::Raise();
153    }
154    else {
155      PntSol = gp_Pnt2d(pnttg1sol(Index));
156      ParSol = par1sol(Index);
157      ParArg = pararg1(Index);
158    }
159  }
160