Integration of OCCT 6.5.0 from SVN
[occt.git] / src / GccAna / GccAna_Circ2d2TanOn_10.cxx
1 // File:        GccAna_Circ2d2TanOn_10.cxx
2 // Created:     Thu Jan  2 16:00:00 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_LinPnt2dBisec.hxx>
14 #include <GccInt_IType.hxx>
15 #include <GccInt_Bisec.hxx>
16 #include <GccInt_BLine.hxx>
17 #include <IntAna2d_Conic.hxx>
18 #include <GccEnt_BadQualifier.hxx>
19
20 //=========================================================================
21 //   Creation d un cercle tangent a une Droite L1 et a un point Point2.   +
22 //                        centre sur un cercle.                           +
23 //  Nous commencons par distinguer les differents cas limites que nous    +
24 //  allons traiter separement.                                            +
25 //  Pour le cas general:                                                  +
26 //  ====================                                                  +
27 //  Nous calculons les bissectrices a L1 et Point2 qui nous donnent       +
28 //  l ensemble des lieux possibles des centres de tous les cercles        +
29 //  tangents a L1 et Point2.                                              +
30 //  Nous intersectons ces bissectrices avec le cerclee OnCirc ce qui nous +
31 //  donne les points parmis lesquels nous allons choisir les solutions.   +
32 //  Les choix s effectuent a partir des Qualifieurs qualifiant L1.        +
33 //=========================================================================
34
35   GccAna_Circ2d2TanOn::
36    GccAna_Circ2d2TanOn (const GccEnt_QualifiedLin&  Qualified1 ,
37                         const gp_Pnt2d&             Point2     ,
38                         const gp_Circ2d&            OnCirc     ,
39                         const Standard_Real         Tolerance  ):
40    cirsol(1,4)     ,
41    qualifier1(1,4) ,
42    qualifier2(1,4) ,
43    TheSame1(1,4) ,
44    TheSame2(1,4) ,
45    pnttg1sol(1,4)  ,
46    pnttg2sol(1,4)  ,
47    pntcen(1,4)     ,
48    par1sol(1,4)    ,
49    par2sol(1,4)    ,
50    pararg1(1,4)    ,
51    pararg2(1,4)    ,
52    parcen3(1,4)
53 {
54
55   TheSame1.Init(0);
56   TheSame2.Init(0);
57   WellDone = Standard_False;
58   NbrSol = 0;
59   if (!(Qualified1.IsEnclosed() ||
60         Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
61   GccEnt_BadQualifier::Raise();
62     return;
63   }
64   Standard_Real Tol = Abs(Tolerance);
65   gp_Dir2d dirx(1.,0.);
66   gp_Lin2d L1 = Qualified1.Qualified();
67   gp_Pnt2d originL1(L1.Location());
68   gp_Dir2d dirL1(L1.Direction());
69   gp_Dir2d normL1(-dirL1.Y(),dirL1.X());
70
71 //=========================================================================
72 //   Traitement des cas limites.                                          +
73 //=========================================================================
74
75   Standard_Real Ron = OnCirc.Radius();
76   Standard_Real distpc = OnCirc.Location().Distance(Point2);
77   gp_Dir2d dir(OnCirc.Location().XY()-Point2.XY());
78   gp_Pnt2d pinterm(Point2.XY()+(distpc+Ron)*dir.XY());
79   Standard_Real dist1 = L1.Distance(pinterm);
80   if (Abs(dist1-distpc-Ron) > Tol) {
81 #ifdef DEB
82     gp_Pnt2d pinterm(Point2.XY()+(distpc-Ron)*dir.XY()); // Unused ! BUG ???
83     Standard_Real dist1 = L1.Distance(pinterm); // Unused ! BUG ???
84 #endif
85   }
86   if (Abs(dist1-distpc+Ron) <= Tol) {
87     dir = gp_Dir2d(-dirL1.Y(),dirL1.X());
88     gp_Dir2d direc(originL1.XY()-pinterm.XY());
89     if (Qualified1.IsOutside()) {
90       if (direc.Dot(dir) >= 0.0) { WellDone = Standard_True; }
91     }
92     else if (Qualified1.IsEnclosed()) {
93       if (direc.Dot(dir) <= 0.0) { WellDone = Standard_True; }
94     }
95     else { WellDone = Standard_True; }
96     if (WellDone) {
97       NbrSol++;
98       cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),dist1);
99 //    =======================================================
100       gp_Dir2d dc1(originL1.XY()-pinterm.XY());
101       Standard_Real sign = dc1.Dot(normL1);
102       if (!Qualified1.IsUnqualified()) { 
103         qualifier1(NbrSol) = Qualified1.Qualifier();
104       }
105       else if (dc1.Dot(normL1) > 0.0) { qualifier1(NbrSol) = GccEnt_outside; }
106       else { qualifier1(NbrSol) = GccEnt_enclosed; }
107       qualifier2(NbrSol) = GccEnt_noqualifier;
108       dc1 = gp_Dir2d(sign*gp_XY(-dirL1.Y(),dirL1.X()));
109       pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dist1*dc1.XY());
110       par1sol(NbrSol) = ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
111       pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
112       pntcen(NbrSol) = pinterm;
113       parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol));
114       parcen3(NbrSol) = 0.;
115       pnttg2sol(NbrSol) = Point2;
116       pararg2(NbrSol) = 0.;
117       par2sol(NbrSol) = ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
118       return;
119     }
120   }
121
122 //=========================================================================
123 //   Cas general.                                                         +
124 //=========================================================================
125
126   GccAna_LinPnt2dBisec Bis(L1,Point2);
127   if (Bis.IsDone()) {
128     Handle(GccInt_Bisec) Sol = Bis.ThisSolution();
129     GccInt_IType type = Sol->ArcType();
130     IntAna2d_AnaIntersection Intp;
131     if (type == GccInt_Lin) {
132       Intp.Perform(Sol->Line(),OnCirc);
133     }
134     if (type == GccInt_Par) {
135       Intp.Perform(OnCirc,IntAna2d_Conic(Sol->Parabola()));
136     }
137     if (Intp.IsDone()) {
138       if (!Intp.IsEmpty()) {
139         for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
140           gp_Pnt2d Center(Intp.Point(j).Value());
141           Standard_Real Radius = L1.Distance(Center);
142 //        Standard_Integer nbsol = 1;
143           Standard_Boolean ok = Standard_False;
144           if (Qualified1.IsEnclosed()) {
145             if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
146                  ((originL1.Y()-Center.Y())*(dirL1.X())))<=0){
147               ok = Standard_True;
148             }
149           }
150           else if (Qualified1.IsOutside()) {
151             if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
152                  ((originL1.Y()-Center.Y())*(dirL1.X())))>=0){
153               ok = Standard_True;
154             }
155           }
156           else if (Qualified1.IsUnqualified()) {
157             ok = Standard_True;
158           }
159           if (ok) {
160             NbrSol++;
161             cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
162 //          =======================================================
163             TheSame1(NbrSol) = 0;
164             TheSame2(NbrSol) = 0;
165             gp_Dir2d dc1(originL1.XY()-Center.XY());
166             Standard_Real sign = dc1.Dot(normL1);
167             if (!Qualified1.IsUnqualified()) { 
168               qualifier1(NbrSol) = Qualified1.Qualifier();
169             }
170             else if (dc1.Dot(normL1) > 0.0) {   
171               qualifier1(NbrSol) = GccEnt_outside; 
172             }
173             else { qualifier1(NbrSol) = GccEnt_enclosed; }
174             qualifier2(NbrSol) = GccEnt_noqualifier;
175             dc1=gp_Dir2d(sign*gp_XY(-dirL1.Y(),dirL1.X()));
176             pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+dist1*dc1.XY());
177             par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
178                                               pnttg1sol(NbrSol));
179             pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
180             pntcen(NbrSol) = Center;
181             parcen3(NbrSol) = ElCLib::Parameter(OnCirc,pntcen(NbrSol));
182             pnttg2sol(NbrSol) = Point2;
183             pararg2(NbrSol) = 0.;
184             par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
185                                               pnttg2sol(NbrSol));
186             qualifier2(NbrSol) = GccEnt_noqualifier;
187            }
188         }
189       }
190       WellDone = Standard_True;
191     }
192   }
193 }
194