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