0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / IntCurve / IntCurve_IntConicConic_1.cxx
1 // File:        IntCurve_IntConicConic_1.cxx
2 // Created:     Wed May  6 16:00:06 1992
3 // Author:      Laurent BUCHARD
4 //              <lbr@topsn3>
5 // a modifier le cas de 2 points confondus ( Insert a la place d'append ? ) 
6
7 #include <IntCurve_IntConicConic.jxx>
8
9 #include <IntCurve_IConicTool.hxx>
10 #include <IntCurve_PConic.hxx>
11 #include <IntRes2d_Domain.hxx>
12 #include <gp.hxx>
13 #include <IntCurve_IntConicConic_Tool.hxx>
14 #include <IntImpParGen.hxx>
15 #include <IntCurve_IntConicConic_1.hxx>
16 #include <ElCLib.hxx>
17 #include <Standard_ConstructionError.hxx>
18 #include <IntRes2d_IntersectionPoint.hxx>
19 #include <IntRes2d_IntersectionSegment.hxx>
20
21 #include <gp_Pnt2d.hxx>
22 #include <gp_Vec2d.hxx>
23 #include <Precision.hxx>
24 #include <IntRes2d_TypeTrans.hxx>
25
26 Standard_Boolean Affichage=Standard_False;
27 Standard_Boolean AffichageGraph=Standard_True;
28
29 //modified by NIZHNY-MKK  Tue Feb 15 10:53:34 2000.BEGIN
30 // #define TOLERANCE_ANGULAIRE 0.00000001
31 #define TOLERANCE_ANGULAIRE 1.e-15 //the reason is at least to make an accordance between transition and position computation.
32 //modified by NIZHNY-MKK  Tue Feb 15 10:53:45 2000.END
33
34 const Standard_Real PIsur2 = 0.5*M_PI;
35
36 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 IntRes2d_Position FindPositionLL(Standard_Real&,const IntRes2d_Domain&);
38 const IntRes2d_IntersectionPoint SegmentToPoint( const IntRes2d_IntersectionPoint& Pa
39                                                 ,const IntRes2d_Transition& T1a
40                                                 ,const IntRes2d_Transition& T2a
41                                                 ,const IntRes2d_IntersectionPoint& Pb
42                                                 ,const IntRes2d_Transition& T1b
43                                                 ,const IntRes2d_Transition& T2b);  
44 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45 void ProjectOnC2AndIntersectWithC2Domain(const gp_Circ2d& Circle1
46                                          ,const gp_Circ2d& Circle2
47                                          ,PeriodicInterval& C1DomainAndRes
48                                          ,PeriodicInterval& DomainC2
49                                          ,PeriodicInterval* SolutionC1
50                                          ,PeriodicInterval* SolutionC2
51                                          ,Standard_Integer &NbSolTotal
52                                          ,const Standard_Boolean IdentCircles)
53 {
54   
55   if(C1DomainAndRes.IsNull()) return;
56   //-------------------------------------------------------------------------
57   //--  On cherche l intervalle correspondant sur C2
58   //--  Puis on intersecte l intervalle avec le domaine de C2
59   //--  Enfin, on cherche l intervalle correspondant sur C1
60   //--
61   Standard_Real C2inf = 
62     ElCLib::CircleParameter(Circle2.Axis()
63                             ,ElCLib::CircleValue(C1DomainAndRes.Binf
64                                                  ,Circle1.Axis(),Circle1.Radius()));
65   Standard_Real C2sup = 
66     ElCLib::CircleParameter(Circle2.Axis()
67                             ,ElCLib::CircleValue(C1DomainAndRes.Bsup
68                                                  ,Circle1.Axis(),Circle1.Radius()));
69
70   PeriodicInterval C2Inter(C2inf,C2sup);
71
72   if(!IdentCircles) {
73     if(C2Inter.Length() > M_PI)
74       C2Inter.Complement();
75   }
76   else {
77     if(C2sup<=C2inf) C2sup+=PIpPI;
78     if(C2inf>=PIpPI) {
79       C2sup-=PIpPI;
80       C2inf-=PIpPI;
81     }
82     C2Inter.Binf=C2inf;
83     C2Inter.Bsup=C2sup; //--- Verifier la longueur de l'intervalle sur C2
84     C2Inter.Bsup=C2inf+C1DomainAndRes.Bsup-C1DomainAndRes.Binf;
85   }
86   
87   PeriodicInterval C2InterAndDomain[2];
88   
89   for(Standard_Integer i=0; i<2 ; i++) {
90     C2InterAndDomain[i]=(i==0)?  DomainC2.FirstIntersection(C2Inter)
91                                : DomainC2.SecondIntersection(C2Inter);
92   
93     if(!C2InterAndDomain[i].IsNull()) {
94
95       Standard_Real C1inf = 
96         ElCLib::CircleParameter(Circle1.Axis()
97                                 ,ElCLib::CircleValue(C2InterAndDomain[i].Binf
98                                         ,Circle2.Axis(),Circle2.Radius()));
99       Standard_Real C1sup = 
100         ElCLib::CircleParameter(Circle1.Axis()
101                                 ,ElCLib::CircleValue(C2InterAndDomain[i].Bsup
102                                         ,Circle2.Axis(),Circle2.Radius()));
103
104       SolutionC1[NbSolTotal]=PeriodicInterval(C1inf,C1sup);
105       if(!IdentCircles) {
106         if(SolutionC1[NbSolTotal].Length() > M_PI)
107           SolutionC1[NbSolTotal].Complement();
108       }
109       else {
110         if(SolutionC1[NbSolTotal].Bsup <= SolutionC1[NbSolTotal].Binf) {
111           SolutionC1[NbSolTotal].Bsup+=PIpPI;
112         }
113         if(SolutionC1[NbSolTotal].Binf>=PIpPI) {
114           SolutionC1[NbSolTotal].Binf-=PIpPI;
115           SolutionC1[NbSolTotal].Bsup-=PIpPI;     
116         }
117       }
118       SolutionC2[NbSolTotal]=C2InterAndDomain[i];
119       NbSolTotal++;
120     }
121   }
122 }
123 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
124 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
125 void CircleCircleGeometricIntersection(const gp_Circ2d& C1
126                                        ,const gp_Circ2d& C2
127                                        ,const Standard_Real Tol
128                                        ,const Standard_Real TolTang
129                                        ,PeriodicInterval& C1_Res1
130                                        ,PeriodicInterval& C1_Res2
131                                        ,Standard_Integer& nbsol) {
132   
133   Standard_Real C1_binf1,C1_binf2=0,C1_bsup1,C1_bsup2=0;
134   Standard_Real dO1O2=(C1.Location()).Distance(C2.Location());
135   Standard_Real R1=C1.Radius();
136   Standard_Real R2=C2.Radius();
137   Standard_Real AbsR1mR2=Abs(R1-R2);
138   //---------------------------------------------------------------- 
139   if(dO1O2 > (R1+R2+Tol)) {
140     if(dO1O2 > (R1+R2+TolTang)) { 
141       nbsol=0; 
142       return; 
143     }
144     else { 
145       C1_binf1 = 0.0;
146       C1_bsup1 = 0.0;
147       nbsol = 1;
148     }
149   }
150   //---------------------------------------------------------------- 
151   else if(dO1O2 <= Tol  &&  AbsR1mR2<=Tol)  { 
152     nbsol=3; 
153     return; 
154   }
155   else { 
156     //---------------------------------------------------------------- 
157     Standard_Real R1pR2=R1+R2;
158     Standard_Real R1pTol=R1+Tol;
159     Standard_Real R1mTol=R1-Tol;
160 //    Standard_Real R1R1=R1*R1;
161     Standard_Real R2R2=R2*R2;
162     Standard_Real R1pTolR1pTol=R1pTol*R1pTol;
163     Standard_Real R1mTolR1mTol=R1mTol*R1mTol;
164     Standard_Real dO1O2dO1O2=dO1O2*dO1O2;
165     Standard_Real dAlpha1;
166     //--------------------------------------------------------------- Cas 
167     //-- C2 coupe le cercle C1+ (=C(x1,y1,R1+Tol))
168     //--            1 seul segment donne par Inter C2 C1+
169     //--
170     if(dO1O2 > R1pR2-Tol) { 
171       Standard_Real dx=(R1pTolR1pTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
172       Standard_Real dy=(R1pTolR1pTol-dx*dx);
173       dy=(dy>=0.0)? Sqrt(dy) : 0.0;
174       dAlpha1=ATan2(dy,dx);
175       
176       C1_binf1=-dAlpha1;  
177       C1_bsup1=dAlpha1;
178       nbsol=1;
179     }
180     //--------------------------------------------------------------------
181     //--           2 segments donnes par Inter C2 avec C1- C1 C1+
182     //-- Seul le signe de dx change si dO1O2 < Max(R1,R2)
183     //-- 
184     else if(dO1O2 > AbsR1mR2-Tol) {  // -- + 
185       //------------------- Intersection C2 C1+ --------------------------
186       Standard_Real dx=(R1pTolR1pTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
187       Standard_Real dy=(R1pTolR1pTol-dx*dx); 
188       dy=(dy>=0.0)? Sqrt(dy) : 0.0;
189       
190       dAlpha1=ATan2(dy,dx);
191       C1_binf1=-dAlpha1;  C1_bsup2=dAlpha1;  //--  |...?     ?...|   Sur C1
192       
193       //------------------ Intersection C2 C1- -------------------------
194       dx=(R1mTolR1mTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
195       dy=(R1mTolR1mTol-dx*dx);
196       dy=(dy>=0.0)? Sqrt(dy) : 0.0;
197       dAlpha1=ATan2(dy,dx);
198       
199       C1_binf2=dAlpha1;  C1_bsup1=-dAlpha1;  //--  |...x     x...|   Sur C1
200       nbsol=2;    
201       //------------------------------
202       //-- Les 2 intervalles sont ils 
203       //-- en fait un seul inter ? 
204       //-- 
205       if(dy==0) {    //-- Les 2 bornes internes sont identiques 
206         C1_bsup1 = C1_bsup2; 
207         nbsol = 1;
208       }
209       else { 
210         if(C1_binf1>C1_bsup1) { 
211           dAlpha1 = C1_binf1; C1_binf1 = C1_bsup1; C1_bsup1 = dAlpha1; 
212         }
213         if(C1_binf2>C1_bsup2) { 
214           dAlpha1 = C1_binf2; C1_binf2 = C1_bsup2; C1_bsup2 = dAlpha1; 
215         }
216         if(   ((C1_binf1<=C1_bsup2) && (C1_binf1>=C1_binf2))
217            || ((C1_bsup1<=C1_bsup2) && (C1_bsup1>=C1_binf2))) { 
218           if(C1_binf1 > C1_binf2) C1_binf1 = C1_binf2;
219           if(C1_binf1 > C1_bsup2) C1_binf1 = C1_bsup2;
220           if(C1_bsup1 < C1_binf2) C1_bsup1 = C1_binf2;
221           if(C1_bsup1 < C1_bsup2) C1_bsup1 = C1_bsup2;
222           nbsol=1;
223         }
224       }
225     }
226     //--------------------------------------------------------------
227     //--    1 seul segment donne par Inter C2 avec C1- ou C1+
228     else if(dO1O2 > AbsR1mR2-Tol) {
229       
230       Standard_Real dx=(R1mTolR1mTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
231       Standard_Real dy=(R1mTolR1mTol-dx*dx);
232       dy=(dy>=0.0)? Sqrt(dy) : 0.0;
233       dAlpha1=ATan2(dy,dx);
234       
235       dx=(R1pTolR1pTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
236       dy=(R1pTolR1pTol-dx*dx);
237       dy=(dy>=0.0)? Sqrt(dy) : 0.0;
238       Standard_Real dAlpha2=ATan2(dy,dx);
239       
240       if(dAlpha2>dAlpha1) dAlpha1 = dAlpha2;
241       C1_binf1=-dAlpha1;  C1_bsup1=dAlpha1;
242       nbsol=1;
243     }
244     //--------------------------------------------------------------
245     else {
246       if((dO1O2 > AbsR1mR2-TolTang) && (AbsR1mR2-TolTang)>0.0) { 
247         C1_binf1=0.0;  
248         C1_bsup1=0.0;
249         nbsol = 1;
250       }
251       else { 
252         nbsol=0; return ;
253       }
254     }
255   }
256
257   //-- cout<<" C1_binf1:"<<C1_binf1;
258   //-- cout<<" C1_bsup1:"<<C1_bsup1;
259   //-- cout<<" C1_binf2:"<<C1_binf2;
260   //-- cout<<" C1_bsup2:"<<C1_bsup2<<endl;
261   //----------------------------------------------------------------
262   //-- Mise en forme des resultats : 
263   //--    Les calculs ont ete fait dans le repere x1,y1, (O1,O2)
264   //--    On se ramene au repere propre a C1
265
266   gp_Vec2d Axe1=C1.XAxis().Direction();
267   gp_Vec2d AxeO1O2=gp_Vec2d(C1.Location(),C2.Location());
268   
269   Standard_Real dAngle1;
270   if(AxeO1O2.Magnitude() <= gp::Resolution()) 
271     dAngle1=Axe1.Angle(C2.XAxis().Direction());
272   else
273     dAngle1=Axe1.Angle(AxeO1O2);
274
275   if(C1.IsDirect() == Standard_False) { 
276     dAngle1 = -dAngle1; 
277   }
278
279
280   C1_binf1+=dAngle1;  C1_bsup1+=dAngle1;
281   
282   //-- par construction aucun des segments ne peut exceder PI
283   //-- (permet de ne pas gerer trop de cas differents)
284
285   C1_Res1.SetValues(C1_binf1,C1_bsup1);
286   if(C1_Res1.Length() > M_PI) C1_Res1.Complement();
287
288   if(nbsol==2) {
289     C1_binf2+=dAngle1;  C1_bsup2+=dAngle1;
290     C1_Res2.SetValues(C1_binf2,C1_bsup2);
291     if(C1_Res2.Length() > M_PI) C1_Res2.Complement();
292   }
293   else {
294     C1_Res2.SetNull(); 
295   }
296 }
297 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
298 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
299 void ProjectOnLAndIntersectWithLDomain(const gp_Circ2d& Circle
300                                        ,const gp_Lin2d& Line
301                                        ,PeriodicInterval& CDomainAndRes
302                                        ,Interval& LDomain
303                                        ,PeriodicInterval* CircleSolution
304                                        ,Interval* LineSolution
305                                        ,Standard_Integer &NbSolTotal
306                                        ,const IntRes2d_Domain& RefLineDomain
307 //                                     ,const IntRes2d_Domain& )
308                                        ,const IntRes2d_Domain& )
309 {
310   
311   
312   if(CDomainAndRes.IsNull()) return;
313   //-------------------------------------------------------------------------
314   //--  On cherche l intervalle correspondant sur C2
315   //--  Puis on intersecte l intervalle avec le domaine de C2
316   //--  Enfin, on cherche l intervalle correspondant sur C1
317   //--
318
319   Standard_Real Linf=ElCLib::Parameter(Line
320                              ,ElCLib::CircleValue(CDomainAndRes.Binf
321                                                  ,Circle.Axis()
322                                                  ,Circle.Radius()));
323   Standard_Real Lsup=ElCLib::Parameter(Line
324                              ,ElCLib::CircleValue(CDomainAndRes.Bsup
325                                                  ,Circle.Axis()
326                                                  ,Circle.Radius()));
327
328   Interval LInter(Linf,Lsup);   //-- Necessairement Borne 
329   
330   Interval LInterAndDomain=LDomain.IntersectionWithBounded(LInter);
331
332   if(!LInterAndDomain.IsNull) {
333
334     Standard_Real DomLinf = (RefLineDomain.HasFirstPoint())? RefLineDomain.FirstParameter() : -Precision::Infinite();
335     Standard_Real DomLsup = (RefLineDomain.HasLastPoint())? RefLineDomain.LastParameter() : Precision::Infinite();
336     
337     Linf = LInterAndDomain.Binf;
338     Lsup = LInterAndDomain.Bsup;
339
340     if(Linf<DomLinf) {
341       Linf = DomLinf; 
342     }
343     if(Lsup<DomLinf) { 
344       Lsup = DomLinf; 
345     }
346     
347     if(Linf>DomLsup) {
348       Linf = DomLsup; 
349     }
350     if(Lsup>DomLsup) { 
351       Lsup = DomLsup; 
352     }
353   
354     LInterAndDomain.Binf = Linf;
355     LInterAndDomain.Bsup = Lsup;
356
357 #if 0     
358     Standard_Real Cinf = 
359       ElCLib::CircleParameter(Circle.Axis()                                            
360                               ,ElCLib::LineValue(LInterAndDomain.Binf,
361                                         Line.Position()));
362     Standard_Real Csup = 
363       ElCLib::CircleParameter(Circle.Axis()
364                               ,ElCLib::LineValue(LInterAndDomain.Bsup
365                                         ,Line.Position()));
366
367     if(Cinf<CDomainAndRes.Binf) Cinf = CDomainAndRes.Binf;
368     if(Csup>CDomainAndRes.Bsup) Csup = CDomainAndRes.Bsup;
369 #else
370     Standard_Real Cinf=CDomainAndRes.Binf;
371     Standard_Real Csup=CDomainAndRes.Bsup;
372 #endif
373     if(Cinf>=Csup) { Cinf = CDomainAndRes.Binf; Csup = CDomainAndRes.Bsup; } 
374     CircleSolution[NbSolTotal]=PeriodicInterval(Cinf,Csup);
375     if(CircleSolution[NbSolTotal].Length() > M_PI)
376       CircleSolution[NbSolTotal].Complement();
377     
378     LineSolution[NbSolTotal]=LInterAndDomain;
379     NbSolTotal++;
380   }
381 }
382
383 //=======================================================================
384 //function : LineCircleGeometricIntersection
385 //purpose  : 
386 //~~ On cherche des segments d intersection dans le `tuyau` 
387 //~~   R+Tol   R-Tol  ( Tol est TolConf : Tolerance de confusion d arc)
388 //~~ On Cherche un point d intersection a une distance TolTang du cercle.   
389 //=======================================================================
390 void LineCircleGeometricIntersection(const gp_Lin2d& Line,
391                                      const gp_Circ2d& Circle,
392                                      const Standard_Real Tol,
393                                      const Standard_Real TolTang,
394                                      PeriodicInterval& CInt1,
395                                      PeriodicInterval& CInt2,
396                                      Standard_Integer& nbsol) 
397 {
398   
399
400   Standard_Real dO1O2=Line.Distance(Circle.Location());
401   Standard_Real R=Circle.Radius();
402   Standard_Real RmTol=R-Tol;
403   Standard_Real binf1,binf2=0,bsup1,bsup2=0;
404     
405   //---------------------------------------------------------------- 
406   if(dO1O2 > (R+Tol))  {  //-- pas d intersection avec le 'tuyau'
407     if(dO1O2 > (R+TolTang)) {  
408       nbsol=0; 
409       return;
410     }
411     else { 
412       binf1=0.0;  
413       bsup1=0.0;
414       nbsol=1;
415     }
416   }
417   else { 
418     //---------------------------------------------------------------- 
419     Standard_Boolean b2Sol;
420     Standard_Real dAlpha1;
421     //---------------------------------------------------------------
422     //-- Line coupe le cercle Circle+ (=C(x1,y1,R1+Tol))
423     //modified by NIZNHY-PKV Thu May 12 12:25:17 2011f
424     b2Sol=Standard_False;
425     if (R>dO1O2+TolTang) {
426       Standard_Real aX2, aTol2;
427       //
428       aTol2=Tol*Tol;
429       aX2=4.*(R*R-dO1O2*dO1O2);
430       if (aX2>aTol2) {
431         b2Sol=!b2Sol;
432       }
433     }
434     if(dO1O2 > RmTol && !b2Sol) { 
435     //if(dO1O2 > RmTol) { 
436     //modified by NIZNHY-PKV Thu May 12 12:25:20 2011t
437       Standard_Real dx=dO1O2;
438       Standard_Real dy=0.0;     //(RpTol*RpTol-dx*dx); //Patch !!!
439       dy=(dy>=0.0)? Sqrt(dy) : 0.0;
440       dAlpha1=ATan2(dy,dx);
441       
442       binf1=-dAlpha1;  
443       bsup1=dAlpha1;
444       nbsol=1;
445     }  
446     //--------------------------------------------------------------------
447     //--           2 segments donnes par Inter Line avec Circle-  Circle+
448     //-- 
449     else {
450       //------------------- Intersection Line Circle+ --------------------------
451       Standard_Real dx=dO1O2;
452       Standard_Real dy=R*R-dx*dx;    //(RpTol*RpTol-dx*dx); //Patch !!!
453       dy=(dy>=0.0)? Sqrt(dy) : 0.0;
454       
455       dAlpha1=ATan2(dy,dx);
456       binf1=-dAlpha1;  bsup2=dAlpha1;  //--  |...?     ?...|   Sur C1
457       
458       //------------------ Intersection Line Circle-  -------------------------
459       dy=R*R-dx*dx;                  //(RmTol*RmTol-dx*dx); //Patch !!!
460       dy=(dy>=0.0)? Sqrt(dy) : 0.0;
461       dAlpha1=ATan2(dy,dx);
462       
463       binf2=dAlpha1;  bsup1=-dAlpha1;  //--  |...x     x...|   Sur C1
464
465       if((dAlpha1*R)<(Max(Tol,TolTang))) { 
466         bsup1 = bsup2; 
467         nbsol = 1;
468       }
469       else { 
470         nbsol=2;
471       }
472     }
473   }
474   //--------------------------------------------------------------
475   //-- Mise en forme des resultats : 
476   //--    Les calculs ont ete fait dans le repere x1,y1, (O1,O2)
477   //--    On se ramene au repere propre a C1
478   
479   Standard_Real dAngle1=(Circle.XAxis().Direction()).Angle(Line.Direction());
480   
481 #if 0 
482   //---------------------------------------------
483   //-- Si le cercle est indirect alors l origine
484   //-- est vue en -dAngle1. 
485   //--
486   if(Circle.IsDirect() == Standard_False) { 
487     dAngle1 = -dAngle1;
488   }
489 #endif  
490   
491   
492   Standard_Real a,b,c,d;
493   Line.Coefficients(a,b,c);
494   
495   d = a*Circle.Location().X() + b*Circle.Location().Y() + c;
496   
497   if(d>0.0)  dAngle1+= PIsur2;
498   else       dAngle1-= PIsur2;
499
500      
501   if(dAngle1<0.0) dAngle1+=PIpPI;
502   else if(dAngle1>PIpPI) dAngle1-=PIpPI;
503   
504   
505   binf1+=dAngle1;  bsup1+=dAngle1;
506   
507   //-- par construction aucun des segments ne peut exceder PI
508   //-- (permet de ne pas gerer trop de cas differents)
509   
510   if(Circle.IsDirect() == Standard_False) {
511     Standard_Real t=binf1; binf1=bsup1; bsup1=t;
512     binf1 = -binf1;
513     bsup1 = -bsup1;
514   }
515
516
517   CInt1.SetValues(binf1,bsup1);
518   if(CInt1.Length() > M_PI) CInt1.Complement();
519   
520
521   if(nbsol==2) {
522     binf2+=dAngle1;  bsup2+=dAngle1;
523
524     if(Circle.IsDirect() == Standard_False) {
525       Standard_Real t=binf2; binf2=bsup2; bsup2=t;
526       binf2 = -binf2;
527       bsup2 = -bsup2;
528     }
529
530     CInt2.SetValues(binf2,bsup2);
531     if(CInt2.Length() > M_PI) CInt2.Complement();
532   }
533 //  Modified by Sergey KHROMOV - Thu Oct 26 17:51:05 2000 Begin
534   else {
535     if (CInt1.Bsup > PIpPI && CInt1.Binf < PIpPI) {
536       nbsol = 2;
537       binf2 = CInt1.Binf;
538       bsup2 = PIpPI;
539       binf1 = 0.;
540       CInt1.SetValues(binf1,CInt1.Bsup - PIpPI);
541       if(CInt1.Length() > M_PI) CInt1.Complement();
542       CInt2.SetValues(binf2,bsup2);
543       if(CInt2.Length() > M_PI) CInt2.Complement();
544     }
545   }
546 //  Modified by Sergey KHROMOV - Thu Oct 26 17:51:13 2000 End
547 }
548 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
549 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
550 void DomainIntersection(const IntRes2d_Domain& Domain
551                         ,const Standard_Real U1inf
552                         ,const Standard_Real U1sup
553                         ,Standard_Real& Res1inf
554                         ,Standard_Real& Res1sup
555                         ,IntRes2d_Position& PosInf
556                         ,IntRes2d_Position& PosSup) {
557   
558   if(Domain.HasFirstPoint()) {
559     if(U1sup < (Domain.FirstParameter()-Domain.FirstTolerance())) {
560       Res1inf=1; Res1sup=-1; 
561       return;
562     }
563     if(U1inf>(Domain.FirstParameter()+Domain.FirstTolerance())) {
564       Res1inf=U1inf;
565       PosInf=IntRes2d_Middle;
566     }
567     else {
568       Res1inf=Domain.FirstParameter(); 
569       PosInf=IntRes2d_Head;
570     }
571   }
572   else {
573     Res1inf=U1inf; 
574     PosInf=IntRes2d_Middle;
575   }
576   
577   if(Domain.HasLastPoint()) {
578     if(U1inf >(Domain.LastParameter()+Domain.LastTolerance())) {
579       Res1inf=1; Res1sup=-1;
580       return;
581     }
582     if(U1sup<(Domain.LastParameter()-Domain.LastTolerance())) {
583       Res1sup=U1sup; 
584       PosSup=IntRes2d_Middle;
585     }
586     else {
587       Res1sup=Domain.LastParameter();
588       PosSup=IntRes2d_End;
589     }
590   }
591   else {
592     Res1sup=U1sup;
593     PosSup=IntRes2d_Middle;
594   }
595   //-- Si un des points est en bout ,
596   //-- on s assure que les parametres sont corrects
597   if(Res1inf>Res1sup) { 
598     if(PosSup==IntRes2d_Middle) {
599       Res1sup=Res1inf;
600     }
601     else {
602       Res1inf=Res1sup;
603     }
604   }
605   //--- Traitement des cas ou une intersection vraie est dans la tolerance
606   //--  d un des bouts
607   /*if(PosInf==IntRes2d_Head) {
608     if(Res1sup <= (Res1inf+Domain.FirstTolerance())) {
609       Res1sup=Res1inf;
610       PosSup=IntRes2d_Head;
611     }
612   }
613   if(PosSup==IntRes2d_End) {
614     if(Res1inf >= (Res1sup-Domain.LastTolerance())) {
615       Res1inf=Res1sup;
616       PosInf=IntRes2d_End;
617     }
618   }*/
619 }
620 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
621 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
622 void LineLineGeometricIntersection(const gp_Lin2d& L1
623                                    ,const gp_Lin2d& L2
624                                    ,const Standard_Real Tol
625                                    ,Standard_Real& U1
626                                    ,Standard_Real& U2
627                                    ,Standard_Real& SinDemiAngle
628                                    ,Standard_Integer& nbsol) {
629   
630   Standard_Real U1x=L1.Direction().X();
631   Standard_Real U1y=L1.Direction().Y();
632   Standard_Real U2x=L2.Direction().X();
633   Standard_Real U2y=L2.Direction().Y();
634   Standard_Real Uo21x = L2.Location().X() - L1.Location().X();
635   Standard_Real Uo21y = L2.Location().Y() - L1.Location().Y();
636   
637   Standard_Real D=U1y*U2x-U1x*U2y;
638
639 //modified by NIZHNY-MKK  Tue Feb 15 10:54:04 2000.BEGIN
640 //   if(Abs(D)<1e-15) { //-- Droites //
641   if(Abs(D) < TOLERANCE_ANGULAIRE) {
642 //modified by NIZHNY-MKK  Tue Feb 15 10:54:11 2000.END
643     D=U1y*Uo21x - U1x*Uo21y;
644     nbsol=(Abs(D)<=Tol)? 2 : 0;
645   }
646   else {
647     U1=(Uo21y * U2x - Uo21x * U2y)/D;
648     U2=(Uo21y * U1x - Uo21x * U1y)/D;
649     
650     //------------------- Calcul du Sin du demi angle  entre L1 et L2
651     //---- 
652     if(D<0.0) D=-D;
653     if(D>1.0) D=1.0;                      //-- Deja vu !
654     SinDemiAngle=Sin(0.5*ASin(D));
655     nbsol=1;
656   }
657 }
658 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
659 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
660 /*IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Lin2d& L1
661                                                ,const IntRes2d_Domain& D1
662                                                ,const gp_Lin2d& L2
663                                                ,const IntRes2d_Domain& D2
664                                                ,const Standard_Real TolConf
665                                                ,const Standard_Real Tol)  {
666   Perform(L1,D1,L2,D2,TolConf,Tol);
667 }
668
669
670 IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Lin2d& L1
671                                                ,const IntRes2d_Domain& D1
672                                                ,const gp_Circ2d& C2
673                                                ,const IntRes2d_Domain& D2
674                                                ,const Standard_Real TolConf
675                                                ,const Standard_Real Tol) {
676   
677   Perform(L1,D1,C2,D2,TolConf,Tol);
678 }
679
680
681 IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Circ2d& C1
682                                               ,const IntRes2d_Domain& D1
683                                               ,const gp_Circ2d& C2
684                                               ,const IntRes2d_Domain& D2
685                                               ,const Standard_Real TolConf
686                                               ,const Standard_Real Tol) {
687   SetReversedParameters(Standard_False);
688   Perform(C1,D1,C2,D2,TolConf,Tol);
689 }*/ //amv OCC12547
690 //----------------------------------------------------------------------
691 void IntCurve_IntConicConic::Perform(const gp_Circ2d& Circle1
692                                 ,const IntRes2d_Domain& DomainCirc1
693                                 ,const gp_Circ2d& _Circle2
694                                 ,const IntRes2d_Domain& _DomainCirc2
695                                 ,const Standard_Real TolConf,const Standard_Real Tol) {
696
697
698 //-- TRES TRES MAL FAIT    A REPRENDRE UN JOUR ....   (lbr Octobre 98) 
699   gp_Circ2d Circle2=_Circle2;
700   IntRes2d_Domain  DomainCirc2=_DomainCirc2;
701   Standard_Boolean IndirectCircles=Standard_False;
702   if(Circle1.IsDirect() != _Circle2.IsDirect()) { 
703     IndirectCircles=Standard_True;
704     Circle2=_Circle2.Reversed();
705     DomainCirc2.SetValues(_DomainCirc2.LastPoint(),
706                           PIpPI-_DomainCirc2.LastParameter(),
707                           _DomainCirc2.LastTolerance(),
708                           _DomainCirc2.FirstPoint(),
709                           PIpPI-_DomainCirc2.FirstParameter(),
710                           _DomainCirc2.FirstTolerance());
711     DomainCirc2.SetEquivalentParameters(0.0,PIpPI);
712   }
713   
714   this->ResetFields();
715   Standard_Integer nbsol=0;
716   PeriodicInterval C1_Int1,C1_Int2;
717
718   //------- Intersection sans tenir compte du domaine  ----> nbsol=0,1,2,3 
719   CircleCircleGeometricIntersection(Circle1,Circle2,TolConf,Tol,C1_Int1,C1_Int2,nbsol);
720   done=Standard_True;
721
722   if(nbsol==0) { //-- Pas de solutions 
723     return;
724   }
725
726   PeriodicInterval C1Domain(DomainCirc1); 
727   //-- On se ramene entre 0 et 2PI
728   Standard_Real deltat = C1Domain.Bsup-C1Domain.Binf;
729   if(deltat>=PIpPI) { deltat=PIpPI-1e-14; } 
730   
731   while(C1Domain.Binf >= PIpPI) C1Domain.Binf-=PIpPI;
732   while(C1Domain.Binf <  0.0)   C1Domain.Binf+=PIpPI;
733   C1Domain.Bsup=C1Domain.Binf+deltat;
734
735   PeriodicInterval C2Domain(DomainCirc2); 
736   deltat = C2Domain.Bsup-C2Domain.Binf;
737   if(deltat>=PIpPI) { deltat=PIpPI-1e-14; } 
738
739   while(C2Domain.Binf >= PIpPI) C2Domain.Binf-=PIpPI;
740   while(C2Domain.Binf <  0.0)   C2Domain.Binf+=PIpPI;
741   C2Domain.Bsup=C2Domain.Binf+deltat;
742
743   Standard_Boolean IdentCircles=Standard_False;
744
745   if(nbsol>2) {       
746     //-- Les 2 cercles sont confondus a Tol pres
747     C1_Int1.SetValues(0,PIpPI);
748     C1_Int2.SetNull(); 
749     //---------------------------------------------------------------
750     //-- Flag utilise pour specifier que les intervalles manipules
751     //--   peuvent etre de longueur superieure a pi. 
752     //-- Pour des cercles non identiques, on a necessairement cette
753     //--   condition sur les resultats de l intersection geometrique
754     //--   ce qui permet de normaliser rapidement les intervalles.
755     //--   ex: -1 4 -> longueur > PI  
756     //--        donc -1 4 devient  4 , 2*pi-1
757     //---------------------------------------------------------------
758     IdentCircles=Standard_True;
759   }
760
761   Standard_Integer NbSolTotal=0;
762   PeriodicInterval SolutionC1[4];
763   PeriodicInterval SolutionC2[4];
764   
765   //----------------------------------------------------------------------
766   //----------- Traitement du premier intervalle Geometrique  C1_Int1 ----
767   //----------------------------------------------------------------------
768   //-- NbSolTotal est incremente a chaque Intervalle solution.
769   //-- On stocke les intervalles dans les tableaux : SolutionC1(C2)
770   //-- Dimensionnes a 4 elements.
771   //-- des Exemples faciles donnent 3 Intersections
772   //-- des Problemes numeriques peuvent en donner 4 ??????
773   //--
774   PeriodicInterval C1DomainAndRes=C1Domain.FirstIntersection(C1_Int1);
775   
776   ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
777                                       ,C1DomainAndRes
778                                       ,C2Domain
779                                       ,SolutionC1,SolutionC2
780                                       ,NbSolTotal
781                                       ,IdentCircles);
782   //----------------------------------------------------------------------
783   //-- Seconde Intersection :  Par exemple :     2*PI-1  2*PI+1
784   //--                         Intersecte avec     0.5   2*PI-0.5
785   //--     Donne les intervalles : 0.5,1    et  2*PI-1,2*PI-0.5
786   //--
787   C1DomainAndRes=C1Domain.SecondIntersection(C1_Int1);
788   
789   ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
790                                       ,C1DomainAndRes
791                                       ,C2Domain
792                                       ,SolutionC1,SolutionC2
793                                       ,NbSolTotal
794                                       ,IdentCircles);
795
796   //----------------------------------------------------------------------
797   //----------- Traitement du second intervalle Geometrique   C1_Int2 ----
798   //----------------------------------------------------------------------
799   if(nbsol==2) {
800     C1DomainAndRes=C1Domain.FirstIntersection(C1_Int2);
801     
802     ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
803                                         ,C1DomainAndRes
804                                         ,C2Domain
805                                         ,SolutionC1,SolutionC2
806                                         ,NbSolTotal
807                                         ,IdentCircles);
808     //--------------------------------------------------------------------
809     C1DomainAndRes=C1Domain.SecondIntersection(C1_Int2);
810     
811     ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
812                                         ,C1DomainAndRes
813                                         ,C2Domain
814                                         ,SolutionC1,SolutionC2
815                                         ,NbSolTotal
816                                         ,IdentCircles);
817   }
818   //----------------------------------------------------------------------
819   //-- Calcul de toutes les transitions et Positions.
820   //--
821   //----------------------------------------------------------------------
822   //-- On determine si des intervalles sont reduit a des points 
823   //--      ( Rayon * Intervalle.Length()    <    Tol   )
824   //--
825   Standard_Real R1=Circle1.Radius();
826   Standard_Real R2=Circle2.Radius();
827   Standard_Real Tol2=Tol+Tol;     //---- Pour eviter de toujours retourner
828                                   //des segments
829   Standard_Integer i ;
830   if(Tol < (1e-10)) Tol2 = 1e-10; 
831   for( i=0; i<NbSolTotal ; i++) { 
832     if(((R1 * SolutionC1[i].Length()))<=Tol2 
833        && ((R2 * SolutionC2[i].Length()))<=Tol2) {
834       
835       Standard_Real t=(SolutionC1[i].Binf+SolutionC1[i].Bsup)*0.5;
836       SolutionC1[i].Binf=SolutionC1[i].Bsup=t;
837       
838       t=(SolutionC2[i].Binf+SolutionC2[i].Bsup)*0.5;
839       SolutionC2[i].Binf=SolutionC2[i].Bsup=t;
840     }
841   }
842
843   //----------------------------------------------------------------------
844   //-- Traitement des intervalles (ou des points obtenus)
845   //-- 
846   gp_Ax22d Axis2C1=Circle1.Axis();
847   gp_Ax22d Axis2C2=Circle2.Axis();
848   gp_Pnt2d P1a,P1b,P2a,P2b;
849   gp_Vec2d Tan1,Tan2,Norm1,Norm2;
850   IntRes2d_Transition T1a,T1b,T2a,T2b;
851   IntRes2d_Position Pos1a,Pos1b,Pos2a,Pos2b;
852
853   Standard_Boolean Opposite=((Circle1.Location().SquareDistance(Circle2.Location()))
854                    >(R1*R1+R2*R2))? Standard_True : Standard_False;
855
856   //if(Circle1.IsDirect()) { cout<<" C1 Direct"<<endl; } else { cout<<" C1 INDirect"<<endl; }
857   //if(Circle2.IsDirect()) { cout<<" C2 Direct"<<endl; } else { cout<<" C2 INDirect"<<endl; }
858
859   for(i=0; i<NbSolTotal; i++) {
860     Standard_Real C2inf=(Opposite)? SolutionC2[i].Bsup : SolutionC2[i].Binf;
861     Standard_Real C2sup=(Opposite)? SolutionC2[i].Binf : SolutionC2[i].Bsup;
862
863     Standard_Real C1inf=NormalizeOnCircleDomain(SolutionC1[i].Binf,DomainCirc1);
864     C2inf=NormalizeOnCircleDomain(C2inf,DomainCirc2);
865
866     if(IndirectCircles) { 
867       
868       ElCLib::CircleD2(C1inf,Axis2C1,R1,P1a,Tan1,Norm1); 
869       ElCLib::CircleD2(C2inf,Axis2C2,R2,P2a,Tan2,Norm2);
870       Tan2.Reverse();
871       
872       IntImpParGen::DeterminePosition(Pos1a,DomainCirc1,P1a,C1inf);
873       IntImpParGen::DeterminePosition(Pos2a,_DomainCirc2,P2a,PIpPI-C2inf);
874       Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
875       
876       
877       IntRes2d_IntersectionPoint NewPoint1(P1a,C1inf,PIpPI-C2inf,T1a,T2a,Standard_False);
878       
879       if((SolutionC1[i].Length()>0.0 ) || (SolutionC2[i].Length() >0.0)) {
880         //-- On traite un intervalle non reduit a un point
881         Standard_Real C1sup=NormalizeOnCircleDomain(SolutionC1[i].Bsup,DomainCirc1);
882         if(C1sup<C1inf) C1sup+=PIpPI;
883         C2sup=NormalizeOnCircleDomain(C2sup,DomainCirc2);
884         
885         ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1); 
886         ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
887         Tan2.Reverse();
888
889         IntImpParGen::DeterminePosition(Pos1b,DomainCirc1,P1b,C1sup);
890         IntImpParGen::DeterminePosition(Pos2b,_DomainCirc2,P2b,PIpPI-C2sup);
891         Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
892         
893         //--------------------------------------------------
894         
895         if(Opposite) {
896           if(nbsol!=3) { 
897             if(C2inf<C2sup) C2inf+=PIpPI;
898           }
899         }
900         else {
901           if(nbsol!=3) { 
902             if(C2sup<C2inf) C2sup+=PIpPI;
903           }
904         }
905         
906         IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,PIpPI-C2sup,T1b,T2b,Standard_False);
907         IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2,
908                                             (Opposite==Standard_True)? Standard_False : Standard_True,
909                                             Standard_False);
910         Append(NewSeg);
911         
912       }
913       else {
914         Append(NewPoint1);
915       }
916       
917     }
918     else { 
919       
920       ElCLib::CircleD2(C1inf,Axis2C1,R1,P1a,Tan1,Norm1); 
921       ElCLib::CircleD2(C2inf,Axis2C2,R2,P2a,Tan2,Norm2);
922       
923       IntImpParGen::DeterminePosition(Pos1a,DomainCirc1,P1a,C1inf);
924       IntImpParGen::DeterminePosition(Pos2a,DomainCirc2,P2a,C2inf);
925       Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
926       
927       
928       IntRes2d_IntersectionPoint NewPoint1(P1a,C1inf,C2inf,T1a,T2a,Standard_False);
929       
930       if((SolutionC1[i].Length()>0.0 ) || (SolutionC2[i].Length() >0.0)) {
931         //-- On traite un intervalle non reduit a un point
932         Standard_Real C1sup=NormalizeOnCircleDomain(SolutionC1[i].Bsup,DomainCirc1);
933         if(C1sup<C1inf) C1sup+=PIpPI;
934         C2sup=NormalizeOnCircleDomain(C2sup,DomainCirc2);
935         
936         ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1); 
937         ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
938         
939         IntImpParGen::DeterminePosition(Pos1b,DomainCirc1,P1b,C1sup);
940         IntImpParGen::DeterminePosition(Pos2b,DomainCirc2,P2b,C2sup);
941         Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
942         
943         //--------------------------------------------------
944         
945         if(Opposite) {
946           if(nbsol!=3) { 
947             if(C2inf<C2sup) C2inf+=PIpPI;
948           }
949         }
950         else {
951           if(nbsol!=3) { 
952             if(C2sup<C2inf) C2sup+=PIpPI;
953           }
954         }
955         
956         IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,C2sup,T1b,T2b,Standard_False);
957         IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2,Opposite,Standard_False);
958         Append(NewSeg);
959         
960       }
961       else {
962         Append(NewPoint1);
963       }
964     }
965   }
966 }
967 //----------------------------------------------------------------------
968 IntRes2d_Position FindPositionLL(Standard_Real &Param
969                                  ,const IntRes2d_Domain& Domain) 
970 {
971   Standard_Real aDPar = Precision::Infinite();
972   IntRes2d_Position aPos = IntRes2d_Middle; 
973   Standard_Real aResPar = Param;
974   if(Domain.HasFirstPoint()) {
975     aDPar = Abs(Param-Domain.FirstParameter());
976     if( aDPar <= Domain.FirstTolerance()) {
977       aResPar=Domain.FirstParameter();
978       aPos = IntRes2d_Head;
979      
980     }
981   }
982   if(Domain.HasLastPoint()) {
983     Standard_Real aD2 = Abs(Param-Domain.LastParameter());
984     if( aD2 <= Domain.LastTolerance() && (aPos == IntRes2d_Middle || aD2 < aDPar )) 
985     {
986       aResPar=Domain.LastParameter();
987       aPos = IntRes2d_End;
988     }
989   }
990   Param = aResPar;
991   return aPos;
992 }
993 //--------------------------------------------------------------------
994 //gka 0022833
995 // Method to compute of point of intersection for case
996 //when specified domain less than specified tolerance for intersection
997 static inline void getDomainParametrs(const IntRes2d_Domain& theDomain,
998                                       Standard_Real& theFirst,
999                                       Standard_Real& theLast,
1000                                       Standard_Real& theTol1,
1001                                       Standard_Real& theTol2)
1002 {
1003   theFirst = (theDomain.HasFirstPoint() ? theDomain.FirstParameter() : -Precision::Infinite());
1004   theLast = (theDomain.HasLastPoint() ? theDomain.LastParameter() : Precision::Infinite()); 
1005   theTol1 = (theDomain.HasFirstPoint() ? theDomain.FirstTolerance() : 0.);
1006   theTol2 = (theDomain.HasLastPoint() ? theDomain.LastTolerance() : 0.);
1007 }
1008
1009
1010 static Standard_Boolean computeIntPoint(const IntRes2d_Domain& theCurDomain,
1011                                                          const IntRes2d_Domain& theDomainOther,
1012                                                          const gp_Lin2d& theCurLin,
1013                                                          const gp_Lin2d& theOtherLin,   
1014                                                          Standard_Real theCosT1T2,
1015                                                          Standard_Real theParCur, Standard_Real theParOther,
1016                                                          Standard_Real& theResInf, Standard_Real& theResSup,
1017                                                          Standard_Integer theNum,
1018                                                          IntRes2d_TypeTrans theCurTrans,    
1019                                                          IntRes2d_IntersectionPoint& theNewPoint)
1020 {
1021   if(fabs(theResSup-theParCur) > fabs(theResInf-theParCur))
1022     theResSup = theResInf;
1023
1024   Standard_Real aRes2 = theParOther + (theResSup - theParCur) * theCosT1T2;
1025
1026   Standard_Real aFirst2, aLast2, aTol1, aTol2;
1027   getDomainParametrs(theDomainOther,aFirst2, aLast2, aTol1, aTol2);
1028   if( aRes2  < aFirst2 - aTol1 || aRes2  > aLast2 + aTol2 ) 
1029           return Standard_False;
1030         
1031   //------ compute parameters of intersection point --
1032   IntRes2d_Transition aT1,aT2;
1033   IntRes2d_Position aPos1a = FindPositionLL(theResSup,theCurDomain);
1034   IntRes2d_Position aPos2a = FindPositionLL(aRes2,theDomainOther);
1035   IntRes2d_TypeTrans anOtherTrans = ( theCurTrans == IntRes2d_Out ? 
1036       IntRes2d_In : ( theCurTrans == IntRes2d_In ? IntRes2d_Out : IntRes2d_Undecided ) );
1037
1038   if( theCurTrans != IntRes2d_Undecided )
1039   {
1040     aT1.SetValue(Standard_False, aPos1a, theCurTrans);
1041     aT2.SetValue(Standard_False,  aPos2a, anOtherTrans);
1042   }
1043   else  
1044   { 
1045     Standard_Boolean anOpposite = theCosT1T2 < 0.;
1046     aT1.SetValue(Standard_False,aPos1a,IntRes2d_Unknown,anOpposite);
1047     aT2.SetValue(Standard_False,aPos2a,IntRes2d_Unknown,anOpposite);
1048   }
1049   //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1050   //--------------------------------------------------
1051   //gka bug 0022833 
1052   Standard_Real aResU1 = theParCur;
1053   Standard_Real aResU2 = theParOther;
1054
1055   Standard_Real aFirst1, aLast1;
1056   getDomainParametrs(theCurDomain,aFirst1, aLast1, aTol1, aTol2);
1057   
1058   Standard_Boolean isInside1 = (theParCur >= aFirst1 && theParCur <= aLast1);
1059   Standard_Boolean isInside2 = (theParOther >= aFirst2 && theParOther <= aLast2);
1060
1061   if(!isInside1 || !isInside2)
1062   {
1063     if(isInside1) 
1064     {
1065       gp_Pnt2d Pt1=ElCLib::Value(aRes2,theOtherLin);
1066       aResU2 = aRes2;
1067       Standard_Real aPar1 = ElCLib::Parameter(theCurLin,Pt1);
1068       aResU1 =((aPar1 >= aFirst1 && aPar1<= aLast1) ?  aPar1 : theResSup);
1069       
1070     }
1071     else if(isInside2)
1072     {
1073       gp_Pnt2d aPt1=ElCLib::Value(theResSup,theCurLin);
1074       aResU1 = theResSup;
1075       Standard_Real aPar2 = ElCLib::Parameter(theOtherLin,aPt1);
1076       aResU2= ((aPar2 >= aFirst2 && aPar2<= aLast2) ? aPar2 : aRes2);
1077     }
1078     else 
1079     {
1080       aResU1 = theResSup;
1081       aResU2= aRes2;
1082     }
1083   }
1084   gp_Pnt2d aPres((ElCLib::Value(aResU1,theCurLin).XY() + ElCLib::Value(aResU2,theOtherLin).XY()) * 0.5 );
1085   if(theNum == 1 )
1086     theNewPoint.SetValues(aPres, aResU1, aResU2 ,aT1, aT2, Standard_False);
1087   else
1088     theNewPoint.SetValues(aPres, aResU2, aResU1 ,aT2, aT1, Standard_False);
1089   return Standard_True;
1090 }
1091
1092 //----------------------------------------------------------------------
1093 void IntCurve_IntConicConic::Perform(const gp_Lin2d& L1
1094                                       ,const IntRes2d_Domain& Domain1
1095                                      ,const gp_Lin2d& L2
1096                                      ,const IntRes2d_Domain& Domain2
1097                                      ,const Standard_Real,const Standard_Real TolR) {  
1098   this->ResetFields();
1099
1100   //-- Coordonnees du point d intersection sur chacune des 2 droites
1101   Standard_Real U1,U2; 
1102   //-- Nombre de points solution : 1 : Intersection
1103   //--                             0 : Non Confondues
1104   //--                             2 : Confondues a la tolerance pres
1105   Standard_Integer nbsol;
1106   IntRes2d_IntersectionPoint PtSeg1,PtSeg2;
1107   Standard_Real SINL1L2;
1108   Standard_Real Tol = TolR;
1109   if(TolR< 1e-10) Tol = 1e-10;
1110   
1111
1112   LineLineGeometricIntersection(L1,L2,Tol,U1,U2,SINL1L2,nbsol);
1113
1114   gp_Vec2d Tan1=L1.Direction();
1115   gp_Vec2d Tan2=L2.Direction();
1116  
1117   Standard_Real aCosT1T2 = Tan1.Dot(Tan2);
1118   Standard_Boolean Opposite=(aCosT1T2 < 0.0)? Standard_True : Standard_False;
1119
1120   done=Standard_True;
1121
1122   if(nbsol==1) {
1123     //---------------------------------------------------
1124     //-- d: distance du point I a partir de laquelle  les 
1125     //--  points de parametre U1+d et U2+-d sont ecartes
1126     //--  d une distance superieure a Tol.
1127     //---------------------------------------------------
1128     IntRes2d_Position Pos1a,Pos2a,Pos1b,Pos2b;
1129     Standard_Real d=Tol/(SINL1L2);
1130     Standard_Real U1inf=U1-d;
1131     Standard_Real U1sup=U1+d;
1132     Standard_Real U1mU2=U1-U2;
1133     Standard_Real U1pU2=U1+U2;
1134     Standard_Real Res1inf,Res1sup;
1135     Standard_Real ProdVectTan;
1136     
1137
1138     //---------------------------------------------------
1139     //-- On agrandit la zone U1inf U1sup pour tenir compte 
1140     //-- des tolerances des points en bout
1141     //--
1142     if(Domain1.HasFirstPoint()) { 
1143       if(L2.Distance(Domain1.FirstPoint()) < Domain1.FirstTolerance()) { 
1144         if(U1inf > Domain1.FirstParameter()) { 
1145           U1inf = Domain1.FirstParameter();
1146         }
1147         if(U1sup < Domain1.FirstParameter()) { 
1148           U1sup = Domain1.FirstParameter();
1149         }
1150       }
1151     }
1152     if(Domain1.HasLastPoint()) { 
1153       if(L2.Distance(Domain1.LastPoint()) < Domain1.LastTolerance()) { 
1154         if(U1inf > Domain1.LastParameter()) { 
1155           U1inf = Domain1.LastParameter();
1156         }
1157         if(U1sup < Domain1.LastParameter()) { 
1158           U1sup = Domain1.LastParameter();
1159         }
1160       }
1161     }      
1162     if(Domain2.HasFirstPoint()) { 
1163       if(L1.Distance(Domain2.FirstPoint()) < Domain2.FirstTolerance()) { 
1164         Standard_Real p = ElCLib::Parameter(L1,Domain2.FirstPoint());
1165         if(U1inf > p) { 
1166           U1inf = p;
1167         }
1168         if(U1sup < p) { 
1169           U1sup = p;
1170         }
1171       }
1172     }
1173     if(Domain2.HasLastPoint()) { 
1174       if(L1.Distance(Domain2.LastPoint()) < Domain2.LastTolerance()) { 
1175         Standard_Real p = ElCLib::Parameter(L1,Domain2.LastPoint());
1176         if(U1inf > p) { 
1177           U1inf = p;
1178         }
1179         if(U1sup < p) { 
1180           U1sup = p;
1181         }
1182       }
1183     }
1184     //-----------------------------------------------------------------
1185
1186     DomainIntersection(Domain1,U1inf,U1sup,Res1inf,Res1sup,Pos1a,Pos1b);
1187     
1188     if((Res1sup-Res1inf)<0.0) {
1189       //-- Si l intersection est vide       
1190       //-- 
1191     }
1192     else { //-- (Domain1  INTER   Zone Intersection)    non vide
1193
1194       ProdVectTan=Tan1.Crossed(Tan2);
1195       
1196       //#####################################################################
1197       //##  Longueur Minimale d un segment    Sur Courbe 1 
1198       //##################################################################### 
1199
1200       Standard_Real LongMiniSeg=Tol;
1201
1202
1203       if(((Res1sup-Res1inf)<=LongMiniSeg)
1204         || ((Pos1a==Pos1b)&&(Pos1a!=IntRes2d_Middle)))     
1205       {
1206         //-------------------------------  Un seul Point -------------------
1207         //--- lorsque la longueur du segment est inferieure a ??
1208         //--- ou si deux points designent le meme bout
1209         //gka #0022833
1210         IntRes2d_TypeTrans aCurTrans = ( ProdVectTan >= TOLERANCE_ANGULAIRE ? 
1211              IntRes2d_Out : ( ProdVectTan <= -TOLERANCE_ANGULAIRE ? IntRes2d_In : IntRes2d_Undecided ) );
1212
1213         IntRes2d_IntersectionPoint NewPoint1;
1214         if( computeIntPoint(Domain1, Domain2, L1, L2, aCosT1T2, U1, U2, Res1inf, Res1sup, 1, aCurTrans, NewPoint1 ) )
1215           Append(NewPoint1);
1216
1217         //------------------------------------------------------
1218       
1219     
1220     }  //---------------   Fin du cas  :   1 seul point --------------------
1221       
1222       else {
1223         //-- Intersection AND Domain1  --------> Segment ---------------------
1224         Standard_Real U2inf,U2sup;
1225         Standard_Real Res2inf,Res2sup;
1226         
1227         if(Opposite) { U2inf = U1pU2 -Res1sup;  U2sup= U1pU2-Res1inf;  }
1228         else         { U2inf = Res1inf-U1mU2;   U2sup= Res1sup-U1mU2;  }
1229         
1230         DomainIntersection(Domain2,U2inf,U2sup,Res2inf,Res2sup,Pos2a,Pos2b);
1231
1232         //####################################################################
1233         //##  Test sur la longueur minimale d un segment sur Ligne2
1234         //####################################################################
1235         Standard_Real Res2sup_m_Res2inf = Res2sup-Res2inf;
1236         if(Res2sup_m_Res2inf < 0.0) {
1237           //-- Pas de solutions On retourne Vide
1238         }
1239         else if(((Res2sup-Res2inf) > LongMiniSeg)  
1240                 || ((Pos2a==Pos2b)&&(Pos2a!=IntRes2d_Middle)))     {
1241           //----------- Calcul des attributs du segment --------------
1242           //-- Attention, les bornes Res1inf(sup) bougent donc il faut
1243           //--  eventuellement recalculer les attributs
1244           
1245           if(Opposite) { Res1inf=U1pU2-Res2sup; Res1sup=U1pU2-Res2inf; 
1246                          Standard_Real Tampon=Res2inf; Res2inf=Res2sup; Res2sup=Tampon;
1247                          IntRes2d_Position Pos=Pos2a; Pos2a=Pos2b; Pos2b=Pos;
1248                        }
1249           else         { Res1inf=U1mU2+Res2inf; Res1sup=U1mU2+Res2sup; }
1250           
1251           Pos1a=FindPositionLL(Res1inf,Domain1);
1252           Pos1b=FindPositionLL(Res1sup,Domain1);          
1253           
1254           IntRes2d_Transition T1a,T2a,T1b,T2b;
1255           
1256           if(ProdVectTan>=TOLERANCE_ANGULAIRE) {  // &&&&&&&&&&&&&&&
1257             T1a.SetValue(Standard_False,Pos1a,IntRes2d_Out);      
1258             T2a.SetValue(Standard_False,Pos2a,IntRes2d_In);
1259           }
1260           else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1261             T1a.SetValue(Standard_False,Pos1a,IntRes2d_In);      
1262             T2a.SetValue(Standard_False,Pos2a,IntRes2d_Out);
1263           }
1264           else {
1265             T1a.SetValue(Standard_False,Pos1a,IntRes2d_Unknown,Opposite);
1266             T2a.SetValue(Standard_False,Pos2a,IntRes2d_Unknown,Opposite);
1267           }
1268           
1269
1270           //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1271           //~~~~~~~  C O N V E N T I O N    -    S E G M E N T     ~~~~~~~
1272           //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1273           //~~ On Renvoie un segment dans les cas suivants :            ~~
1274           //~~   (1) Extremite L1 L2   ------>    Extremite L1 L2       ~~
1275           //~~   (2) Extremite L1 L2   ------>    Intersection          ~~
1276           //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1277           
1278           Standard_Boolean ResultIsAPoint=Standard_False;
1279
1280           if(((Res1sup-Res1inf)<=LongMiniSeg) 
1281              || (Abs(Res2sup-Res2inf)<=LongMiniSeg)) {
1282             //-- On force la creation d un point
1283             ResultIsAPoint=Standard_True;
1284           }
1285           else {
1286             //------------------------------------------------------------
1287             //-- On traite les cas ou l intersection est situee du 
1288             //-- Mauvais cote du domaine 
1289             //-- Attention : Res2inf <-> Pos2a        Res2sup <-> Pos2b
1290             //--  et         Res1inf <-> Pos1a        Res1sup <-> Pos1b
1291             //--             avec Res1inf <= Res1sup
1292             //------------------------------------------------------------
1293             //-- Le point sera : Res1inf,Res2inf,T1a(Pos1a),T2a(Pos2a)
1294             //------------------------------------------------------------
1295
1296             if(Pos1a==IntRes2d_Head) { 
1297               if(Pos1b!=IntRes2d_End && U1<Res1inf)    { ResultIsAPoint=Standard_True; U1=Res1inf; U2=Res2inf; }
1298             }
1299             if(Pos1b==IntRes2d_End)  { 
1300               if(Pos1a!=IntRes2d_Head && U1>Res1sup)   { ResultIsAPoint=Standard_True; U1=Res1sup; U2=Res2sup; }
1301             }
1302         
1303             if(Pos2a==IntRes2d_Head) { 
1304               if(Pos2b!=IntRes2d_End && U2<Res2inf)    { ResultIsAPoint=Standard_True; U2=Res2inf; U1=Res1inf; }
1305             }
1306             else {
1307               if(Pos2a==IntRes2d_End)  { 
1308                 if(Pos2b!=IntRes2d_Head && U2>Res2inf) { ResultIsAPoint=Standard_True; U2=Res2inf; U1=Res1inf; }
1309               }
1310             }
1311             if(Pos2b==IntRes2d_Head) { 
1312               if(Pos2a!=IntRes2d_End && U2<Res2sup)    { ResultIsAPoint=Standard_True; U2=Res2sup; U1=Res1sup; }
1313             }
1314             else {
1315               if(Pos2b==IntRes2d_End) {
1316                 if(Pos2a!=IntRes2d_Head && U2>Res2sup) { ResultIsAPoint=Standard_True; U2=Res2sup; U1=Res1sup; }
1317               }
1318             }
1319           }
1320             
1321           
1322
1323           if((!ResultIsAPoint) && (Pos1a!=IntRes2d_Middle || Pos2a!=IntRes2d_Middle)) {
1324             IntRes2d_Transition T1b,T2b;
1325             if(ProdVectTan>=TOLERANCE_ANGULAIRE) { //&&&&&&&&&&&&&&
1326               T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1327               T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1328             }
1329             else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) { //&&&&&&&&&&&&&&
1330               T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1331               T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1332             }
1333             else {
1334               T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1335               T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1336             }
1337             gp_Pnt2d Ptdebut;
1338             if(Pos1a==IntRes2d_Middle) { 
1339               Standard_Real t3;
1340               if(Opposite) {
1341                 t3 = (Pos2a == IntRes2d_Head)? Res2sup : Res2inf;
1342               }
1343               else {
1344                 t3 = (Pos2a == IntRes2d_Head)? Res2inf : Res2sup;
1345               }
1346               Ptdebut=ElCLib::Value(t3,L2);
1347               Res1inf=ElCLib::Parameter(L1,Ptdebut);
1348             }
1349             else {
1350               Standard_Real t4 = (Pos1a == IntRes2d_Head)? Res1inf : Res1sup;
1351               Ptdebut=ElCLib::Value(t4,L1);
1352               Res2inf=ElCLib::Parameter(L2,Ptdebut);
1353             }
1354             PtSeg1.SetValues(Ptdebut,Res1inf,Res2inf,T1a,T2a,Standard_False);
1355             if(Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle) {
1356               //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1357               //~~ Ajustement des parametres et du point renvoye
1358               gp_Pnt2d Ptfin;
1359               if(Pos1b==IntRes2d_Middle) { 
1360                 Ptfin=ElCLib::Value(Res2sup,L2);
1361                 Res1sup=ElCLib::Parameter(L1,Ptfin);
1362               }
1363               else {
1364                 Ptfin=ElCLib::Value(Res1sup,L1);
1365                 Res2sup=ElCLib::Parameter(L2,Ptfin);
1366               }
1367               PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1368               IntRes2d_IntersectionSegment Segment(PtSeg1,PtSeg2
1369                                                    ,Opposite,Standard_False);
1370               Append(Segment);  
1371             } 
1372             else { //-- Extremite(L1 ou L2)  ------>   Point Middle(L1 et L2)
1373
1374               Pos1b=FindPositionLL(U1,Domain1);
1375               Pos2b=FindPositionLL(U2,Domain2);         
1376               if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1377                 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1378                 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1379               }
1380               else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1381                 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1382                 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1383               }
1384               else {
1385                 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1386                 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1387               }
1388               
1389               PtSeg2.SetValues(ElCLib::Value(U2,L2),U1,U2,T1b,T2b,Standard_False);
1390
1391               if((Abs(Res1inf-U1) >LongMiniSeg) && (Abs(Res2inf-U2) >LongMiniSeg)) {
1392                 IntRes2d_IntersectionSegment Segment(PtSeg1,PtSeg2,Opposite,Standard_False);
1393                 Append(Segment);  
1394               }
1395               else {
1396                 Append(SegmentToPoint(PtSeg1,T1a,T2a,PtSeg2,T1b,T2b));
1397               }
1398             }
1399
1400           } //-- (Pos1a!=IntRes2d_Middle || Pos2a!=IntRes2d_Middle) --
1401           else {  //-- Pos1a == Pos2a == Middle
1402             if(Pos1b==IntRes2d_Middle) Pos1b=Pos1a;
1403             if(Pos2b==IntRes2d_Middle) Pos2b=Pos2a;
1404             if(ResultIsAPoint) {
1405               //-- Middle sur le segment A 
1406               //-- 
1407               if(Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle) {
1408                 gp_Pnt2d Ptfin;
1409                 if(Pos1b==IntRes2d_Middle) {
1410                   Standard_Real t2;
1411                   if(Opposite) { 
1412                     t2 = (Pos2b == IntRes2d_Head)? Res2sup : Res2inf;
1413                   }
1414                   else {
1415                     t2 = (Pos2b == IntRes2d_Head)? Res2inf : Res2sup;
1416                   }
1417                   Ptfin=ElCLib::Value(t2,L2);
1418                   Res1sup=ElCLib::Parameter(L1,Ptfin);
1419 //modified by NIZHNY-MKK  Tue Feb 15 10:54:51 2000.BEGIN
1420                   Pos1b=FindPositionLL(Res1sup,Domain1);
1421 //modified by NIZHNY-MKK  Tue Feb 15 10:54:55 2000.END
1422
1423                 }
1424                 else {
1425                   Standard_Real t1 = (Pos1b == IntRes2d_Head)? Res1inf : Res1sup;
1426                   Ptfin=ElCLib::Value(t1,L1);
1427                   Res2sup=ElCLib::Parameter(L2,Ptfin);
1428 //modified by NIZHNY-MKK  Tue Feb 15 10:55:08 2000.BEGIN
1429                   Pos2b=FindPositionLL(Res2sup,Domain2);
1430 //modified by NIZHNY-MKK  Tue Feb 15 10:55:11 2000.END
1431                 }
1432                 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1433                   T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1434                   T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1435                 }
1436                 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1437                   T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1438                   T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1439                 }
1440                 else {
1441                   T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1442                   T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1443                 }
1444                 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1445                 Append(PtSeg2);
1446               }
1447               else {
1448                 Pos1b=FindPositionLL(U1,Domain1);
1449                 Pos2b=FindPositionLL(U2,Domain2);               
1450                 
1451                 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1452                   T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1453                   T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1454                 }
1455                 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1456                   T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1457                   T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1458                 }
1459                 else {
1460                   T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1461                   T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1462                 }
1463                 PtSeg1.SetValues(ElCLib::Value(U2,L2),U1,U2,T1b,T2b,Standard_False);
1464                 Append(PtSeg1); 
1465               }
1466             }
1467             else {
1468               PtSeg1.SetValues(ElCLib::Value(U2,L2),U1,U2,T1a,T2a,Standard_False);
1469               
1470               if((Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle)) {
1471                 IntRes2d_Transition T1b,T2b;
1472                 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1473                   T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1474                   T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1475                 }
1476                 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1477                   T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1478                   T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1479                 }
1480                 else {
1481                   T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1482                   T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1483                 }
1484                 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1485                 //~~ Ajustement des parametres et du point renvoye
1486                 gp_Pnt2d Ptfin;             
1487                 if(Pos1b==IntRes2d_Middle) {
1488                   Ptfin=ElCLib::Value(Res2sup,L2);
1489                   Res1sup=ElCLib::Parameter(L1,Ptfin);
1490                 }
1491                 else {
1492                   Ptfin=ElCLib::Value(Res1sup,L1);
1493                   Res2sup=ElCLib::Parameter(L2,Ptfin);
1494                 }
1495
1496                 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1497                 
1498                 if((Abs(U1-Res1sup)>LongMiniSeg)
1499                    ||(Abs(U2-Res2sup)>LongMiniSeg)) { 
1500                   //-- Modif du 1er Octobre 92 (Pour Composites)
1501                   
1502                   IntRes2d_IntersectionSegment Segment(PtSeg1,PtSeg2
1503                                                        ,Opposite,Standard_False);
1504                   Append(Segment);  
1505                 }
1506                 else {
1507                   Append(SegmentToPoint(PtSeg1,T1a,T2a,PtSeg2,T1b,T2b));
1508                 }
1509               }
1510               else {
1511                 Append(PtSeg1); 
1512               }
1513             }
1514           }
1515         } //----- Fin Creation Segment ----(Res2sup-Res2inf>Tol)-------------
1516         else {
1517           //------ (Intersection And Domain1)  AND  Domain2  --> Point ------
1518           //-- Attention Res1sup peut etre  different de  U2
1519           //--   Mais on a Res1sup-Res1inf < Tol 
1520
1521     //gka #0022833
1522     IntRes2d_TypeTrans aCurTrans = ( ProdVectTan >= TOLERANCE_ANGULAIRE ? 
1523            IntRes2d_In : ( ProdVectTan <= -TOLERANCE_ANGULAIRE ? IntRes2d_Out : IntRes2d_Undecided ) );
1524
1525     IntRes2d_IntersectionPoint NewPoint1;
1526     if( computeIntPoint(Domain2, Domain1, L2, L1, aCosT1T2, U2, U1, Res2inf, Res2sup, 2, aCurTrans, NewPoint1 ) )
1527       Append(NewPoint1);
1528         
1529         }
1530       }
1531     }
1532   }
1533   else {
1534     if(nbsol==2) {  //== Droites confondues a la tolerance pres 
1535       //--On traite ici le cas de segments resultats non neccess. bornes
1536       //-- 
1537       //--On prend la droite D1 comme reference ( pour le sens positif )
1538       //--
1539       Standard_Integer ResHasFirstPoint=0;    
1540       Standard_Integer ResHasLastPoint=0;
1541       Standard_Real ParamStart,ParamStart2,ParamEnd,ParamEnd2;
1542       Standard_Real Org2SurL1=ElCLib::Parameter(L1,L2.Location());
1543       //== 3 : L1 et L2 bornent
1544       //== 2 :       L2 borne
1545       //== 1 : L1 borne
1546       if(Domain1.HasFirstPoint()) ResHasFirstPoint=1;
1547       if(Domain1.HasLastPoint())   ResHasLastPoint=1;
1548       if(Opposite) {
1549         if(Domain2.HasLastPoint())     ResHasFirstPoint+=2;
1550         if(Domain2.HasFirstPoint())   ResHasLastPoint+=2;
1551       }
1552       else {
1553         if(Domain2.HasLastPoint())     ResHasLastPoint+=2;
1554         if(Domain2.HasFirstPoint())   ResHasFirstPoint+=2;
1555       }
1556       if(ResHasFirstPoint==0 && ResHasLastPoint==0) {
1557         //~~~~ Creation d un segment infini avec Opposite
1558         Append(IntRes2d_IntersectionSegment(Opposite));
1559       }
1560       else {  //-- On obtient au pire une demi-droite
1561         switch(ResHasFirstPoint) {
1562         case 1: 
1563           ParamStart=Domain1.FirstParameter(); 
1564           ParamStart2=(Opposite)? (Org2SurL1-ParamStart) 
1565                                  :(ParamStart-Org2SurL1); 
1566           break;
1567         case 2:
1568           if(Opposite) {
1569             ParamStart2=Domain2.LastParameter();
1570             ParamStart=Org2SurL1 - ParamStart2; 
1571           }
1572           else {
1573             ParamStart2=Domain2.FirstParameter();
1574             ParamStart=Org2SurL1 + ParamStart2;
1575           }
1576           break;
1577         case 3:
1578           if(Opposite) {
1579             ParamStart2=Domain2.LastParameter();
1580             ParamStart=Org2SurL1 - ParamStart2; 
1581             if(ParamStart < Domain1.FirstParameter()) {
1582               ParamStart=Domain1.FirstParameter();
1583               ParamStart2=Org2SurL1 -  ParamStart;
1584             }
1585           }
1586           else {
1587             ParamStart2=Domain2.FirstParameter();
1588             ParamStart=Org2SurL1 + ParamStart2;
1589             if(ParamStart < Domain1.FirstParameter()) {
1590               ParamStart=Domain1.FirstParameter();
1591               ParamStart2=ParamStart - Org2SurL1;
1592             }
1593           }
1594           break;
1595         default:  //~~~ Segment Infini a gauche
1596           break;
1597         }
1598         
1599         switch(ResHasLastPoint) {
1600         case 1: 
1601           ParamEnd=Domain1.LastParameter(); 
1602           ParamEnd2=(Opposite)? (Org2SurL1-ParamEnd) 
1603                                  :(ParamEnd-Org2SurL1); 
1604           break;
1605         case 2:
1606           if(Opposite) {
1607             ParamEnd2=Domain2.FirstParameter();
1608             ParamEnd=Org2SurL1 - ParamEnd2; 
1609           }
1610           else {
1611             ParamEnd2=Domain2.LastParameter();
1612             ParamEnd=Org2SurL1 + ParamEnd2;
1613           }
1614           break;
1615         case 3:
1616           if(Opposite) {
1617             ParamEnd2=Domain2.FirstParameter();
1618             ParamEnd=Org2SurL1 - ParamEnd2; 
1619             if(ParamEnd > Domain1.LastParameter()) {
1620               ParamEnd=Domain1.LastParameter();
1621               ParamEnd2=Org2SurL1 -  ParamEnd;
1622             }
1623           }
1624           else {
1625             ParamEnd2=Domain2.LastParameter();
1626             ParamEnd=Org2SurL1 + ParamEnd2;
1627             if(ParamEnd > Domain1.LastParameter()) {
1628               ParamEnd=Domain1.LastParameter();
1629               ParamEnd2=ParamEnd - Org2SurL1;
1630             }
1631           }
1632         default:  //~~~ Segment Infini a droite
1633           break;
1634         }
1635         
1636         IntRes2d_Transition Tinf,Tsup;
1637
1638         if(ResHasFirstPoint) {
1639           if(ResHasLastPoint) {
1640             //~~~ Creation de la borne superieure
1641             //~~~ L1 :     |------------->       ou          |-------------->
1642             //~~~ L2 : <------------|            ou  <----|
1643             if(ParamEnd >= (ParamStart-Tol)) { 
1644               //~~~ Creation d un segment
1645               IntRes2d_Position Pos1,Pos2;
1646               Pos1=FindPositionLL(ParamStart,Domain1);
1647               Pos2=FindPositionLL(ParamStart2,Domain2);
1648               Tinf.SetValue(Standard_True,Pos1,IntRes2d_Unknown,Opposite);
1649               Tsup.SetValue(Standard_True,Pos2,IntRes2d_Unknown,Opposite);
1650               IntRes2d_IntersectionPoint P1(ElCLib::Value(ParamStart,L1)
1651                                             ,ParamStart,ParamStart2
1652                                             ,Tinf,Tsup,Standard_False);
1653               if(ParamEnd > (ParamStart+Tol)) {
1654                 //~~~ Le segment est assez long
1655                 Pos1=FindPositionLL(ParamEnd,Domain1);
1656                 Pos2=FindPositionLL(ParamEnd2,Domain2);
1657                 Tinf.SetValue(Standard_True,Pos1,IntRes2d_Unknown,Opposite);
1658                 Tsup.SetValue(Standard_True,Pos2,IntRes2d_Unknown,Opposite);
1659
1660                 IntRes2d_IntersectionPoint P2(ElCLib::Value(ParamEnd,L1)
1661                                               ,ParamEnd,ParamEnd2
1662                                               ,Tinf,Tsup,Standard_False);
1663                 IntRes2d_IntersectionSegment Seg(P1,P2,Opposite,Standard_False);
1664                 Append(Seg);
1665               }
1666               else {   //~~~~ le segment est de longueur inferieure a Tol
1667                 Append(P1);
1668               }
1669             } //-- if( ParamEnd >= ...)
1670           }   //-- if(ResHasLastPoint)
1671           else { 
1672             //~~~ Creation de la demi droite   |----------->
1673             IntRes2d_Position Pos1=FindPositionLL(ParamStart,Domain1);
1674             IntRes2d_Position Pos2=FindPositionLL(ParamStart2,Domain2);
1675             Tinf.SetValue(Standard_True,Pos1,IntRes2d_Unknown,Opposite);
1676             Tsup.SetValue(Standard_True,Pos2,IntRes2d_Unknown,Opposite);
1677
1678             IntRes2d_IntersectionPoint P(ElCLib::Value(ParamStart,L1)
1679                                           ,ParamStart,ParamStart2
1680                                           ,Tinf,Tsup,Standard_False);
1681             IntRes2d_IntersectionSegment Seg(P,Standard_True,Opposite,Standard_False);
1682             Append(Seg);
1683           }
1684         }
1685         else {
1686           IntRes2d_Position Pos1=FindPositionLL(ParamEnd,Domain1);
1687           IntRes2d_Position Pos2=FindPositionLL(ParamEnd2,Domain2);
1688           Tinf.SetValue(Standard_True,Pos1,IntRes2d_Unknown,Opposite);
1689           Tsup.SetValue(Standard_True,Pos2,IntRes2d_Unknown,Opposite);
1690
1691           IntRes2d_IntersectionPoint P2(ElCLib::Value(ParamEnd,L1)
1692                                         ,ParamEnd,ParamEnd2
1693                                         ,Tinf,Tsup,Standard_False);
1694           IntRes2d_IntersectionSegment Seg(P2,Standard_False,Opposite,Standard_False);
1695           Append(Seg);
1696           //~~~ Creation de la demi droite   <-----------|
1697         }
1698       }
1699     }
1700   }
1701 }
1702
1703
1704 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1705 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1706 void IntCurve_IntConicConic::Perform(const gp_Lin2d& Line
1707                                      ,const IntRes2d_Domain& LIG_Domain
1708                                      ,const gp_Circ2d& Circle
1709                                      ,const IntRes2d_Domain& CIRC_Domain
1710                                      ,const Standard_Real TolConf,const Standard_Real Tol) {
1711
1712 //--  if(! CIRC_Domain.IsClosed()) {
1713 //--    Standard_ConstructionError::Raise("Domaine incorrect");
1714 //--  }
1715
1716   Standard_Boolean TheReversedParameters=ReversedParameters();
1717   this->ResetFields();
1718   this->SetReversedParameters(TheReversedParameters);
1719
1720   Standard_Integer nbsol=0;
1721   PeriodicInterval CInt1,CInt2;  
1722   
1723   LineCircleGeometricIntersection(Line,Circle,TolConf,Tol
1724                                   ,CInt1,CInt2
1725                                   ,nbsol);
1726
1727   done=Standard_True;
1728
1729   if(nbsol==0) { //-- Pas de solutions 
1730     return;
1731   }
1732   
1733 //  Modified by Sergey KHROMOV - Mon Dec 18 11:13:18 2000 Begin
1734   if (nbsol == 2 && CInt2.Bsup == CInt1.Binf + PIpPI) {
1735     Standard_Real FirstBound = CIRC_Domain.FirstParameter();
1736     Standard_Real LastBound = CIRC_Domain.LastParameter();
1737     Standard_Real FirstTol = CIRC_Domain.FirstTolerance();
1738     Standard_Real LastTol = CIRC_Domain.LastTolerance();
1739     if (CInt1.Binf == 0 && FirstBound - FirstTol > CInt1.Bsup) {
1740       nbsol = 1;
1741       CInt1.SetValues(CInt2.Binf, CInt2.Bsup);
1742     } else if (CInt2.Bsup == PIpPI && LastBound + LastTol < CInt2.Binf)
1743       nbsol = 1;
1744   }
1745 //  Modified by Sergey KHROMOV - Mon Dec 18 11:13:20 2000 End
1746
1747   PeriodicInterval CDomain(CIRC_Domain);
1748   Standard_Real deltat = CDomain.Bsup-CDomain.Binf;
1749   while(CDomain.Binf >= PIpPI) CDomain.Binf-=PIpPI;
1750   while(CDomain.Binf <  0.0)   CDomain.Binf+=PIpPI;
1751   CDomain.Bsup=CDomain.Binf+deltat;
1752
1753   //------------------------------------------------------------
1754   //-- Ajout : Jeudi 28 mars 96 
1755   //-- On agrandit artificiellement les domaines
1756   Standard_Real BinfModif = CDomain.Binf;
1757   Standard_Real BsupModif = CDomain.Bsup;
1758   BinfModif-=CIRC_Domain.FirstTolerance() / Circle.Radius();
1759   BsupModif+=CIRC_Domain.LastTolerance() / Circle.Radius();
1760   deltat = BsupModif-BinfModif;
1761   if(deltat<=PIpPI) { 
1762     CDomain.Binf = BinfModif;
1763     CDomain.Bsup = BsupModif;
1764   }
1765   else { 
1766     Standard_Real t=PIpPI-deltat;
1767     t*=0.5;
1768     CDomain.Binf = BinfModif+t;
1769     CDomain.Bsup = BsupModif-t; 
1770   }
1771   deltat = CDomain.Bsup-CDomain.Binf;
1772   while(CDomain.Binf >= PIpPI) CDomain.Binf-=PIpPI;
1773   while(CDomain.Binf <  0.0)   CDomain.Binf+=PIpPI;
1774   CDomain.Bsup=CDomain.Binf+deltat;
1775   //-- ------------------------------------------------------------
1776
1777   Interval LDomain(LIG_Domain);
1778   
1779   Standard_Integer NbSolTotal=0;
1780   
1781   PeriodicInterval SolutionCircle[4];
1782   Interval SolutionLine[4];
1783   
1784   //----------------------------------------------------------------------
1785   //----------- Traitement du premier intervalle Geometrique  CInt1   ----
1786   //----------------------------------------------------------------------
1787   //-- NbSolTotal est incremente a chaque Intervalle solution.
1788   //-- On stocke les intervalles dans les tableaux : SolutionCircle[4] 
1789   //--                                            et SolutionLine[4]
1790   //-- des Exemples faciles donnent 3 Intersections
1791   //-- des Problemes numeriques peuvent peut etre en donner 4 ??????
1792   //--
1793   PeriodicInterval CDomainAndRes=CDomain.FirstIntersection(CInt1);
1794   
1795   ProjectOnLAndIntersectWithLDomain(Circle,Line
1796                                     ,CDomainAndRes
1797                                     ,LDomain
1798                                     ,SolutionCircle
1799                                     ,SolutionLine
1800                                     ,NbSolTotal
1801                                     ,LIG_Domain
1802                                     ,CIRC_Domain);
1803   
1804   CDomainAndRes=CDomain.SecondIntersection(CInt1);
1805   
1806   ProjectOnLAndIntersectWithLDomain(Circle,Line
1807                                     ,CDomainAndRes
1808                                     ,LDomain
1809                                     ,SolutionCircle
1810                                     ,SolutionLine
1811                                     ,NbSolTotal
1812                                     ,LIG_Domain
1813                                     ,CIRC_Domain);
1814   
1815   //----------------------------------------------------------------------
1816   //----------- Traitement du second intervalle Geometrique   C1_Int2 ----
1817   //----------------------------------------------------------------------
1818   if(nbsol==2) {
1819     CDomainAndRes=CDomain.FirstIntersection(CInt2);
1820     
1821     ProjectOnLAndIntersectWithLDomain(Circle,Line
1822                                       ,CDomainAndRes
1823                                       ,LDomain
1824                                       ,SolutionCircle
1825                                       ,SolutionLine
1826                                       ,NbSolTotal
1827                                       ,LIG_Domain
1828                                       ,CIRC_Domain);
1829     
1830     //--------------------------------------------------------------------
1831     CDomainAndRes=CDomain.SecondIntersection(CInt2);
1832     
1833     
1834     ProjectOnLAndIntersectWithLDomain(Circle,Line
1835                                       ,CDomainAndRes
1836                                       ,LDomain
1837                                       ,SolutionCircle
1838                                       ,SolutionLine
1839                                       ,NbSolTotal
1840                                       ,LIG_Domain
1841                                       ,CIRC_Domain);
1842   }
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852   //----------------------------------------------------------------------
1853   //-- Calcul de toutes les transitions et Positions.
1854   //--
1855   //-- On determine si des intervalles sont reduit a des points 
1856   //--      ( Rayon * Intervalle.Length()    <    TolConf   )   ### Modif 19 Nov Tol-->TolConf
1857   //--
1858   Standard_Real R=Circle.Radius();
1859   Standard_Integer i ;
1860   Standard_Real MaxTol = TolConf;
1861   if(MaxTol<Tol) MaxTol = Tol;
1862   if(MaxTol<1.0e-10) MaxTol = 1.0e-10; 
1863
1864   for( i=0; i<NbSolTotal ; i++) { 
1865     if((R * SolutionCircle[i].Length())<MaxTol 
1866        && (SolutionLine[i].Length())<MaxTol) {
1867       
1868       Standard_Real t=(SolutionCircle[i].Binf+SolutionCircle[i].Bsup)*0.5;
1869       SolutionCircle[i].Binf=SolutionCircle[i].Bsup=t;
1870       
1871       t=(SolutionLine[i].Binf+SolutionLine[i].Bsup)*0.5;
1872       SolutionLine[i].Binf=SolutionLine[i].Bsup=t;
1873     }
1874   }
1875 #if 0 
1876   if(NbSolTotal == 2) { 
1877     if(SolutionLine[0].Binf==SolutionLine[0].BSup) { 
1878       if(SolutionLine[1].Binf==SolutionLine[1].BSup) {
1879         if(Abs(SolutionLine[0].Binf-SolutionLine[1].Binf)<TolConf) { 
1880           SolutionLine[0].Binf=0.5*(SolutionLine[0].BSup+SolutionLine[1].BSup);
1881           SolutionLine[0].BSup=SolutionLine[0].Binf;
1882           NbSolTotal = 1;
1883         }
1884       }
1885     }
1886   }
1887 #endif
1888   //----------------------------------------------------------------------
1889   //-- Traitement des intervalles (ou des points obtenus)
1890   //-- 
1891   if(NbSolTotal) { 
1892     gp_Ax22d CircleAxis=Circle.Axis();
1893     gp_Ax2d LineAxis=Line.Position();
1894     gp_Pnt2d P1a,P2a,P1b,P2b;
1895     gp_Vec2d Tan1,Tan2,Norm1;
1896     gp_Vec2d Norm2(0.0,0.0);
1897     IntRes2d_Transition T1a,T2a,T1b,T2b;
1898     IntRes2d_Position Pos1a,Pos1b,Pos2a,Pos2b;
1899     
1900     ElCLib::CircleD1(SolutionCircle[0].Binf,CircleAxis,R,P1a,Tan1);
1901     ElCLib::LineD1(SolutionLine[0].Binf,LineAxis,P2a,Tan2);
1902     
1903     Standard_Boolean Opposite=((Tan1.Dot(Tan2))<0.0)? Standard_True : Standard_False;
1904     
1905     
1906     for(i=0; i<NbSolTotal; i++ ) {
1907
1908
1909       //-- 7 aout 97 
1910       //-- On recentre Bin et Bsup de facon a avoir une portion commune avec CIRC_Domain
1911       Standard_Real p1=SolutionCircle[i].Binf;
1912       Standard_Real p2=SolutionCircle[i].Bsup;
1913       Standard_Real q1=CIRC_Domain.FirstParameter();
1914       Standard_Real q2=CIRC_Domain.LastParameter();
1915       //--          |------ CircDomain ------|   [-- Sol --]
1916       if(p1>q2) {       
1917         do { 
1918           p1-=PIpPI; 
1919           p2-=PIpPI;
1920         }
1921         while( (p1>q2) );
1922       }
1923       else if(p2<q1) { 
1924         do { 
1925           p1+=PIpPI; 
1926           p2+=PIpPI;
1927         }
1928         while( (p2<q1) );       
1929       }
1930       if(p1<q1 && p2>q1) { 
1931         p1=q1;
1932       }
1933       if(p1<q2 && p2>q2) { 
1934         p2=q2;
1935       }
1936       
1937 #if 0
1938       if(SolutionCircle[i].Binf!=p1 || SolutionCircle[i].Bsup!=p2) { 
1939         printf("\n IntCurve_IntConicConic_1.cxx : (%g , %g) --> (%g , %g)\n",
1940                SolutionCircle[i].Binf,SolutionCircle[i].Bsup,p1,p2); 
1941       } 
1942 #endif
1943       SolutionCircle[i].Binf=p1;
1944       SolutionCircle[i].Bsup=p2;
1945       
1946 //-- Fin 7 aout 97
1947
1948       
1949       Standard_Real Linf=(Opposite)? SolutionLine[i].Bsup : SolutionLine[i].Binf;
1950       Standard_Real Lsup=(Opposite)? SolutionLine[i].Binf : SolutionLine[i].Bsup;
1951       
1952       //---------------------------------------------------------------
1953       //-- Si les parametres sur le cercle sont en premier 
1954       //-- On doit retourner ces parametres dans l ordre croissant
1955       //---------------------------------------------------------------
1956       if(Linf > Lsup) {
1957         Standard_Real T=SolutionCircle[i].Binf;
1958         SolutionCircle[i].Binf=SolutionCircle[i].Bsup;
1959         SolutionCircle[i].Bsup=T;
1960         
1961         T=Linf; Linf=Lsup; Lsup=T;
1962       }
1963       
1964       
1965       ElCLib::CircleD2(SolutionCircle[i].Binf,CircleAxis,R,P1a,Tan1,Norm1); 
1966       ElCLib::LineD1(Linf,LineAxis,P2a,Tan2);
1967       
1968       IntImpParGen::DeterminePosition(Pos1a,CIRC_Domain,P1a,SolutionCircle[i].Binf);
1969       IntImpParGen::DeterminePosition(Pos2a,LIG_Domain,P2a,Linf); 
1970       Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
1971       Standard_Real Cinf;
1972       if(Pos1a==IntRes2d_End) {
1973         Cinf = CIRC_Domain.LastParameter();
1974         P1a  = CIRC_Domain.LastPoint();
1975         Linf = ElCLib::Parameter(Line,P1a);
1976         
1977         ElCLib::CircleD2(Cinf,CircleAxis,R,P1a,Tan1,Norm1); 
1978         ElCLib::LineD1(Linf,LineAxis,P2a,Tan2); 
1979         IntImpParGen::DeterminePosition(Pos1a,CIRC_Domain,P1a,Cinf);
1980         IntImpParGen::DeterminePosition(Pos2a,LIG_Domain,P2a,Linf); 
1981         Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
1982       }
1983       else if(Pos1a==IntRes2d_Head) { 
1984         Cinf = CIRC_Domain.FirstParameter();
1985         P1a  = CIRC_Domain.FirstPoint();
1986         Linf = ElCLib::Parameter(Line,P1a);
1987         
1988         ElCLib::CircleD2(Cinf,CircleAxis,R,P1a,Tan1,Norm1); 
1989         ElCLib::LineD1(Linf,LineAxis,P2a,Tan2); 
1990         IntImpParGen::DeterminePosition(Pos1a,CIRC_Domain,P1a,Cinf);
1991         IntImpParGen::DeterminePosition(Pos2a,LIG_Domain,P2a,Linf); 
1992         Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
1993       }
1994       else { 
1995         Cinf=NormalizeOnCircleDomain(SolutionCircle[i].Binf,CIRC_Domain);
1996       }
1997
1998       IntRes2d_IntersectionPoint NewPoint1(P1a,Linf,Cinf,T2a,T1a,ReversedParameters());
1999       
2000       if((SolutionLine[i].Length()+SolutionCircle[i].Length()) >0.0) {
2001         
2002         ElCLib::CircleD2(SolutionCircle[i].Bsup,CircleAxis,R,P1b,Tan1,Norm1); 
2003         ElCLib::LineD1(Lsup,LineAxis,P2b,Tan2);
2004           
2005         IntImpParGen::DeterminePosition(Pos1b,CIRC_Domain,P1b,SolutionCircle[i].Bsup);
2006         IntImpParGen::DeterminePosition(Pos2b,LIG_Domain,P2b,Lsup);
2007         Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
2008         Standard_Real Csup;
2009         if(Pos1b==IntRes2d_End) {
2010           Csup = CIRC_Domain.LastParameter();
2011           P1b  = CIRC_Domain.LastPoint();
2012           Lsup = ElCLib::Parameter(Line,P1b);
2013           ElCLib::CircleD2(Csup,CircleAxis,R,P1b,Tan1,Norm1); 
2014           ElCLib::LineD1(Lsup,LineAxis,P2b,Tan2);
2015           
2016           IntImpParGen::DeterminePosition(Pos1b,CIRC_Domain,P1b,Csup);
2017           IntImpParGen::DeterminePosition(Pos2b,LIG_Domain,P2b,Lsup);
2018           Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);      
2019         }
2020         else if(Pos1b==IntRes2d_Head) { 
2021           Csup = CIRC_Domain.FirstParameter();
2022           P1b  = CIRC_Domain.FirstPoint();
2023           Lsup = ElCLib::Parameter(Line,P1b);
2024           ElCLib::CircleD2(Csup,CircleAxis,R,P1b,Tan1,Norm1); 
2025           ElCLib::LineD1(Lsup,LineAxis,P2b,Tan2);
2026           
2027           IntImpParGen::DeterminePosition(Pos1b,CIRC_Domain,P1b,Csup);
2028           IntImpParGen::DeterminePosition(Pos2b,LIG_Domain,P2b,Lsup);
2029           Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);    
2030         }
2031         else { 
2032           Csup=NormalizeOnCircleDomain(SolutionCircle[i].Bsup,CIRC_Domain);
2033         }
2034
2035         IntRes2d_IntersectionPoint NewPoint2(P1b,Lsup,Csup,T2b,T1b,ReversedParameters());
2036         
2037         if(((Abs(Csup-Cinf)*R >  MaxTol) && (Abs(Lsup-Linf) > MaxTol))
2038            || (T1a.TransitionType() != T2a.TransitionType())) {  
2039           //-- Verifier egalement les transitions 
2040           
2041           IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2
2042                                               ,Opposite,ReversedParameters());
2043           Append(NewSeg);
2044         }
2045         else { 
2046           if(Pos1a!=IntRes2d_Middle ||  Pos2a!=IntRes2d_Middle) { 
2047             Insert(NewPoint1);
2048           }
2049           if(Pos1b!=IntRes2d_Middle ||  Pos2b!=IntRes2d_Middle) { 
2050             Insert(NewPoint2);
2051           }
2052
2053         }
2054       }
2055       else {
2056         //--Standard_Real Cmid=NormalizeOnCircleDomain(0.5*(SolutionCircle[i].Bsup+SolutionCircle[i].Binf)
2057         //--                                       ,CIRC_Domain);        
2058         //--IntRes2d_IntersectionPoint NewPoint(P2a,0.5*(Linf+Lsup)
2059         //--                                ,Cmid
2060         //--                                ,T2a,T1a,ReversedParameters());
2061         Insert(NewPoint1);
2062       }
2063     }
2064   }
2065 }
2066
2067
2068
2069
2070 const IntRes2d_IntersectionPoint SegmentToPoint( const IntRes2d_IntersectionPoint& Pa
2071                                                 ,const IntRes2d_Transition& T1a
2072                                                 ,const IntRes2d_Transition& T2a
2073                                                 ,const IntRes2d_IntersectionPoint& Pb
2074                                                 ,const IntRes2d_Transition& T1b
2075                                                 ,const IntRes2d_Transition& T2b) {  
2076   
2077   if((T1b.PositionOnCurve() == IntRes2d_Middle) 
2078      && (T2b.PositionOnCurve() == IntRes2d_Middle)) { 
2079     return(Pa);
2080   }
2081   if((T1a.PositionOnCurve() == IntRes2d_Middle) 
2082      && (T2a.PositionOnCurve() == IntRes2d_Middle)) { 
2083     return(Pb);
2084   }
2085   
2086   IntRes2d_Transition t1 = T1a;
2087   IntRes2d_Transition t2 = T2a;
2088   Standard_Real u1 = Pa.ParamOnFirst();
2089   Standard_Real u2 = Pa.ParamOnSecond();
2090   
2091   
2092   if(t1.PositionOnCurve() == IntRes2d_Middle) { 
2093     t1.SetPosition(T1b.PositionOnCurve());
2094     u1 = Pb.ParamOnFirst();
2095   }
2096   if(t2.PositionOnCurve() == IntRes2d_Middle) {
2097     t2.SetPosition(T2b.PositionOnCurve());
2098     u2 = Pb.ParamOnSecond();
2099   } 
2100   return(IntRes2d_IntersectionPoint(Pa.Value(),u1,u2,t1,t2,Standard_False));
2101 }