0024510: Remove unused local variables
[occt.git] / src / GccAna / GccAna_Circ2d2TanRad_1.cxx
1 // Created on: 1991-09-24
2 // Created by: Remi GILET
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <GccAna_Circ2d2TanRad.jxx>
18
19 #include <ElCLib.hxx>
20 #include <gp_Ax2d.hxx>
21 #include <gp_Circ2d.hxx>
22 #include <gp_Lin2d.hxx>
23 #include <IntAna2d_AnaIntersection.hxx>
24 #include <IntAna2d_IntPoint.hxx>
25 #include <TColStd_Array1OfReal.hxx>
26 #include <Standard_NegativeValue.hxx>
27 #include <GccEnt_BadQualifier.hxx>
28
29 // circular tangent to a circle, a line and a given radius
30 //==============================================================
31 //========================================================================
32 // Initialize WellDone to false.                                         +
33 // Return circle C1 and straight line L2.                                +
34 // Leave with error if the construction is impossible.                   +
35 // Create parallel to C1 in the proper direction.                        +
36 // Create parallel to L2 in the proper direction.                        +
37 // Intersect parallels ==> center point of the solution.                 +
38 // Create the solution and add it to already found ones.                 +
39 // Fill the fields.                                                      +
40 //========================================================================
41
42 GccAna_Circ2d2TanRad::
43    GccAna_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1 ,
44                          const GccEnt_QualifiedLin&  Qualified2 ,
45                          const Standard_Real         Radius     ,
46                          const Standard_Real         Tolerance  ):
47    qualifier1(1,8) ,
48    qualifier2(1,8),
49    TheSame1(1,8)   ,
50    TheSame2(1,8)   ,
51    cirsol(1,8)     ,
52    pnttg1sol(1,8)  ,
53    pnttg2sol(1,8)  ,
54    par1sol(1,8)    ,
55    par2sol(1,8)    ,
56    pararg1(1,8)    ,
57    pararg2(1,8)    
58 {
59
60   Standard_Real Tol = Abs(Tolerance);
61   gp_Dir2d dirx(1.,0.);
62   NbrSol = 0;
63   WellDone = Standard_False;
64   if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
65         Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
66       !(Qualified2.IsEnclosed() || Qualified2.IsOutside() || 
67         Qualified2.IsUnqualified())) {
68     GccEnt_BadQualifier::Raise();
69     return;
70   }
71   Standard_Integer i ;
72   for ( i = 1 ; i <= 8 ; i++) { TheSame2(i) = 0; }
73   Standard_Integer ncote1=0;
74   Standard_Integer ncote2=0;
75   Standard_Integer nbsol = 0;
76   Standard_Real cote = 0.0;
77   Standard_Real ccote = 0.0;
78   TColStd_Array1OfReal cote1(1,3);
79   TColStd_Array1OfReal cote2(1,2);
80   gp_Circ2d C1 = Qualified1.Qualified();
81   gp_Lin2d  L2 = Qualified2.Qualified();
82   Standard_Real xdir = (L2.Direction()).X();
83   Standard_Real ydir = (L2.Direction()).Y();
84   gp_Dir2d normL2(-ydir,xdir);
85   Standard_Real lxloc = (L2.Location()).X();
86   Standard_Real lyloc = (L2.Location()).Y();
87   Standard_Real cxloc = (C1.Location()).X();
88   Standard_Real cyloc = (C1.Location()).Y();
89   Standard_Real R1 = C1.Radius();
90   gp_Pnt2d center1(cxloc,cyloc);
91   gp_Pnt2d origin2(lxloc,lyloc);
92   Standard_Real dist = Radius*2.0 + R1;
93   Standard_Real distance = L2.Distance(center1);
94   
95   if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
96   else {
97     if ( distance-dist >Tol) { WellDone = Standard_True; }
98     else if (Qualified1.IsEnclosed()) {
99 //  =================================
100       if (Qualified2.IsEnclosed()) {
101 //    ============================
102         if (distance-R1 > Tol) { WellDone = Standard_True; }
103         else if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) && 
104                   (Radius*2.0-R1+distance > Tol)) ||
105                  ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
106                   (Radius*2.0-R1-distance > Tol))||
107                  (Radius-R1 > Tol)) { WellDone = Standard_True; }
108         else {
109           if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) && 
110                (Radius*2.0>R1-distance)) || (Abs(distance-R1)<Tol) ||
111               ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
112                (Radius*2.0 > (R1+distance+Tol)))) {
113             cote = 1.0;
114             nbsol = 3;
115             ccote = 1.0;
116           }
117           else {
118             ncote1 = 1;
119             ncote2 = 1;
120             cote1(1) = R1-Radius;
121             cote2(1) = 1.0;
122             nbsol = 1;
123           }
124         }
125       }
126       else if (Qualified2.IsOutside()) {
127 //    ================================
128         if (distance > R1+Tol) { WellDone = Standard_True; }
129         else if ((((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)) > 0.0) &&
130                   (Radius*2.0-R1+distance > Tol)) ||
131                  (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)) < 0.0) &&
132                   (Radius*2.0-R1-distance > Tol)) ||
133                  (Radius-R1 >Tol)) { WellDone = Standard_True; }
134         else {
135           if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) > 0.0) && 
136                (Radius*2.0 > R1-distance)) || (Abs(R1-Radius) < Tol) ||
137               ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) < 0.0) &&
138                (Radius*2.0>(R1+distance))) || (Abs(distance-R1)<Tol)) {
139             cote = -1.0;
140             nbsol = 3;
141             ccote = 1.0;
142           }
143           else {
144             ncote1 = 1;
145             ncote2 = 1;
146             cote1(1) = R1-Radius;
147             cote2(1) = -1.0;
148             nbsol = 1;
149           }
150         }
151       }
152       else if (Qualified2.IsUnqualified()) {
153 //    ====================================
154         if ((distance-R1>Tol) || (Radius*2.0-R1-distance>Tol) ||
155             (Radius-R1 > Tol)) { WellDone = Standard_True; }
156         else if (distance > R1) {
157           if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) > 0.0)) {
158             cote = 1.0;
159           }
160           else {
161             cote = -1.0;
162             nbsol = 3;
163           }
164           nbsol = 3;
165           ccote = 1;
166         }
167         else {
168           ncote1 = 1;
169           ncote2 = 2;
170           cote1(1) = R1-Radius;
171           cote2(1) = 1.0;
172           cote2(2) = -1.0;
173           nbsol = 1;
174         }
175       }
176       if (nbsol == 3) {
177       }
178     }
179     else if (Qualified1.IsEnclosing()) {
180 //  ==================================
181       if (Qualified2.IsEnclosed()) {
182 //    =================================
183         if ((distance<R1-Tol)||(Radius<R1-Tol)||(Radius*2<distance+R1-Tol) ||
184             (Tol<R1-Radius)||(-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0)){
185           WellDone = Standard_True;
186         }
187         else if ((distance<R1) || (Radius<R1) || (Radius*2.0<distance+R1)) {
188           cote = 1.0;
189           ccote =1.0;
190           nbsol = 3;
191         }
192         else {
193           ncote1 = 1;
194           ncote2 = 1;
195           cote1(1) = Radius-R1;
196           cote2(1) = 1.0;
197           nbsol = 1;
198         }
199       }
200       else if (Qualified2.IsOutside()) {
201 //    ================================
202         if ((Tol<R1-distance) || (Tol<distance+R1-Radius*2.0) ||
203             (Tol<R1-Radius)||(-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0)){
204           WellDone = Standard_True;
205         }
206         else if ((distance<R1) || (Radius*2.0<distance+R1) || (Radius<R1)) {
207           cote = -1.0;
208           ccote = -1.0;
209           nbsol = 3;
210         }
211         else {
212           ncote1 = 1;
213           ncote2 = 1;
214           cote1(1) = Radius-R1;
215           cote2(1) = -1.0;
216           nbsol = 1;
217         }
218       }
219       else if (Qualified2.IsUnqualified()) {
220 //    ====================================
221         if ((distance<R1-Tol) || (Radius*2.0<distance+R1-Tol) ||
222             (Radius < R1-Tol)) { WellDone = Standard_True; }
223         else if ((distance < R1) || (Radius*2.0 < distance+R1)) {
224           if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) > 0.0)) {
225             cote = 1.0;
226             ccote = 1.0;
227             nbsol = 3;
228           }
229           else {
230             ccote = -1.0;
231             cote = -1.0;
232             nbsol = 3;
233           }
234         }
235         else {
236           ncote1 = 1;
237           ncote2 = 2;
238           cote1(1) = Radius-R1;
239           cote2(1) = 1.0;
240           cote2(2) = -1.0;
241           nbsol = 1;
242         }
243       }
244     }
245     else if ((Qualified1.IsOutside()) && (Qualified2.IsEnclosed())) {
246 //  ===============================================================
247       if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
248            (distance>R1+Tol)) || (distance > R1+Radius*2.0+Tol)) {
249         WellDone = Standard_True;
250       }
251       else {
252         if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
253             (distance>R1)) {
254           cote = 1.0;
255           nbsol = 2;
256         }
257         else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
258                  (distance>R1+2.0*Radius)) {
259           cote = -1.0;
260           nbsol = 2;
261         }
262         else {
263           ncote1 = 1;
264           ncote2 = 1;
265           cote1(1) = Radius+R1;
266           cote2(1) = 1.0;
267           nbsol = 1;
268         }
269       }
270     }
271     else if ((Qualified1.IsOutside()) && (Qualified2.IsOutside())) {
272 //  ==============================================================
273       if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
274            (distance>R1+Tol)) || (distance > R1+Radius*2.0+Tol)) {
275         WellDone = Standard_True;
276       }
277       else {
278         if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) && (distance>R1)) {
279           cote = -1.0;
280           nbsol = 2;
281         }
282         else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
283                  (distance>R1+2.0*Radius)) {
284           cote = 1.0;
285           nbsol = 2;
286         }
287         else {
288           ncote1 = 1;
289           ncote2 = 1;
290           cote1(1) = Radius+R1;
291           cote2(1) = -1.0;
292           nbsol = 1;
293         }
294       }
295     }
296     else if ((Qualified1.IsOutside()) && (Qualified2.IsUnqualified())) {
297 //  ==================================================================
298       if (distance > Radius*2.0+R1+Tol) { WellDone = Standard_True; }
299       else if (distance > Radius*2.0+R1) {
300         if (-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) { cote = 1.0; }
301         else { cote = -1.0; }
302         nbsol = 4;
303       }
304       else {
305         ncote1 = 1;
306         ncote2 = 2;
307         cote1(1) = Radius+R1;
308         cote2(1) = 1.0;
309         cote2(2) = -1.0;
310         nbsol = 1;
311       }
312     }
313     else if ((Qualified1.IsUnqualified()) && (Qualified2.IsEnclosed())) {
314 //  ===================================================================
315       if ((distance>R1+Radius*2.0+Tol) ||
316           ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) && 
317            (distance > R1+Tol))){ WellDone = Standard_True; }
318       else {
319         if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) && (distance > R1)){
320           cote = 1.0;
321           nbsol = 2;
322         }
323         else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
324                  (distance>R1+2.0*Radius)) {
325           cote = -1.0;
326           nbsol = 2;
327         }
328         else {
329           ncote1 = 2;
330           ncote2 = 1;
331           cote1(1) = Abs(Radius-R1);
332           cote1(2) = Radius+R1;
333           cote2(1) = 1.0;
334           nbsol = 1;
335         }
336       }
337     }
338     else if ((Qualified1.IsUnqualified()) && (Qualified2.IsOutside())) {
339 //  ==================================================================
340       if ((distance>R1+Radius*2.0+Tol) ||
341           ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) && 
342            (distance > R1+Tol))){ WellDone = Standard_True; }
343       else {
344         if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) && (distance > R1)){
345           cote = -1.0;
346           nbsol = 2;
347         }
348         else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
349                  (distance>R1+2.0*Radius)) {
350           cote = 1.0;
351           nbsol = 2;
352         }
353         else {
354           ncote1 = 2;
355           ncote2 = 1;
356           cote1(1) = Abs(Radius-R1);
357           cote1(2) = Radius+R1;
358           cote2(1) = -1.0;
359           nbsol = 1;
360         }
361       }
362     }
363     else if ((Qualified1.IsUnqualified()) && (Qualified2.IsUnqualified())) {
364 //  ======================================================================
365       if (distance>R1+Radius*2.0+Tol) { WellDone = Standard_True; }
366       else if (distance>R1+Radius*2.0) {
367         if (-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) { cote = -1.0; }
368         else { cote = 1.0; }
369         nbsol = 4;
370       }
371       else {
372         ncote1 = 2;
373         ncote2 = 2;
374         cote1(1) = Abs(Radius-R1);
375         cote1(2) = Radius+R1;
376         cote2(1) = 1.0;
377         cote2(2) = -1.0;
378         nbsol = 1;
379       }
380     }
381     if (nbsol == 1) {
382       for (Standard_Integer jcote1 = 1 ; jcote1 <= ncote1 ; jcote1++) {
383         for (Standard_Integer jcote2 = 1 ; jcote2 <= ncote2 ; jcote2++) {
384           if (cote1(jcote1)<Tol) continue;
385           gp_Circ2d cirint(gp_Ax2d(center1,dirx),cote1(jcote1));
386           gp_Lin2d  linint(gp_Pnt2d(lxloc-cote2(jcote2)*ydir*Radius,
387                              lyloc+cote2(jcote2)*xdir*Radius),L2.Direction());
388           IntAna2d_AnaIntersection Intp(linint,cirint);
389           if (Intp.IsDone()) {
390             if (!Intp.IsEmpty()) {
391               for (i = 1 ; i <= Intp.NbPoints() ; i++) {
392                 NbrSol++;
393                 gp_Pnt2d Center(Intp.Point(i).Value());
394                 gp_Ax2d axe(Center,dirx);
395                 cirsol(NbrSol) = gp_Circ2d(axe,Radius);
396 //              ======================================
397 #ifdef DEB
398                 gp_Dir2d dc1(center1.XY()-Center.XY());
399 #endif
400                 gp_Dir2d dc2(origin2.XY()-Center.XY());
401                 Standard_Real distcc1 = Center.Distance(center1);
402                 if (!Qualified1.IsUnqualified()) { 
403                   qualifier1(NbrSol) = Qualified1.Qualifier();
404                 }
405                 else if (Abs(distcc1+Radius-R1) < Tol) {
406                   qualifier1(NbrSol) = GccEnt_enclosed;
407                 }
408                 else if (Abs(distcc1-R1-Radius) < Tol) {
409                   qualifier1(NbrSol) = GccEnt_outside;
410                 }
411                 else { qualifier1(NbrSol) = GccEnt_enclosing; }
412                 if (!Qualified2.IsUnqualified()) { 
413                   qualifier2(NbrSol) = Qualified2.Qualifier();
414                 }
415                 else if (dc2.Dot(normL2) > 0.0) {
416                   qualifier2(NbrSol) = GccEnt_outside;
417                 }
418                 else { qualifier2(NbrSol) = GccEnt_enclosed; }
419                 TheSame1(NbrSol) = 0;
420                 if ((Radius < R1) && Center.Distance(center1) <= R1) {
421                   pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*(gp_Dir2d(
422                                         Center.XY()-center1.XY()).XY()));
423                 }
424                 else {
425                   pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*(gp_Dir2d(
426                                         Center.XY()-center1.XY()).XY()));
427                 }
428                 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+
429                                        cote2(jcote2)*Radius*gp_XY(ydir,-xdir));
430               }
431             }
432             WellDone = Standard_True;
433           }
434         }
435       }
436     }
437     else if (nbsol == 2) {
438       gp_Pnt2d Cen(center1.XY()+cote*(R1+Radius)*gp_XY(-ydir,xdir));
439       gp_Ax2d axe(Cen,dirx);
440       cirsol(1) = gp_Circ2d(axe,Radius);
441 //    =================================
442       WellDone = Standard_True;
443       NbrSol = 1;
444       TheSame1(1) = 0;
445       qualifier1(1) = Qualified1.Qualifier();;
446       qualifier2(1) = Qualified2.Qualifier();
447       pnttg1sol(1)=gp_Pnt2d(Cen.XY()+cote*Radius*gp_XY(ydir,-xdir));
448       pnttg2sol(1)=gp_Pnt2d(Cen.XY()+Radius*gp_XY(ydir,-xdir));
449     }
450     else if (nbsol == 3) {
451       WellDone = Standard_True;
452       NbrSol = 1;
453       gp_Pnt2d Cen(center1.XY()+cote*(R1-Radius)*gp_XY(ydir,-xdir));
454       gp_Ax2d axe(Cen,dirx);
455       cirsol(1) = gp_Circ2d(axe,Radius);
456 //    =================================
457       qualifier1(1) = Qualified1.Qualifier();
458       qualifier2(1) = Qualified2.Qualifier();
459       pnttg2sol(1) = gp_Pnt2d(Cen.XY()+cote*Radius*gp_XY(ydir,-xdir));
460       if (Abs(R1-Radius) > 0.0) {
461         pnttg1sol(1) = gp_Pnt2d(Cen.XY()+ccote*Radius*gp_XY(ydir,-xdir));
462       }
463       else { TheSame1(1) = 1; }
464     }
465     else if (nbsol == 4) {
466       gp_Pnt2d Cent(center1.XY()+cote*(R1+Radius)*gp_XY(-ydir,xdir));
467       gp_Ax2d axe(Cent,dirx);
468       cirsol(1) = gp_Circ2d(axe,Radius);
469 //    =================================
470       qualifier1(1) = Qualified1.Qualifier();
471       qualifier2(1) = Qualified2.Qualifier();
472       WellDone = Standard_True;
473       NbrSol = 1;
474       TheSame1(1) = 0;
475       pnttg1sol(1)=gp_Pnt2d(Cent.XY()+cote*Radius*gp_XY(ydir,-xdir));
476       pnttg2sol(1)=gp_Pnt2d(Cent.XY()+cote*Radius*gp_XY(-ydir,xdir));
477     }
478   }
479   for (i = 1 ; i <= NbrSol ; i++) {
480     par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
481     if (TheSame1(i) == 0) {
482       pararg1(i)=ElCLib::Parameter(C1,pnttg1sol(i));
483     }
484     par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
485     pararg2(i)=ElCLib::Parameter(L2,pnttg2sol(i));
486   }
487 }
488
489