0022312: Translation of french commentaries in OCCT files
[occt.git] / src / GccAna / GccAna_Circ2dTanOnRad_2.cxx
1 // file GccAna_Circ2dTanOnRad_2.cxx, REG 08/07/91
2
3 #include <GccAna_Circ2dTanOnRad.jxx>
4
5 #include <ElCLib.hxx>
6 #include <math_DirectPolynomialRoots.hxx>
7 #include <Standard_NegativeValue.hxx>
8 #include <Standard_OutOfRange.hxx>
9 #include <gp_Dir2d.hxx>
10
11 //=========================================================================
12 //    typedef of handled objects :                                      +
13 //=========================================================================
14
15 typedef math_DirectPolynomialRoots Roots;
16
17 //=========================================================================
18 //   Circle tangent to a point      Point1.                               +
19 //          center on straight line OnLine.                               +
20 //          radius                  Radius.                               +
21 //                                                                        +
22 //  Initialize the table of solutions cirsol and all fields.              +
23 //  Eliminate cases not being the solution.                     +
24 //  Solve the equation of second degree showing that the found center point +
25 //  (xc,yc) is at distance Radius from point Point1 and on the straight line OnLine. +
26 //  The solutions are represented by circles :                     +
27 //                   - of center Pntcen(xc,yc)                            +
28 //                   - of radius Radius.                                   +
29 //=========================================================================
30
31 GccAna_Circ2dTanOnRad::
32    GccAna_Circ2dTanOnRad (const gp_Pnt2d&     Point1    ,
33                           const gp_Lin2d&     OnLine    ,
34                           const Standard_Real Radius    ,
35                           const Standard_Real Tolerance ):
36    cirsol(1,2)   ,
37    qualifier1(1,2) ,
38    TheSame1(1,2) ,
39    pnttg1sol(1,2),
40    pntcen3(1,2)  ,
41    par1sol(1,2)  ,
42    pararg1(1,2)  ,
43    parcen3(1,2)  
44 {
45
46    gp_Dir2d dirx(1.0,0.0);
47    Standard_Real Tol = Abs(Tolerance);
48    WellDone = Standard_False;
49    NbrSol = 0;
50    Standard_Real dp1lin = OnLine.Distance(Point1);
51
52    if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
53    else {
54      if (dp1lin > Radius+Tol) { WellDone = Standard_True; }
55      Standard_Real xc;
56      Standard_Real yc;
57      Standard_Real x1 = Point1.X();
58      Standard_Real y1 = Point1.Y();
59      Standard_Real xbid = 0;
60      Standard_Real xdir = (OnLine.Direction()).X();
61      Standard_Real ydir = (OnLine.Direction()).Y();
62      Standard_Real lxloc = (OnLine.Location()).X();
63      Standard_Real lyloc = (OnLine.Location()).Y();
64      if (Abs(dp1lin-Radius) < Tol) {
65        WellDone = Standard_True;
66        NbrSol = 1;
67        if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) {
68          gp_Ax2d axe(gp_Pnt2d(x1-ydir*dp1lin,y1+xdir*dp1lin),dirx);
69          cirsol(NbrSol) = gp_Circ2d(axe,Radius);
70 //       ======================================
71          qualifier1(NbrSol) = GccEnt_noqualifier;
72        }
73        else {
74          gp_Ax2d axe(gp_Pnt2d(x1+ydir*dp1lin,y1-xdir*dp1lin),dirx);
75          cirsol(NbrSol) = gp_Circ2d(axe,Radius);
76 //       ======================================
77          qualifier1(NbrSol) = GccEnt_noqualifier;
78        }
79        TheSame1(NbrSol) = 0;
80        pnttg1sol(NbrSol) = Point1;
81        pntcen3(NbrSol) = cirsol(NbrSol).Location();
82        pararg1(NbrSol) = 0.0;
83        par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
84        parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
85      }
86      else if (dp1lin < Tol) {
87        pntcen3(1) = gp_Pnt2d(Point1.X()+Radius*xdir,Point1.Y()+Radius*ydir);
88        pntcen3(2) = gp_Pnt2d(Point1.X()-Radius*xdir,Point1.Y()-Radius*ydir);
89        pntcen3(1) = ElCLib::Value(ElCLib::Parameter(OnLine,pntcen3(1)),OnLine);
90        pntcen3(2) = ElCLib::Value(ElCLib::Parameter(OnLine,pntcen3(2)),OnLine);
91        gp_Ax2d axe(pntcen3(1),OnLine.Direction());
92        cirsol(1) = gp_Circ2d(axe,Radius);
93        axe = gp_Ax2d(pntcen3(2),OnLine.Direction());
94        cirsol(2) = gp_Circ2d(axe,Radius);
95        TheSame1(1) = 0;
96        pnttg1sol(1) = Point1;
97        pararg1(1) = 0.0;
98        par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
99        parcen3(1)=ElCLib::Parameter(OnLine,pntcen3(1));
100        TheSame1(2) = 0;
101        pnttg1sol(2) = Point1;
102        pararg1(2) = 0.0;
103        par1sol(2)=ElCLib::Parameter(cirsol(2),pnttg1sol(2));
104        parcen3(2)=ElCLib::Parameter(OnLine,pntcen3(2));
105        NbrSol = 2;
106      }
107      else {
108        Standard_Real A,B,C;
109        OnLine.Coefficients(A,B,C);
110        Standard_Real D = A;
111        if (A == 0.0) {
112          A = B;
113          B = D;
114          xbid = x1;
115          x1 = y1;
116          y1 = xbid;
117        }
118        if (A != 0.0) {
119          Roots Sol((B*B+A*A)/(A*A),
120                    2.0*(B*C/(A*A)+(B/A)*x1-y1),
121                    x1*x1+y1*y1+C*C/(A*A)-Radius*Radius+2.0*C*x1/A);
122          if (Sol.IsDone()) {
123            for (Standard_Integer i = 1 ; i <= Sol.NbSolutions() ; i++) {
124              if (D != 0.0) {
125                yc = Sol.Value(i);
126                xc = -(B/A)*yc-C/A;
127              }
128              else {
129                xc = Sol.Value(i);
130                yc = -(B/A)*xc-C/A;
131              }
132              NbrSol++;
133              gp_Pnt2d Center(xc,yc);
134              cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
135 //           =======================================================
136              qualifier1(NbrSol) = GccEnt_noqualifier;
137              TheSame1(NbrSol) = 0;
138              pnttg1sol(NbrSol) = Point1;
139              pntcen3(NbrSol) = cirsol(NbrSol).Location();
140              pararg1(NbrSol) = 0.0;
141              par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
142                                               pnttg1sol(NbrSol));
143              parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
144            }
145            WellDone = Standard_True;
146          }
147        }
148      }
149    }
150  }