0022312: Translation of french commentaries in OCCT files
[occt.git] / src / GccAna / GccAna_Circ2d2TanOn_4.cxx
1 // File:        GccAna_Circ2d2TanOn_4.cxx
2 // Created:     Thu Jan  2 15:54:38 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 <GccAna_LinPnt2dBisec.hxx>
12 #include <IntAna2d_AnaIntersection.hxx>
13 #include <IntAna2d_IntPoint.hxx>
14 #include <GccInt_IType.hxx>
15 #include <GccInt_Bisec.hxx>
16 #include <GccInt_BCirc.hxx>
17 #include <GccInt_BLine.hxx>
18 #include <IntAna2d_Conic.hxx>
19 #include <GccEnt_BadQualifier.hxx>
20 #include <Precision.hxx>
21 //=========================================================================
22 //   Creation of a circle Tangent to : 1 straight line L1.                +
23 //                        Passing by : 1 point Point2.                    +
24 //                        Centered on  : 1 straight line OnLine.                  +
25 //   with a Tolerance of precision  : Tolerance.                        +
26 //                                                                        +
27 //  We start by making difference with various boundary cases that will be +
28 //  processed separately.                                            +
29 //  For the general case:                                                  +
30 //  ====================                                                  +
31 //  We calculate bissectrices to L1 and Point2 that give us       +
32 //  all possible locations of centers of all circles        +
33 //  tangent to L1 and passing through Point2.                                  +
34 //  We intersect these bissectrices with straight line OnLine which gives us +
35 //  the points among which we'll choose the solutions.   +
36 //  The choices are made basing on Qualifieurs of L1.        +
37 //=========================================================================
38
39 GccAna_Circ2d2TanOn::
40    GccAna_Circ2d2TanOn (const GccEnt_QualifiedLin&  Qualified1 ,
41                         const gp_Pnt2d&             Point2     ,
42                         const gp_Lin2d&             OnLine     ,
43                         const Standard_Real         Tolerance  ):
44    cirsol(1,4)     ,
45    qualifier1(1,4) ,
46    qualifier2(1,4),
47    TheSame1(1,4) ,
48    TheSame2(1,4) ,
49    pnttg1sol(1,4)  ,
50    pnttg2sol(1,4)  ,
51    pntcen(1,4)     ,
52    par1sol(1,4)    ,
53    par2sol(1,4)    ,
54    pararg1(1,4)    ,
55    pararg2(1,4)    ,
56    parcen3(1,4)    
57 {
58   TheSame1.Init(0);
59   TheSame2.Init(0);
60   WellDone = Standard_False;
61   NbrSol = 0;
62   if (!(Qualified1.IsEnclosed() ||
63         Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
64     GccEnt_BadQualifier::Raise();
65     return;
66   }
67   Standard_Real Tol = Abs(Tolerance);
68   gp_Dir2d dirx(1.,0.);
69   gp_Lin2d L1 = Qualified1.Qualified();
70   gp_Pnt2d originL1(L1.Location());
71   gp_Dir2d dirL1(L1.Direction());
72   gp_Dir2d normal(-dirL1.Y(),dirL1.X());
73
74 //=========================================================================
75 //   Processing of boundary cases.                                          +
76 //=========================================================================
77
78   if (dirL1.IsEqual(OnLine.Direction(),Precision::Confusion()) &&
79       OnLine.Distance(originL1)<Precision::Confusion()) {
80     // POP : l2s 2 straight line are identic : no Sol
81     NbrSol = 0;
82     return ;
83   }
84
85
86   Standard_Real dp2l = OnLine.Distance(Point2);
87   gp_Dir2d donline(OnLine.Direction());
88   gp_Pnt2d pinterm(Point2.XY()+dp2l*gp_XY(-donline.Y(),donline.X()));
89   if (OnLine.Distance(pinterm) > Tol) {
90     pinterm = gp_Pnt2d(Point2.XY()-dp2l*gp_XY(-donline.Y(),donline.X()));
91   }
92   Standard_Real dist = L1.Distance(pinterm);
93   if (Abs(dist-dp2l) <= Tol) {
94     gp_Dir2d dirbid(originL1.XY()-pinterm.XY());
95     if (Qualified1.IsEnclosed() && dirbid.Dot(normal)<0.) {
96       WellDone = Standard_True;
97     }
98     else if (Qualified1.IsOutside() && dirbid.Dot(normal) > 0.) {
99       WellDone = Standard_True;
100     }
101     else if (Qualified1.IsUnqualified()) { WellDone = Standard_True; }
102     if (WellDone) {
103       NbrSol++;
104       cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),dp2l);
105 //    ======================================================
106       qualifier2(NbrSol) = GccEnt_noqualifier;
107       gp_Dir2d dc2(originL1.XY()-pinterm.XY());
108       if (!Qualified1.IsUnqualified()) { 
109         qualifier1(NbrSol) = Qualified1.Qualifier();
110       }
111       else if (dc2.Dot(normal) > 0.0) {
112         qualifier1(NbrSol) = GccEnt_outside;
113       }
114       else { qualifier1(NbrSol) = GccEnt_enclosed; }
115       Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL1.Y(),
116                                             dirL1.X()));
117       dc2 = gp_Dir2d(sign*gp_XY(-dirL1.Y(),dirL1.X()));
118       pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dp2l*dc2.XY());
119       pnttg2sol(NbrSol) = Point2;
120       pntcen(NbrSol) = pinterm;
121       par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
122       pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
123       par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
124       pararg2(NbrSol) = 0.;
125       parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
126       return;
127     }
128   }
129
130 //=========================================================================
131 //   General case.                                                        +
132 //=========================================================================
133
134   GccAna_LinPnt2dBisec Bis(L1,Point2);
135   if (Bis.IsDone()) {
136     Handle(GccInt_Bisec) Sol = Bis.ThisSolution();
137     GccInt_IType type = Sol->ArcType();
138     IntAna2d_AnaIntersection Intp;
139     if (type == GccInt_Lin) {
140       Intp.Perform(OnLine,Sol->Line());
141     }
142     if (type == GccInt_Par) {
143       Intp.Perform(OnLine,IntAna2d_Conic(Sol->Parabola()));
144     }
145     if (Intp.IsDone()) {
146       if (!Intp.IsEmpty()) {
147         for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
148           gp_Pnt2d Center(Intp.Point(j).Value());
149           Standard_Real Radius = L1.Distance(Center);
150 //        Standard_Integer nbsol = 1;
151           Standard_Boolean ok = Standard_False;
152           if (Qualified1.IsEnclosed()) {
153             if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
154                  ((originL1.Y()-Center.Y())*(dirL1.X())))<=0){
155               ok = Standard_True;
156             }
157           }
158           else if (Qualified1.IsOutside()) {
159             if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
160                  ((originL1.Y()-Center.Y())*(dirL1.X())))>=0){
161               ok = Standard_True;
162             }
163           }
164           else if (Qualified1.IsUnqualified()) {
165             ok = Standard_True;
166           }
167           if (ok) {
168             NbrSol++;
169             cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
170 //          =======================================================
171             qualifier2(NbrSol) = GccEnt_noqualifier;
172             gp_Dir2d dc2(originL1.XY()-Center.XY());
173             if (!Qualified1.IsUnqualified()) { 
174               qualifier1(NbrSol) = Qualified1.Qualifier();
175             }
176             else if (dc2.Dot(normal) > 0.0) {
177               qualifier1(NbrSol) = GccEnt_outside;
178             }
179             else { qualifier1(NbrSol) = GccEnt_enclosed; }
180             TheSame1(NbrSol) = 0;
181             TheSame2(NbrSol) = 0;
182             gp_Dir2d dc1(originL1.XY()-Center.XY());
183             Standard_Real sign = dc1.Dot(gp_Dir2d(normal));
184             dc1=gp_Dir2d(sign*(normal.XY()));
185             pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
186             pnttg2sol(NbrSol) = Point2;
187             pntcen(NbrSol) = Center;
188             par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
189                                               pnttg1sol(NbrSol));
190             pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
191             par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
192                                               pnttg2sol(NbrSol));
193             pararg2(NbrSol) = 0.;
194             parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
195           }
196         }
197       }
198       WellDone = Standard_True;
199     }
200   }
201 }
202