175025295442faddc74ed91b581dbc15ebe58156
[occt.git] / src / GccAna / GccAna_Circ2dTanOnRad_5.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 <ElCLib.hxx>
17 #include <GccAna_Circ2dTanOnRad.hxx>
18 #include <GccEnt_BadQualifier.hxx>
19 #include <GccEnt_QualifiedCirc.hxx>
20 #include <GccEnt_QualifiedLin.hxx>
21 #include <gp_Circ2d.hxx>
22 #include <gp_Dir2d.hxx>
23 #include <gp_Lin2d.hxx>
24 #include <gp_Pnt2d.hxx>
25 #include <IntAna2d_AnaIntersection.hxx>
26 #include <IntAna2d_IntPoint.hxx>
27 #include <Standard_NegativeValue.hxx>
28 #include <Standard_OutOfRange.hxx>
29 #include <StdFail_NotDone.hxx>
30
31 //=========================================================================
32 //   Circle tangent to a point   Point1.                                  +
33 //          center on circle     OnCirc.                                  +
34 //          radius               Radius.                                  +
35 //                                                                        +
36 //  Initialize the table of solutions cirsol and all fields.              +
37 //  Eliminate cases not being the solution.                               +
38 //  Create the circle with center in Point1 of radius Radius.             +
39 //  Intersect this circle with OnCirc and obtain the center points        +
40 //  of found solutions.                                                   +
41 //  Create solutions cirsol.                                              +
42 //=========================================================================
43 GccAna_Circ2dTanOnRad::
44    GccAna_Circ2dTanOnRad (const gp_Pnt2d&     Point1    ,
45                           const gp_Circ2d&    OnCirc    ,
46                           const Standard_Real Radius    ,
47                           const Standard_Real Tolerance ):
48    cirsol(1,2)   ,
49    qualifier1(1,2) ,
50    TheSame1(1,2) ,
51    pnttg1sol(1,2),
52    pntcen3(1,2)  ,
53    par1sol(1,2)  ,
54    pararg1(1,2)  ,
55    parcen3(1,2)  
56 {
57
58    gp_Dir2d dirx(1.0,0.0);
59    Standard_Real Tol = Abs(Tolerance);
60    WellDone = Standard_False;
61    NbrSol = 0;
62    Standard_Real Roncirc = OnCirc.Radius();
63    Standard_Real dist1 = Point1.Distance(OnCirc.Location())-Roncirc;
64    Standard_Real dist2 = Point1.Distance(OnCirc.Location())+Roncirc;
65
66    if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
67    else if ((dist1-Radius > Tol) || (Tol < Radius-dist2)) { 
68      WellDone = Standard_True; 
69    }
70    else {
71      Standard_Integer signe = 0;
72      if (Abs(dist1-Radius) < Tol) { signe = 1; }
73      else if (Abs(dist2-Radius) < Tol) { signe = -1; }
74      if (signe != 0) {
75        gp_Ax2d axe(gp_Pnt2d(OnCirc.Location().XY()-Roncirc*
76                          gp_Dir2d(OnCirc.Location().X()-signe*Point1.X(),
77                            OnCirc.Location().Y()-signe*Point1.Y()).XY()),dirx);
78        cirsol(1) = gp_Circ2d(axe,Radius);
79 //      ================================
80        qualifier1(1) = GccEnt_noqualifier;
81        TheSame1(1) = 0;
82        pnttg1sol(1) = Point1;
83        pntcen3(1) = cirsol(1).Location();
84        pararg1(1) = 0.0;
85        par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
86        parcen3(1) = ElCLib::Parameter(OnCirc,pntcen3(1));
87        WellDone = Standard_True;
88        NbrSol = 1;
89      }
90      else {
91        IntAna2d_AnaIntersection Intp(OnCirc,gp_Circ2d(gp_Ax2d(Point1,dirx),
92                                                       Radius));
93        if (Intp.IsDone()) {
94          if (!Intp.IsEmpty()) {
95            for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
96              NbrSol++;
97              gp_Pnt2d Center(Intp.Point(i).Value());
98              cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
99 //           =======================================================
100        qualifier1(1) = GccEnt_noqualifier;
101              TheSame1(1) = 0;
102              pnttg1sol(1) = Point1;
103              pntcen3(1) = cirsol(1).Location();
104              par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
105              parcen3(1) = ElCLib::Parameter(OnCirc,pntcen3(1));
106              pararg1(1) = 0.0;
107            }
108          }
109          WellDone = Standard_True;
110        }
111      }
112    }
113  }