0022312: Translation of french commentaries in OCCT files
[occt.git] / src / GccAna / GccAna_Circ2d2TanOn_1.cxx
1 // File:        GccAna_Circ2d2TanOn_1.cxx
2 // Created:     Thu Jan  2 15:50:43 1992
3 // Author:      Remi GILET
4 //              <reg@topsn3>
5
6 #include <GccAna_Circ2d2TanOn.jxx>
7
8 #include <ElCLib.hxx>
9 #include <gp_Dir2d.hxx>
10 #include <gp_Ax2d.hxx>
11 #include <IntAna2d_AnaIntersection.hxx>
12 #include <IntAna2d_IntPoint.hxx>
13 #include <GccAna_CircLin2dBisec.hxx>
14 #include <GccInt_IType.hxx>
15 #include <GccInt_BCirc.hxx>
16 #include <IntAna2d_Conic.hxx>
17 #include <GccEnt_BadQualifier.hxx>
18
19 //=========================================================================
20 //   Creation of a circle tangent to Circle C1 and a straight line L2.    +
21 //                        centered on a straight line.                    +
22 //  We start by making difference between cases that we are going to      +
23 //  proceess separately.                                            +
24 //  In general case:                                                  +
25 //  ====================                                                  +
26 //  We calculate bissectrices to C1 and L2 that give us            +
27 //  all possibles locations of centers of all circles tangent to C1 and L2+                                                  +
28 //  We intersect these bissectrices with straight line OnLine which gives   +
29 //  us points among which we'll choose the solutions.   +
30 //  The choices are made basing on Qualifiers of C1 and L2.  +
31 //=========================================================================
32
33 GccAna_Circ2d2TanOn::
34    GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1  , 
35                         const GccEnt_QualifiedLin&  Qualified2  , 
36                         const gp_Lin2d&             OnLine      ,
37                         const Standard_Real         Tolerance   ):
38    cirsol(1,4)     ,
39    qualifier1(1,4) ,
40    qualifier2(1,4),
41    TheSame1(1,4)   ,
42    TheSame2(1,4)   ,
43    pnttg1sol(1,4)  ,
44    pnttg2sol(1,4)  ,
45    pntcen(1,4)     ,
46    par1sol(1,4)    ,
47    par2sol(1,4)    ,
48    pararg1(1,4)    ,
49    pararg2(1,4)    ,
50    parcen3(1,4)
51 {
52
53    TheSame1.Init(0);
54    TheSame2.Init(0);
55    WellDone = Standard_False;
56    NbrSol = 0;
57    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
58          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
59        !(Qualified2.IsEnclosed() ||
60          Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
61      GccEnt_BadQualifier::Raise();
62      return;
63    }
64    Standard_Real Tol = Abs(Tolerance);
65    Standard_Real Radius=0;
66    Standard_Boolean ok = Standard_False;
67    gp_Dir2d dirx(1.,0.);
68    gp_Circ2d C1 = Qualified1.Qualified();
69    gp_Lin2d  L2 = Qualified2.Qualified();
70    Standard_Real R1 = C1.Radius();
71    gp_Pnt2d center1(C1.Location());
72    gp_Pnt2d origin2(L2.Location());
73    gp_Dir2d dirL2(L2.Direction());
74    gp_Dir2d normL2(-dirL2.Y(),dirL2.X());
75
76 //=========================================================================
77 //   Processing of limit cases.                                          +
78 //=========================================================================
79
80    Standard_Real distcl = OnLine.Distance(center1);
81    gp_Pnt2d pinterm(center1.XY()+distcl*
82                     gp_XY(-OnLine.Direction().Y(),OnLine.Direction().X()));
83    if (OnLine.Distance(pinterm) > Tolerance) {
84      pinterm = gp_Pnt2d(center1.XY()+distcl*
85                         gp_XY(-OnLine.Direction().Y(),OnLine.Direction().X()));
86    }
87    Standard_Real dist2 = L2.Distance(pinterm);
88    if (Qualified1.IsEnclosed() || Qualified1.IsOutside()) {
89      if (Abs(distcl-R1-dist2) <= Tol) { ok = Standard_True; }
90    }
91    else if (Qualified1.IsEnclosing()) {
92      if (Abs(dist2-distcl-R1) <= Tol) { ok = Standard_True; }
93    }
94    else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
95    else { 
96      GccEnt_BadQualifier::Raise();
97      return;
98    }
99    if (ok) {
100      if (Qualified2.IsOutside()) {
101        gp_Pnt2d pbid(pinterm.XY()+dist2*gp_XY(-dirL2.Y(),dirL2.X()));
102        if (L2.Distance(pbid) <= Tol) { WellDone = Standard_True; }
103      }
104      else if (Qualified2.IsEnclosed()) {
105        gp_Pnt2d pbid(pinterm.XY()-dist2*gp_XY(-dirL2.Y(),dirL2.X()));
106        if (L2.Distance(pbid) <= Tol) { WellDone = Standard_True; }
107      }
108      else if (Qualified2.IsUnqualified()) { WellDone = Standard_False; }
109      else { 
110        GccEnt_BadQualifier::Raise();
111        return;
112      }
113    }
114    if (WellDone) {
115      NbrSol++;
116      cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),dist2);
117 //   =======================================================
118      gp_Dir2d dc1(center1.XY()-pinterm.XY());
119      gp_Dir2d dc2(origin2.XY()-pinterm.XY());
120      Standard_Real distcc1 = pinterm.Distance(center1);
121      if (!Qualified1.IsUnqualified()) { 
122        qualifier1(NbrSol) = Qualified1.Qualifier();
123      }
124      else if (Abs(distcc1+dist2-R1) < Tol) {
125        qualifier1(NbrSol) = GccEnt_enclosed;
126      }
127      else if (Abs(distcc1-R1-dist2) < Tol) {
128        qualifier1(NbrSol) = GccEnt_outside;
129      }
130      else { qualifier1(NbrSol) = GccEnt_enclosing; }
131      if (!Qualified2.IsUnqualified()) { 
132        qualifier2(NbrSol) = Qualified2.Qualifier();
133      }
134      else if (dc2.Dot(normL2) > 0.0) {
135        qualifier2(NbrSol) = GccEnt_outside;
136      }
137      else { qualifier2(NbrSol) = GccEnt_enclosed; }
138
139      Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL2.Y(),dirL2.X()));
140      dc2 = gp_Dir2d(sign*gp_XY(-dirL2.Y(),dirL2.X()));
141      pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dist2*dc1.XY());
142      pnttg2sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dist2*dc2.XY());
143      par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
144      pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
145      par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
146      pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
147      pntcen(NbrSol) = cirsol(NbrSol).Location();
148      parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
149      return;
150    }
151
152 //=========================================================================
153 //   General case.                                                        +
154 //=========================================================================
155
156    GccAna_CircLin2dBisec Bis(C1,L2);
157    if (Bis.IsDone()) {
158      Standard_Integer nbsolution = Bis.NbSolutions();
159      for (Standard_Integer i = 1 ; i <=  nbsolution; i++) {
160        Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
161        GccInt_IType type = Sol->ArcType();
162        IntAna2d_AnaIntersection Intp;
163        if (type == GccInt_Lin) {
164          Intp.Perform(OnLine,Sol->Line());
165        }
166        else if (type == GccInt_Par) {
167          Intp.Perform(OnLine,IntAna2d_Conic(Sol->Parabola()));
168        }
169        if (Intp.IsDone()) {
170          if (!Intp.IsEmpty()) {
171            for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
172              gp_Pnt2d Center(Intp.Point(j).Value());
173              Standard_Real dist1 = Center.Distance(center1);
174              dist2 = L2.Distance(Center);
175 //           Standard_Integer nbsol = 1;
176              ok = Standard_False;
177              if (Qualified1.IsEnclosed()) {
178                if (dist1-R1 < Tolerance) {
179                  if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; }
180                }
181              }
182              else if (Qualified1.IsOutside()) {
183                if (R1-dist1 < Tolerance) {
184                  if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; }
185                }
186              }
187              else if (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) {
188                ok = Standard_True;
189              }
190              if (Qualified2.IsEnclosed() && ok) {
191                if ((((origin2.X()-Center.X())*(-dirL2.Y()))+
192                     ((origin2.Y()-Center.Y())*(dirL2.X())))<=0){
193                  ok = Standard_True;
194                  Radius = dist2;
195                }
196              }
197              else if (Qualified2.IsOutside() && ok) {
198                if ((((origin2.X()-Center.X())*(-dirL2.Y()))+
199                     ((origin2.Y()-Center.Y())*(dirL2.X())))>=0){
200                  ok = Standard_True;
201                  Radius = dist2;
202                }
203              }
204              else if (Qualified2.IsUnqualified() && ok) {
205                ok = Standard_True;
206                Radius = dist2;
207              }
208              if (ok) {
209                NbrSol++;
210                cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
211 //             =======================================================
212                gp_Dir2d dc1(center1.XY()-Center.XY());
213                gp_Dir2d dc2(origin2.XY()-Center.XY());
214                Standard_Real distcc1 = Center.Distance(center1);
215                if (!Qualified1.IsUnqualified()) { 
216                  qualifier1(NbrSol) = Qualified1.Qualifier();
217                }
218                else if (Abs(distcc1+Radius-R1) < Tol) {
219                  qualifier1(NbrSol) = GccEnt_enclosed;
220                }
221                else if (Abs(distcc1-R1-Radius) < Tol) {
222                  qualifier1(NbrSol) = GccEnt_outside;
223                }
224                else { qualifier1(NbrSol) = GccEnt_enclosing; }
225                if (!Qualified2.IsUnqualified()) { 
226                  qualifier2(NbrSol) = Qualified2.Qualifier();
227                }
228                else if (dc2.Dot(normL2) > 0.0) {
229                  qualifier2(NbrSol) = GccEnt_outside;
230                }
231                else { qualifier2(NbrSol) = GccEnt_enclosed; }
232                if (Center.Distance(center1) <= Tolerance &&
233                    Abs(Radius-C1.Radius()) <= Tolerance) {
234                  TheSame1(NbrSol) = 1;
235                  }
236                else {
237                  TheSame1(NbrSol) = 0;
238                  pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
239                  par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
240                                                         pnttg1sol(NbrSol));
241                  pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
242                }
243                TheSame2(NbrSol) = 0;
244                Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL2.Y(),dirL2.X()));
245                dc2 = gp_Dir2d(sign*gp_XY(-dirL2.Y(),dirL2.X()));
246                pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY());
247                par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
248                                                       pnttg2sol(NbrSol));
249                pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
250                pntcen(NbrSol) = Center;
251                parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
252              }
253            }
254          }
255          WellDone = Standard_True;
256        }
257      }
258    }
259  }
260
261
262
263
264
265