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