0033661: Data Exchange, Step Import - Tessellated GDTs are not imported
[occt.git] / src / GccAna / GccAna_Circ2d2TanRad_3.cxx
1 // Created on: 1991-09-24
2 // Created by: Joelle CHAUVET
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 under
9 // the terms of the GNU Lesser General Public License 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 // Modified:    Thu Jun 18 15:45:00 1998
18 //              PRO10310 : cas ou le point est sur la droite
19
20 #include <ElCLib.hxx>
21 #include <GccAna_Circ2d2TanRad.hxx>
22 #include <GccEnt_BadQualifier.hxx>
23 #include <GccEnt_QualifiedLin.hxx>
24 #include <gp_Ax2d.hxx>
25 #include <gp_Circ2d.hxx>
26 #include <gp_Lin2d.hxx>
27 #include <gp_Pnt2d.hxx>
28 #include <IntAna2d_AnaIntersection.hxx>
29 #include <IntAna2d_IntPoint.hxx>
30 #include <Standard_NegativeValue.hxx>
31 #include <TColStd_Array1OfReal.hxx>
32
33 // circular tangent to a line and a point and a given radius
34 //=============================================================
35 //========================================================================
36 // Initialize WellDone to false.                                         +
37 // Return line L1.                                                       +
38 // Leave with error if the construction is impossible.                   +
39 // Create parallel to L1 in the proper direction.                        +
40 // Create the circle with center at Point1 of radius Radius.             +
41 // Intersect the parallel and the circle.                                +
42 //                              ==> The center point of the  solution.   +
43 // Create the solution to be added to already found solutions.           +
44 // Fill the fields.                                                      +
45 //========================================================================
46 GccAna_Circ2d2TanRad::
47    GccAna_Circ2d2TanRad (const GccEnt_QualifiedLin&  Qualified1 ,
48                          const gp_Pnt2d&             Point2     ,
49                          const Standard_Real         Radius     ,
50                          const Standard_Real         Tolerance  ):
51    qualifier1(1,2) ,
52    qualifier2(1,2),
53    TheSame1(1,2)   ,
54    TheSame2(1,2)   ,
55    cirsol(1,2)     ,
56    pnttg1sol(1,2)  ,
57    pnttg2sol(1,2)  ,
58    par1sol(1,2)    ,
59    par2sol(1,2)    ,
60    pararg1(1,2)    ,
61    pararg2(1,2)    
62 {
63
64   gp_Dir2d dirx(1.0,0.0);
65   Standard_Real Tol = Abs(Tolerance);
66   NbrSol = 0;
67   WellDone = Standard_False;
68   if (!(Qualified1.IsEnclosed() || Qualified1.IsOutside() || 
69         Qualified1.IsUnqualified())) {
70     throw GccEnt_BadQualifier();
71     return;
72   }
73   Standard_Integer nbsol = 0;
74   Standard_Integer nbcote=0;
75   TColStd_Array1OfReal cote(1,2);
76   gp_Lin2d L1 = Qualified1.Qualified();
77   Standard_Real displ1 = L1.Distance(Point2);
78   Standard_Real xdir = (L1.Direction()).X();
79   Standard_Real ydir = (L1.Direction()).Y();
80   Standard_Real lxloc = (L1.Location()).X();
81   Standard_Real lyloc = (L1.Location()).Y();
82   gp_Pnt2d origin1(lxloc,lyloc);
83   gp_Dir2d normL1(-ydir,xdir);
84   Standard_Real cxloc = Point2.X();
85   Standard_Real cyloc = Point2.Y();
86
87   if (Radius < 0.0) { throw Standard_NegativeValue(); }
88
89   else {
90     if ( displ1-Radius*2.0 > Tol) { WellDone = Standard_True; }
91     else if (Qualified1.IsEnclosed()) {
92 //  =================================
93       if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0)) { 
94         WellDone = Standard_True; 
95       }
96       else {
97         if ( displ1-Radius*2.0 > 0.0) {
98           nbsol = 2;
99           NbrSol = 1;
100           nbcote = 1;
101           cote(1) = 1.0;
102         }
103         else {
104           nbsol = 1;
105           nbcote = 1;
106           cote(1) = 1.0;
107         } 
108       }
109     }
110     else if (Qualified1.IsOutside()) {
111 //  ================================
112       if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0)) { 
113         WellDone = Standard_True; 
114       }
115       else {
116         if ( displ1-Radius*2.0 > 0.0) {
117           nbsol = 2;
118           nbcote = 1;
119           cote(1) = -1.0;
120         }
121         else {
122           nbsol = 1;
123           nbcote = 1;
124           cote(1) = -1.0;
125         }
126       }
127     }
128     else if (Qualified1.IsUnqualified()) {
129 //  ====================================
130       if ( displ1-Radius*2.0 > 0.0) {
131         if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0)) {
132           nbsol = 2;
133           nbcote = 1;
134           cote(1) = 1.0;
135         }
136         else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0)) {
137           nbsol = 2;
138           nbcote = 1;
139           cote(1) = -1.0;
140         }
141       }
142       else {
143         nbsol = 1;
144         nbcote = 2;
145         cote(1) = 1.0;
146         cote(2) = -1.0;
147       }
148     }
149
150     if (nbsol == 1) {
151       if (displ1<1.e-10) {
152         // particular case when Point2 is on the line
153         // construct two solutions directly
154         for (Standard_Integer jcote = 1 ; jcote <= nbcote ; jcote++) {
155           NbrSol++;
156           gp_Pnt2d Center(cxloc-cote(jcote)*ydir*Radius,
157                           cyloc+cote(jcote)*xdir*Radius);
158           cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
159 //        =======================================================
160           qualifier2(NbrSol) = GccEnt_noqualifier;
161           if (!Qualified1.IsUnqualified()) { 
162             qualifier1(NbrSol) = Qualified1.Qualifier();
163           }
164           else if (cote(jcote) > 0.0) {
165             qualifier1(NbrSol) = GccEnt_outside;
166           }
167           else { 
168             qualifier1(NbrSol) = GccEnt_enclosed; 
169           }
170           TheSame1(NbrSol) = 0;
171           TheSame2(NbrSol) = 0;
172           pnttg1sol(NbrSol) = Point2;
173           pnttg2sol(NbrSol) = Point2;
174         }
175         WellDone = Standard_True;
176       }
177       else {
178         gp_Circ2d cirint(gp_Ax2d(Point2,dirx),Radius);
179         for (Standard_Integer jcote = 1 ; jcote <= nbcote ; jcote++) {
180           gp_Lin2d  linint(gp_Pnt2d(lxloc-cote(jcote)*ydir*Radius,
181                                     lyloc+cote(jcote)*xdir*Radius),
182                            L1.Direction());
183           IntAna2d_AnaIntersection Intp(linint,cirint);
184           if (Intp.IsDone()) {
185             if (!Intp.IsEmpty()) {
186               for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol<2; i++) {
187                 NbrSol++;
188                 gp_Pnt2d Center(Intp.Point(i).Value());
189                 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
190   //            =======================================================
191                 gp_Dir2d dc1(origin1.XY()-Center.XY());
192                 qualifier2(NbrSol) = GccEnt_noqualifier;
193                 if (!Qualified1.IsUnqualified()) { 
194                   qualifier1(NbrSol) = Qualified1.Qualifier();
195                 }
196                 else if (dc1.Dot(normL1) > 0.0) {
197                   qualifier1(NbrSol) = GccEnt_outside;
198                 }
199                 else { qualifier1(NbrSol) = GccEnt_enclosed; }
200                 TheSame1(NbrSol) = 0;
201                 TheSame2(NbrSol) = 0;
202                 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+
203                                            cote(jcote)*Radius*gp_XY(ydir,-xdir));
204                 pnttg2sol(NbrSol) = Point2;
205               }
206             }
207             WellDone = Standard_True;
208           }
209         }
210       }
211     }
212
213     else if (nbsol == 2) {
214       gp_Pnt2d Center(Point2.XY()+cote(1)*Radius*gp_XY(-ydir,xdir));
215       WellDone = Standard_True;
216       NbrSol = 1;
217       cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
218 //    ==================================================
219       qualifier2(1) = GccEnt_noqualifier;
220       TheSame1(1) = 0;
221       TheSame2(1) = 0;
222       pnttg1sol(1)=gp_Pnt2d(Center.XY()+cote(1)*Radius*gp_XY(ydir,-xdir));
223       pnttg2sol(1) = Point2;
224     }
225   }
226
227   for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
228     par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
229     pararg1(i)=ElCLib::Parameter(L1,pnttg1sol(i));
230     par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
231     pararg2(i)=0.;
232   }
233
234 }
235
236
237
238