0027232: Configuration - fix mblen missing building issue on Android
[occt.git] / src / GccAna / GccAna_Circ2dTanOnRad_4.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 straight line Qualified1 (L1).                     +
33 //          center on  circle OnCirc.                                     +
34 //          with radius       Radius.                                     +
35 //                                                                        +
36 //  Initialize table of solutions cirsol and all fields.                  +
37 //  Eliminate cases not being the solution.                               +
38 //  Create parallel line(s) to L1 in the required direction(s).           +
39 //  Intersect parallel line(s) with OnCirc and obtain                     +
40 //  center points of found solutions.                                     +
41 //  Create solutions cirsol.                                              +
42 //=========================================================================
43 GccAna_Circ2dTanOnRad::
44    GccAna_Circ2dTanOnRad (const GccEnt_QualifiedLin& Qualified1,
45                           const gp_Circ2d&           OnCirc    ,
46                           const Standard_Real        Radius    ,
47                           const Standard_Real        Tolerance ):
48
49 //=========================================================================
50 //  Initialization of fields.                                            +
51 //=========================================================================
52
53    cirsol(1,4)   ,
54    qualifier1(1,4) ,
55    TheSame1(1,4) ,
56    pnttg1sol(1,4),
57    pntcen3(1,4)  ,
58    par1sol(1,4)  ,
59    pararg1(1,4)  ,
60    parcen3(1,4)  
61 {
62
63      TheSame1.Init(0);
64    gp_Dir2d dirx(1.0,0.0);
65    Standard_Real Tol = Abs(Tolerance);
66    WellDone = Standard_False;
67    NbrSol = 0;
68    if (!(Qualified1.IsEnclosed() ||
69          Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
70      GccEnt_BadQualifier::Raise();
71      return;
72    }
73
74 //=========================================================================
75 //  Initialisation of various variables.                                 +
76 //=========================================================================
77
78    Standard_Integer nbsol = 0;
79    Standard_Integer sign = 0;
80    gp_Lin2d L1 = Qualified1.Qualified();
81    gp_Pnt2d origin1(L1.Location());
82    gp_Dir2d dir1(L1.Direction());
83    gp_Dir2d normL1(-dir1.Y(),dir1.X());
84    Standard_Real dist1 = L1.Distance(OnCirc.Location())-OnCirc.Radius();
85    Standard_Real dist2 = L1.Distance(OnCirc.Location())+OnCirc.Radius();
86
87 //=========================================================================
88 //  Processing.                                                           +
89 //=========================================================================
90
91    if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
92    else {
93      L1 = Qualified1.Qualified();
94      if ((dist1-Radius>Tol) || (Tol<Radius-dist2)) { WellDone=Standard_True; }
95      else {
96
97 // to modify later
98
99        if (dist1-Radius > 0.0) { dist1 = Radius; }
100        else if (dist2-Radius < 0.0) { dist2 = Radius; }
101
102        if (Qualified1.IsEnclosed()) {
103 //     ============================
104          nbsol = 1;
105          sign = -1;
106        }
107        else if (Qualified1.IsOutside()) {
108 //     ================================
109          nbsol = 1;
110          sign = 1;
111        }
112        else {
113 //     ====
114          nbsol = 2;
115          sign = 1;
116        }
117        for (Standard_Integer j = 1 ; j <= nbsol ;j++) {
118          sign = -sign;
119          gp_Lin2d L(gp_Pnt2d(origin1.X()-sign*Radius*dir1.Y(),
120                              origin1.Y()+sign*Radius*dir1.X()),dir1);
121          IntAna2d_AnaIntersection Intp(L,OnCirc);
122          if (Intp.IsDone()) {
123            if (!Intp.IsEmpty()) {
124              for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
125                NbrSol++;
126                gp_Pnt2d Center(Intp.Point(i).Value());
127                gp_Ax2d axe(Center,dirx);
128                cirsol(NbrSol) = gp_Circ2d(axe,Radius);
129 //             ======================================
130                gp_Dir2d dc1(origin1.XY()-Center.XY());
131                sign = (Standard_Integer) dc1.Dot(normL1);
132                if (!Qualified1.IsUnqualified()) { 
133                  qualifier1(NbrSol) = Qualified1.Qualifier();
134                }
135                else if (dc1.Dot(normL1) > 0.0) {        
136                  qualifier1(NbrSol) = GccEnt_outside; 
137                }
138                else { qualifier1(NbrSol) = GccEnt_enclosed; }
139                pntcen3(NbrSol) = cirsol(NbrSol).Location();
140                pnttg1sol(NbrSol) = gp_Pnt2d(pntcen3(NbrSol).XY()+
141                                     gp_XY(sign*Radius*dir1.Y(),
142                                           -sign*Radius*dir1.X()));
143                pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
144                par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
145                                                 pnttg1sol(NbrSol));
146                parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen3(NbrSol));
147              }
148            }
149            WellDone = Standard_True;
150          }
151        }
152      }
153    }
154  }
155
156
157