0023292:The variable 'k' is being used for this loop and for the outer loop.
[occt.git] / src / GccAna / GccAna_Circ2d3Tan_2.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19
20 #include <GccAna_Circ2d3Tan.jxx>
21
22 #include <IntAna2d_AnaIntersection.hxx>
23 #include <IntAna2d_IntPoint.hxx>
24 #include <gp_Lin2d.hxx>
25 #include <ElCLib.hxx>
26 #include <gp_Circ2d.hxx>
27 #include <gp_Dir2d.hxx>
28 #include <TColStd_Array1OfReal.hxx>
29 #include <GccAna_CircLin2dBisec.hxx>
30 #include <GccAna_Lin2dBisec.hxx>
31 #include <GccInt_IType.hxx>
32 #include <GccInt_BLine.hxx>
33 #include <GccInt_BParab.hxx>
34 #include <IntAna2d_Conic.hxx>
35 #include <GccEnt_BadQualifier.hxx>
36
37 //=========================================================================
38 //   Creation of a circle tangent to a circle and two straight lines.          +
39 //=========================================================================
40
41 GccAna_Circ2d3Tan::GccAna_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 ,
42                                       const GccEnt_QualifiedLin&  Qualified2 ,
43                                       const GccEnt_QualifiedLin&  Qualified3 ,
44                                       const Standard_Real         Tolerance  )
45                    
46 //=========================================================================
47 //   Initialisation of fields.                                           +
48 //=========================================================================
49
50 :cirsol(1,8)    ,
51 qualifier1(1,8) ,
52 qualifier2(1,8) ,
53 qualifier3(1,8) ,
54 TheSame1(1,8)   ,
55 TheSame2(1,8)   ,
56 TheSame3(1,8)   ,
57 pnttg1sol(1,8)  ,
58 pnttg2sol(1,8)  , 
59 pnttg3sol(1,8)  ,
60 par1sol(1,8)    ,
61 par2sol(1,8)    ,
62 par3sol(1,8)    ,
63 pararg1(1,8)    ,
64 pararg2(1,8)    ,
65 pararg3(1,8)    
66 {
67   
68   TheSame1.Init(0);
69   
70   gp_Dir2d dirx(1.0,0.0);
71    Standard_Real Tol = Abs(Tolerance);
72    WellDone = Standard_False;
73    NbrSol = 0;
74    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
75          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
76        !(Qualified2.IsEnclosed() || 
77          Qualified2.IsOutside() || Qualified2.IsUnqualified()) ||
78        !(Qualified3.IsEnclosed() ||
79          Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
80      GccEnt_BadQualifier::Raise();
81      return;
82    }
83
84 //=========================================================================
85 //   Processing.                                                          +
86 //=========================================================================
87
88    gp_Circ2d C1 = Qualified1.Qualified();
89    gp_Lin2d L2  = Qualified2.Qualified();
90    gp_Lin2d L3  = Qualified3.Qualified();
91    Standard_Real R1      = C1.Radius();
92    gp_Pnt2d center1(C1.Location());
93    gp_Pnt2d origin2(L2.Location());
94    gp_Dir2d dir2(L2.Direction());
95    gp_Dir2d normL2(-dir2.Y(),dir2.X());
96    gp_Pnt2d origin3(L3.Location());
97    gp_Dir2d dir3(L3.Direction());
98    gp_Dir2d normL3(-dir3.Y(),dir3.X());
99
100    TColStd_Array1OfReal Radius(1,2);
101    GccAna_CircLin2dBisec Bis1(C1,L2);
102    GccAna_Lin2dBisec Bis2(L2,L3);
103    if (Bis1.IsDone() && Bis2.IsDone()) {
104      Standard_Integer nbsolution1 = Bis1.NbSolutions();
105      Standard_Integer nbsolution2 = Bis2.NbSolutions();
106      for (Standard_Integer i = 1 ; i <=  nbsolution1; i++) {
107        Handle(GccInt_Bisec) Sol1 = Bis1.ThisSolution(i);
108        GccInt_IType typ1 = Sol1->ArcType();
109        IntAna2d_AnaIntersection Intp;
110        for (Standard_Integer k = 1 ; k <=  nbsolution2; k++) {
111          if (typ1 == GccInt_Lin) {
112            Intp.Perform(Sol1->Line(),Bis2.ThisSolution(k));
113          }
114          else if (typ1 == GccInt_Par) {
115            Intp.Perform(Bis2.ThisSolution(k),IntAna2d_Conic(Sol1->Parabola()));
116          }
117          if (Intp.IsDone()) {
118            if ((!Intp.IsEmpty())&&(!Intp.ParallelElements())&&
119                (!Intp.IdenticalElements())) {
120              for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
121                gp_Pnt2d Center(Intp.Point(j).Value());
122                Standard_Real dist1 = Center.Distance(center1);
123                Standard_Real dist2 = L2.Distance(Center);
124                Standard_Real dist3 = L3.Distance(Center);
125                Standard_Integer nbsol1 = 0;
126                Standard_Integer nbsol2 = 0;
127                Standard_Integer nbsol3 = 0;
128                Standard_Boolean ok = Standard_False;
129                if (Qualified1.IsEnclosed()) {
130                  if (dist1-R1 < Tolerance) {
131                    Radius(1) = Abs(R1-dist1);
132                    nbsol1 = 1;
133                    ok = Standard_True;
134                  }
135                }
136                else if (Qualified1.IsOutside()) {
137                  if (R1-dist1 < Tolerance) {
138                    Radius(1) = Abs(R1-dist1);
139                    nbsol1 = 1;
140                    ok = Standard_True;
141                  }
142                }
143                else if (Qualified1.IsEnclosing()) {
144                  ok = Standard_True;
145                  nbsol1 = 1;
146                  Radius(1) = Abs(R1-dist1);
147                }
148                else if (Qualified1.IsUnqualified()) {
149                  ok = Standard_True;
150                  nbsol1 = 2;
151                  Radius(1) = Abs(R1-dist1);
152                  Radius(2) = R1+dist1;
153                }
154                if (Qualified2.IsEnclosed() && ok) {
155                  if ((((origin2.X()-Center.X())*(-dir2.Y()))+
156                     ((origin2.Y()-Center.Y())*(dir2.X())))<=0){
157                    for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
158                      if (Abs(dist2-Radius(ii)) < Tol) { 
159                        ok = Standard_True;
160                        nbsol2 = 1;
161                        Radius(1) = Radius(ii);
162                      }
163                    }
164                  }
165                }
166                else if (Qualified2.IsOutside() && ok) {
167                  if ((((origin2.X()-Center.X())*(-dir2.Y()))+
168                     ((origin2.Y()-Center.Y())*(dir2.X())))>=0){
169                    for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
170                      if (Abs(dist2-Radius(ii)) < Tol) { 
171                        ok = Standard_True;
172                        nbsol2 = 1;
173                        Radius(1) = Radius(ii);
174                      }
175                    }
176                  }
177                }
178                else if (Qualified2.IsUnqualified() && ok) {
179                  for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
180                    if (Abs(dist2-Radius(ii)) < Tol) { 
181                      ok = Standard_True;
182                      nbsol2 = 1;
183                      Radius(1) = Radius(ii);
184                    }
185                  }
186                }
187                if (Qualified3.IsEnclosed() && ok) {
188                  if ((((origin3.X()-Center.X())*(-dir3.Y()))+
189                     ((origin3.Y()-Center.Y())*(dir3.X())))<=0){
190                    if (Abs(dist3-Radius(1)) < Tol) { 
191                      ok = Standard_True;
192                      nbsol3 = 1;
193                    }
194                  }
195                }
196                else if (Qualified3.IsOutside() && ok) {
197                  if ((((origin3.X()-Center.X())*(-dir3.Y()))+
198                     ((origin3.Y()-Center.Y())*(dir3.X())))>=0){
199                    if (Abs(dist3-Radius(1)) < Tol) { 
200                      ok = Standard_True;
201                      nbsol3 = 1;
202                    }
203                  }
204                }
205                else if (Qualified3.IsUnqualified() && ok) {
206                  if (Abs(dist3-Radius(1)) < Tol) { 
207                    ok = Standard_True;
208                    nbsol3 = 1;
209                  }
210                }
211                if (ok) {
212                  for (Standard_Integer m = 1 ; m <= nbsol3 ; m++) {
213                    NbrSol++;
214                    cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(m));
215 //                 ==========================================================
216                    Standard_Real distcc1 = Center.Distance(center1);
217                    if (!Qualified1.IsUnqualified()) { 
218                      qualifier1(NbrSol) = Qualified1.Qualifier();
219                    }
220                    else if (Abs(distcc1+Radius(m)-R1) < Tol) {
221                      qualifier1(NbrSol) = GccEnt_enclosed;
222                    }
223                    else if (Abs(distcc1-R1-Radius(m)) < Tol) {
224                      qualifier1(NbrSol) = GccEnt_outside;
225                    }
226                    else { qualifier1(NbrSol) = GccEnt_enclosing; }
227                    gp_Dir2d dc2(origin2.XY()-Center.XY());
228                    if (!Qualified2.IsUnqualified()) { 
229                      qualifier2(NbrSol) = Qualified2.Qualifier();
230                    }
231                    else if (dc2.Dot(normL2) > 0.0) {
232                      qualifier2(NbrSol) = GccEnt_outside;
233                    }
234                    else { qualifier2(NbrSol) = GccEnt_enclosed; }
235                    gp_Dir2d dc3(origin3.XY()-Center.XY());
236                    if (!Qualified3.IsUnqualified()) { 
237                      qualifier3(NbrSol) = Qualified3.Qualifier();
238                    }
239                    else if (dc3.Dot(normL3) > 0.0) {
240                      qualifier3(NbrSol) = GccEnt_outside;
241                    }
242                    else { qualifier3(NbrSol) = GccEnt_enclosed; }
243                    if (Center.Distance(center1) <= Tolerance &&
244                        Abs(Radius(m)-R1) <= Tolerance) {
245                      TheSame1(NbrSol) = 1;
246                    }
247                    else {
248                      TheSame1(NbrSol) = 0;
249                      gp_Dir2d dc(center1.XY()-Center.XY());
250                      pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(m)*dc.XY());
251                      par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
252                                                       pnttg1sol(NbrSol));
253                      pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
254                    }
255                    TheSame2(NbrSol) = 0;
256                    TheSame3(NbrSol) = 0;
257                    gp_Dir2d dc(origin2.XY()-Center.XY());
258                    Standard_Real sign = dc.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
259                    dc = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
260                    pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(m)*dc.XY());
261                    par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
262                                                     pnttg2sol(NbrSol));
263                    pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
264                    dc = gp_Dir2d(origin3.XY()-Center.XY());
265                    sign = dc.Dot(gp_Dir2d(-dir3.Y(),dir3.X()));
266                    dc = gp_Dir2d(sign*gp_XY(-dir3.Y(),dir3.X()));
267                    pnttg3sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(m)*dc.XY());
268                    par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
269                                                     pnttg3sol(NbrSol));
270                    pararg3(NbrSol)=ElCLib::Parameter(L3,pnttg3sol(NbrSol));
271                  }
272                }
273              }
274            }
275            WellDone = Standard_True;
276          }
277        }
278      }
279    }
280  }
281
282