0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / Geom2dGcc / Geom2dGcc_Lin2d2Tan.cxx
1 // Created on: 1992-10-21
2 // Created by: Remi GILET
3 // Copyright (c) 1992-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
18 #include <GccAna_Lin2d2Tan.hxx>
19 #include <GccEnt_BadQualifier.hxx>
20 #include <GccEnt_QualifiedCirc.hxx>
21 #include <Geom2d_Circle.hxx>
22 #include <Geom2dAdaptor_Curve.hxx>
23 #include <Geom2dGcc_CurveTool.hxx>
24 #include <Geom2dGcc_Lin2d2Tan.hxx>
25 #include <Geom2dGcc_Lin2d2TanIter.hxx>
26 #include <Geom2dGcc_QCurve.hxx>
27 #include <Geom2dGcc_QualifiedCurve.hxx>
28 #include <gp_Lin2d.hxx>
29 #include <gp_Pnt2d.hxx>
30 #include <Standard_NegativeValue.hxx>
31 #include <Standard_OutOfRange.hxx>
32 #include <StdFail_NotDone.hxx>
33
34 //  Modified by Sergey KHROMOV - Wed Oct 16 11:44:41 2002 Begin
35 Geom2dGcc_Lin2d2Tan::
36     Geom2dGcc_Lin2d2Tan (const Geom2dGcc_QualifiedCurve& Qualified1,
37                          const Geom2dGcc_QualifiedCurve& Qualified2,
38                          const Standard_Real             Tolang    ):
39   linsol(1,4)    ,
40   qualifier1(1,4),
41   qualifier2(1,4),
42   pnttg1sol(1,4) ,
43   pnttg2sol(1,4) ,
44   par1sol(1,4)   ,
45   par2sol(1,4)   ,
46   pararg1(1,4)   ,
47   pararg2(1,4)   
48 {
49   Geom2dAdaptor_Curve C1 = Qualified1.Qualified();
50   Geom2dAdaptor_Curve C2 = Qualified2.Qualified();
51   Handle(Geom2d_Curve) CC1 = C1.Curve();
52   Handle(Geom2d_Curve) CC2 = C2.Curve();
53   GeomAbs_CurveType Type1 = C1.GetType();
54   GeomAbs_CurveType Type2 = C2.GetType();
55
56 //=============================================================================
57 //                            Appel a GccAna.                                 +
58 //=============================================================================
59
60   NbrSol = 0;
61   if (Type1 == GeomAbs_Circle && Type2 == GeomAbs_Circle ) {
62     Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
63     gp_Circ2d c1(CCC1->Circ2d());
64     Handle(Geom2d_Circle) CCC2 = Handle(Geom2d_Circle)::DownCast(CC2);
65     gp_Circ2d c2(CCC2->Circ2d());
66     GccEnt_QualifiedCirc Qc1=GccEnt_QualifiedCirc(c1,Qualified1.Qualifier());
67     GccEnt_QualifiedCirc Qc2=GccEnt_QualifiedCirc(c2,Qualified2.Qualifier());
68     GccAna_Lin2d2Tan Lin(Qc1,Qc2,Tolang);
69     WellDone = Lin.IsDone();
70 //  Modified by Sergey KHROMOV - Thu Apr  5 17:50:48 2001 Begin
71     if (WellDone) {
72 //  Modified by Sergey KHROMOV - Thu Apr  5 17:50:49 2001 End
73       NbrSol = Lin.NbSolutions();
74       for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
75         linsol(i)    = Lin.ThisSolution(i);
76         Lin.Tangency1(i,par1sol(i),pararg1(i),pnttg1sol(i));
77         Lin.Tangency2(i,par2sol(i),pararg2(i),pnttg2sol(i));
78         Lin.WhichQualifier(i,qualifier1(i),qualifier2(i));
79       }
80     }
81   }
82   else {
83     Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
84     Standard_Real      a1FPar      = Geom2dGcc_CurveTool::FirstParameter(C1);
85     Standard_Real      a1LPar      = Geom2dGcc_CurveTool::LastParameter(C1);
86     Standard_Integer   aNbSamples1 = Geom2dGcc_CurveTool::NbSamples(C1);
87     Standard_Real      aStep1      = (a1LPar - a1FPar)/aNbSamples1;
88     Standard_Real      Param1      = a1FPar;
89     Geom2dGcc_QCurve Qc2(C2,Qualified2.Qualifier());
90     Standard_Real      a2FPar      = Geom2dGcc_CurveTool::FirstParameter(C2);
91     Standard_Real      a2LPar      = Geom2dGcc_CurveTool::LastParameter(C2);
92     Standard_Integer   aNbSamples2 = Geom2dGcc_CurveTool::NbSamples(C2);
93     Standard_Real      aStep2      = (a2LPar - a2FPar)/aNbSamples2;
94     Standard_Real      Param2      = a2FPar;
95     Standard_Integer   i;
96     Standard_Integer   j;
97     
98     for (i = 0; i <= aNbSamples1 && NbrSol < 4; i++) {
99       Param2 = a2FPar;
100
101       for (j = 0; j <= aNbSamples2 && NbrSol < 4; j++) {
102         Geom2dGcc_Lin2d2TanIter Lin(Qc1,Qc2,Param1,Param2,Tolang);
103
104         if (Lin.IsDone()) {
105           if (Add(NbrSol + 1, Lin, Tolang, C1, C2))
106             NbrSol++;
107         }
108         Param2 += aStep2;
109       }
110       Param1 += aStep1;
111     }
112
113     WellDone = (NbrSol > 0);
114   }
115 }
116
117 Geom2dGcc_Lin2d2Tan::
118     Geom2dGcc_Lin2d2Tan (const Geom2dGcc_QualifiedCurve& Qualified1,
119                          const gp_Pnt2d&                 ThePoint  ,
120                          const Standard_Real             Tolang    ):
121   linsol(1,2)    ,
122   qualifier1(1,2),
123   qualifier2(1,2),
124   pnttg1sol(1,2) ,
125   pnttg2sol(1,2) ,
126   par1sol(1,2)   ,
127   par2sol(1,2)   ,
128   pararg1(1,2)   ,
129   pararg2(1,2)   
130 {
131   Geom2dAdaptor_Curve C1 = Qualified1.Qualified();
132   Handle(Geom2d_Curve) CC1 = C1.Curve();
133   GeomAbs_CurveType Type1 = C1.GetType();
134
135 //=============================================================================
136 //                            Appel a GccAna.                                 +
137 //=============================================================================
138
139   NbrSol = 0;
140   if (Type1 == GeomAbs_Circle) {
141     Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
142     gp_Circ2d c1(CCC1->Circ2d());
143     GccEnt_QualifiedCirc Qc1=GccEnt_QualifiedCirc(c1,Qualified1.Qualifier());
144     GccAna_Lin2d2Tan Lin(Qc1,ThePoint,Tolang);
145     WellDone = Lin.IsDone();
146
147     if (WellDone) {
148       NbrSol = Lin.NbSolutions();
149       for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
150         linsol(i)    = Lin.ThisSolution(i);
151         Lin.Tangency1(i,par1sol(i),pararg1(i),pnttg1sol(i));
152         Lin.Tangency2(i,par2sol(i),pararg2(i),pnttg2sol(i));
153         Lin.WhichQualifier(i,qualifier1(i),qualifier2(i));
154       }
155     }
156   }
157   else {
158     Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
159     Standard_Real      aFirstPar  = Geom2dGcc_CurveTool::FirstParameter(C1);
160     Standard_Real      aLastPar   = Geom2dGcc_CurveTool::LastParameter(C1);
161     Standard_Integer   aNbSamples = Geom2dGcc_CurveTool::NbSamples(C1);
162     Standard_Real      aStep      = (aLastPar - aFirstPar)/aNbSamples;
163     Standard_Real      Param1     = aFirstPar;
164     Standard_Integer   i;
165     
166     for (i = 0; i <= aNbSamples && NbrSol < 2; i++) {
167       Geom2dGcc_Lin2d2TanIter Lin(Qc1,ThePoint,Param1,Tolang);
168
169       if (Lin.IsDone()) {
170         if (Add(NbrSol + 1, Lin, Tolang, C1, Geom2dAdaptor_Curve()))
171           NbrSol++;
172       }
173
174       Param1 += aStep;
175     }
176
177     WellDone = (NbrSol > 0);
178   }
179 }
180
181 //  Modified by Sergey KHROMOV - Wed Oct 16 11:44:41 2002 End
182
183 Geom2dGcc_Lin2d2Tan::
184     Geom2dGcc_Lin2d2Tan (const Geom2dGcc_QualifiedCurve& Qualified1,
185                          const Geom2dGcc_QualifiedCurve& Qualified2,
186                          const Standard_Real             Tolang    ,
187                          const Standard_Real             Param1    ,
188                          const Standard_Real             Param2    ):
189   linsol(1,4)    ,
190   qualifier1(1,4),
191   qualifier2(1,4),
192   pnttg1sol(1,4) ,
193   pnttg2sol(1,4) ,
194   par1sol(1,4)   ,
195   par2sol(1,4)   ,
196   pararg1(1,4)   ,
197   pararg2(1,4)   
198 {
199   Geom2dAdaptor_Curve C1 = Qualified1.Qualified();
200   Geom2dAdaptor_Curve C2 = Qualified2.Qualified();
201   Handle(Geom2d_Curve) CC1 = C1.Curve();
202   Handle(Geom2d_Curve) CC2 = C2.Curve();
203   GeomAbs_CurveType Type1 = C1.GetType();
204   GeomAbs_CurveType Type2 = C2.GetType();
205
206 //=============================================================================
207 //                            Appel a GccAna.                                 +
208 //=============================================================================
209
210   NbrSol = 0;
211   if (Type1 == GeomAbs_Circle && Type2 == GeomAbs_Circle ) {
212     Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
213     gp_Circ2d c1(CCC1->Circ2d());
214     Handle(Geom2d_Circle) CCC2 = Handle(Geom2d_Circle)::DownCast(CC2);
215     gp_Circ2d c2(CCC2->Circ2d());
216     GccEnt_QualifiedCirc Qc1=GccEnt_QualifiedCirc(c1,Qualified1.Qualifier());
217     GccEnt_QualifiedCirc Qc2=GccEnt_QualifiedCirc(c2,Qualified2.Qualifier());
218     GccAna_Lin2d2Tan Lin(Qc1,Qc2,Tolang);
219     WellDone = Lin.IsDone();
220 //  Modified by Sergey KHROMOV - Thu Apr  5 17:50:48 2001 Begin
221     if (WellDone) {
222 //  Modified by Sergey KHROMOV - Thu Apr  5 17:50:49 2001 End
223       NbrSol = Lin.NbSolutions();
224       for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
225         linsol(i)    = Lin.ThisSolution(i);
226         Lin.Tangency1(i,par1sol(i),pararg1(i),pnttg1sol(i));
227         Lin.Tangency2(i,par2sol(i),pararg2(i),pnttg2sol(i));
228         Lin.WhichQualifier(i,qualifier1(i),qualifier2(i));
229       }
230     }
231   }
232   else {
233     Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
234     Geom2dGcc_QCurve Qc2(C2,Qualified2.Qualifier());
235     Geom2dGcc_Lin2d2TanIter Lin(Qc1,Qc2,Param1,Param2,Tolang);
236     WellDone = Lin.IsDone();
237 //  Modified by Sergey KHROMOV - Thu Apr  5 17:51:59 2001 Begin
238     if (WellDone) {
239 //  Modified by Sergey KHROMOV - Thu Apr  5 17:52:00 2001 End
240       NbrSol = 1;
241       linsol(1)    = Lin.ThisSolution();
242       Lin.Tangency1(par1sol(1),pararg1(1),pnttg1sol(1));
243       Lin.Tangency2(par2sol(1),pararg2(1),pnttg2sol(1));
244       Lin.WhichQualifier(qualifier1(1),qualifier2(1));
245     }
246   }
247 }
248
249 Geom2dGcc_Lin2d2Tan::
250     Geom2dGcc_Lin2d2Tan (const Geom2dGcc_QualifiedCurve& Qualified1,
251                          const gp_Pnt2d&                 ThePoint  ,
252                          const Standard_Real             Tolang    ,
253                          const Standard_Real             Param1    ):
254   linsol(1,2)    ,
255   qualifier1(1,2),
256   qualifier2(1,2),
257   pnttg1sol(1,2) ,
258   pnttg2sol(1,2) ,
259   par1sol(1,2)   ,
260   par2sol(1,2)   ,
261   pararg1(1,2)   ,
262   pararg2(1,2)   
263 {
264   Geom2dAdaptor_Curve C1 = Qualified1.Qualified();
265   Handle(Geom2d_Curve) CC1 = C1.Curve();
266   GeomAbs_CurveType Type1 = C1.GetType();
267
268 //=============================================================================
269 //                            Appel a GccAna.                                 +
270 //=============================================================================
271
272   NbrSol = 0;
273   if (Type1 == GeomAbs_Circle) {
274     Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
275     gp_Circ2d c1(CCC1->Circ2d());
276     GccEnt_QualifiedCirc Qc1=GccEnt_QualifiedCirc(c1,Qualified1.Qualifier());
277     GccAna_Lin2d2Tan Lin(Qc1,ThePoint,Tolang);
278     WellDone = Lin.IsDone();
279 //  Modified by Sergey KHROMOV - Thu Apr  5 17:52:32 2001 Begin
280     if (WellDone) {
281 //  Modified by Sergey KHROMOV - Thu Apr  5 17:52:34 2001 End
282       NbrSol = Lin.NbSolutions();
283       for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
284         linsol(i)    = Lin.ThisSolution(i);
285         Lin.Tangency1(i,par1sol(i),pararg1(i),pnttg1sol(i));
286         Lin.Tangency2(i,par2sol(i),pararg2(i),pnttg2sol(i));
287         Lin.WhichQualifier(i,qualifier1(i),qualifier2(i));
288       }
289     }
290   }
291   else {
292     Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
293     Geom2dGcc_Lin2d2TanIter Lin(Qc1,ThePoint,Param1,Tolang);
294     WellDone = Lin.IsDone();
295 //  Modified by Sergey KHROMOV - Thu Apr  5 17:53:01 2001 Begin
296     if (WellDone) {
297 //  Modified by Sergey KHROMOV - Thu Apr  5 17:53:02 2001 End
298       NbrSol = 1;
299       linsol(1)    = Lin.ThisSolution();
300       Lin.Tangency1(par1sol(1),pararg1(1),pnttg1sol(1));
301       Lin.Tangency2(par2sol(1),pararg2(1),pnttg2sol(1));
302       Lin.WhichQualifier(qualifier1(1),qualifier2(1));
303     }
304   }
305 }
306
307 Standard_Boolean Geom2dGcc_Lin2d2Tan::
308    IsDone () const { return WellDone; }
309
310 Standard_Integer Geom2dGcc_Lin2d2Tan::
311    NbSolutions () const { return NbrSol; }
312
313 gp_Lin2d Geom2dGcc_Lin2d2Tan::
314    ThisSolution (const Standard_Integer Index) const 
315 {
316   if (Index > NbrSol || Index <= 0) { throw Standard_OutOfRange(); }
317   return linsol(Index);
318 }
319
320 void Geom2dGcc_Lin2d2Tan::
321    WhichQualifier (const Standard_Integer Index  ,
322                          GccEnt_Position& Qualif1,
323                          GccEnt_Position& Qualif2) const
324 {
325   if (!WellDone) { throw StdFail_NotDone(); }
326   else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
327   else { 
328     Qualif1 = qualifier1(Index);
329     Qualif2 = qualifier2(Index);
330   }
331 }
332
333 void Geom2dGcc_Lin2d2Tan::
334   Tangency1 (const Standard_Integer Index,
335              Standard_Real& ParSol,
336              Standard_Real& ParArg,
337              gp_Pnt2d& PntSol) const 
338 {
339   if (!WellDone) { throw StdFail_NotDone(); }
340   else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
341   else {
342     ParSol = par1sol(Index);
343     ParArg = pararg1(Index);
344     PntSol = pnttg1sol(Index);
345   }
346 }
347   
348 void Geom2dGcc_Lin2d2Tan::
349    Tangency2 (const Standard_Integer   Index  ,
350                     Standard_Real&     ParSol ,
351                     Standard_Real&     ParArg ,
352                     gp_Pnt2d& PntSol ) const 
353 {
354   if (!WellDone) { throw StdFail_NotDone(); }
355   else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
356   else {
357     ParSol = par2sol(Index);
358     ParArg = pararg2(Index);
359     PntSol = pnttg2sol(Index);
360   }
361 }
362
363 Standard_Boolean Geom2dGcc_Lin2d2Tan::Add(const Standard_Integer     theIndex,
364                                           const Geom2dGcc_Lin2d2TanIter &theLin,
365                                           const Standard_Real        theTol,
366                                           const Geom2dAdaptor_Curve &theC1,
367                                           const Geom2dAdaptor_Curve &theC2)
368 {
369   Standard_Integer i;
370   Standard_Real    aPar1sol;
371   Standard_Real    aPar2sol;
372   Standard_Real    aPar1arg;
373   Standard_Real    aPar2arg;
374   gp_Pnt2d         aPnt1Sol;
375   gp_Pnt2d         aPnt2Sol;
376   gp_Lin2d         aLin   = theLin.ThisSolution();
377
378   theLin.Tangency1(aPar1sol, aPar1arg, aPnt1Sol);
379   theLin.Tangency2(aPar2sol, aPar2arg, aPnt2Sol);
380
381   for(i = 1; i < theIndex; i++) {
382     if (Abs(aPar1arg - pararg1(i)) <= theTol &&
383         Abs(aPar2arg - pararg2(i)) <= theTol)
384       return Standard_False;
385   }
386
387   gp_Dir2d aLinDir = aLin.Direction();
388   gp_Vec2d aVTan;
389   gp_Pnt2d aPoint;
390
391   Geom2dGcc_CurveTool::D1(theC1, aPar1arg, aPoint, aVTan);
392
393   if (Abs(aLinDir.Crossed(gp_Dir2d(aVTan))) > theTol)
394     return Standard_False;
395
396   if (!theC2.Curve().IsNull()) {
397     Geom2dGcc_CurveTool::D1(theC2, aPar2arg, aPoint, aVTan);
398
399     if (Abs(aLinDir.Crossed(gp_Dir2d(aVTan))) > theTol)
400       return Standard_False;
401   }
402
403   linsol(theIndex)    = aLin;
404   par1sol(theIndex)   = aPar1sol;
405   pararg1(theIndex)   = aPar1arg;
406   pnttg1sol(theIndex) = aPnt1Sol;
407   par2sol(theIndex)   = aPar2sol;
408   pararg2(theIndex)   = aPar2arg;
409   pnttg2sol(theIndex) = aPnt2Sol;
410
411   theLin.WhichQualifier(qualifier1(theIndex),qualifier2(theIndex));
412
413   return Standard_True;
414 }