d7487d39dfefe4fa74a8f2db391c8e3e28bbeef4
[occt.git] / src / Geom2dGcc / Geom2dGcc_Circ2dTanCenGeo.cxx
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
16 #include <Extrema_ExtPC2d.hxx>
17 #include <Extrema_POnCurv2d.hxx>
18 #include <GccEnt_BadQualifier.hxx>
19 #include <Geom2dGcc_Circ2dTanCenGeo.hxx>
20 #include <Geom2dGcc_CurveTool.hxx>
21 #include <Geom2dGcc_QCurve.hxx>
22 #include <gp.hxx>
23 #include <gp_Ax2d.hxx>
24 #include <gp_Circ2d.hxx>
25 #include <gp_Pnt2d.hxx>
26 #include <gp_Vec2d.hxx>
27 #include <Standard_Failure.hxx>
28 #include <Standard_OutOfRange.hxx>
29 #include <StdFail_NotDone.hxx>
30 #include <TColStd_Array1OfInteger.hxx>
31 #include <TColStd_Array1OfReal.hxx>
32
33 //=========================================================================
34 //   Creation d un cercle tangent a une courbe centre en un point.        +
35 //=========================================================================
36 Geom2dGcc_Circ2dTanCenGeo::
37 Geom2dGcc_Circ2dTanCenGeo (const Geom2dGcc_QCurve&  Qualified1,
38                            const gp_Pnt2d&          Pcenter   ,
39                            const Standard_Real      Tolerance ):
40
41 //========================================================================
42 //   Initialisation des champs.                                          +
43 //========================================================================
44
45   cirsol(1,2)    ,
46   qualifier1(1,2),
47   pnttg1sol(1,2) ,
48   par1sol(1,2)   ,
49   pararg1(1,2)   
50 {
51   Standard_Real Tol = Abs(Tolerance);
52   TColgp_Array1OfPnt2d pTan(1,2);
53   TColStd_Array1OfInteger Index(1,2);
54   TColStd_Array1OfReal theDist2(1,2);
55   TColStd_Array1OfReal theParam(1,2);
56   theDist2(1) = RealLast();
57   theDist2(2) = 0.;
58   Standard_Integer i = 1;
59   Standard_Integer nbsol = 0;
60   gp_Dir2d dirx(1.0,0.0);
61   Standard_Real thePar;
62   Geom2dAdaptor_Curve curve = Qualified1.Qualified();
63   Extrema_ExtPC2d distmin(Pcenter,curve,Geom2dGcc_CurveTool::NbSamples(curve),
64     Geom2dGcc_CurveTool::EpsX(curve,Tol),Tol);
65   if (!distmin.IsDone() ) { throw Standard_Failure(); }
66   Standard_Integer nbext = distmin.NbExt();
67   if(nbext==0) { throw Standard_Failure(); }
68   while (i<=nbext) {
69     thePar = distmin.Point(i).Parameter();
70     if (distmin.SquareDistance(i)<theDist2(1) && 
71       thePar>=Geom2dGcc_CurveTool::FirstParameter(curve) && 
72       thePar <= Geom2dGcc_CurveTool::LastParameter(curve)) {
73         theDist2(1) = distmin.SquareDistance(i);
74         theParam(1) = thePar;
75         pTan(1) = distmin.Point(i).Value();
76     }
77     if (distmin.SquareDistance(i)>theDist2(2) && 
78       thePar>=Geom2dGcc_CurveTool::FirstParameter(curve) && 
79       thePar <= Geom2dGcc_CurveTool::LastParameter(curve)) {
80         theDist2(2) = distmin.SquareDistance(i);
81         theParam(2) = thePar;
82         pTan(2) = distmin.Point(i).Value();
83     }
84     i++;
85   }
86   if (Index(1) == Index(2)) { nbsol = 1; }
87   else { nbsol = 2; }
88   for (i = 1 ; i <= nbsol; i++) {
89     gp_Pnt2d point1;
90     gp_Vec2d Tan1;
91     Geom2dGcc_CurveTool::D1(curve,theParam(i),point1,Tan1);
92     Standard_Real normetan1 = Tan1.Magnitude();
93     gp_Vec2d Vec1(point1,Pcenter);
94     Standard_Real normevec1 = Vec1.Magnitude();
95     Standard_Real dot1;
96     if (normevec1 >= gp::Resolution() && normetan1 >= gp::Resolution()) {
97       dot1 = Vec1.Dot(Tan1)/(normevec1*normetan1);
98     }
99     else { dot1 = 0.; }
100     Tol = 1.e-12;
101     if (dot1 <= Tol) {
102       Standard_Real Angle1 = Vec1.Angle(Tan1);
103       if (Qualified1.IsUnqualified()||
104         (Qualified1.IsEnclosing()&&Angle1<=0.)||
105         (Qualified1.IsOutside() && Angle1 >= 0.) ||
106         (Qualified1.IsEnclosed() && Angle1 <= 0.)) {
107           NbrSol++;
108           cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),sqrt (theDist2(i)));
109           qualifier1(NbrSol) = Qualified1.Qualifier();
110           pararg1(NbrSol) = theParam(i);
111           par1sol(NbrSol) = 0.;
112           pnttg1sol(NbrSol) = pTan(i);
113           WellDone = Standard_True;
114       }
115     }
116   }
117 }
118
119
120
121 //=========================================================================
122
123
124 Standard_Boolean Geom2dGcc_Circ2dTanCenGeo::
125 IsDone () const { return WellDone; }
126
127 Standard_Integer Geom2dGcc_Circ2dTanCenGeo::
128 NbSolutions () const { return NbrSol; }
129
130 gp_Circ2d Geom2dGcc_Circ2dTanCenGeo::
131 ThisSolution (const Standard_Integer Index) const 
132 {
133   if (Index > NbrSol || Index <= 0) throw Standard_OutOfRange();
134
135   return cirsol(Index);
136 }
137
138 void Geom2dGcc_Circ2dTanCenGeo::
139 WhichQualifier(const Standard_Integer Index   ,
140                GccEnt_Position& Qualif1 ) const
141 {
142   if (!WellDone) { throw StdFail_NotDone(); }
143   else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
144   else {
145     Qualif1 = qualifier1(Index);
146   }
147 }
148
149 void Geom2dGcc_Circ2dTanCenGeo::
150 Tangency1 (const Standard_Integer Index,
151            Standard_Real&   ParSol,
152            Standard_Real&   ParArg,
153            gp_Pnt2d& PntSol) const{
154              if (!WellDone) {
155                throw StdFail_NotDone();
156              }
157              else if (Index <= 0 ||Index > NbrSol) {
158                throw Standard_OutOfRange();
159              }
160              else {
161                PntSol = gp_Pnt2d(pnttg1sol(Index));
162                ParSol = par1sol(Index);
163                ParArg = pararg1(Index);
164              }
165 }
166