1 // Created on: 1992-05-06
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // a modifier le cas de 2 points confondus ( Insert a la place d'append ? )
19 #include <IntCurve_IntConicConic.jxx>
21 #include <IntCurve_IConicTool.hxx>
22 #include <IntCurve_PConic.hxx>
23 #include <IntRes2d_Domain.hxx>
25 #include <IntCurve_IntConicConic_Tool.hxx>
26 #include <IntImpParGen.hxx>
27 #include <IntCurve_IntConicConic_1.hxx>
29 #include <Standard_ConstructionError.hxx>
30 #include <IntRes2d_IntersectionPoint.hxx>
31 #include <IntRes2d_IntersectionSegment.hxx>
33 #include <gp_Pnt2d.hxx>
34 #include <gp_Vec2d.hxx>
35 #include <Precision.hxx>
36 #include <IntRes2d_TypeTrans.hxx>
38 Standard_Boolean Affichage=Standard_False;
39 Standard_Boolean AffichageGraph=Standard_True;
41 //modified by NIZHNY-MKK Tue Feb 15 10:53:34 2000.BEGIN
42 // #define TOLERANCE_ANGULAIRE 0.00000001
43 #define TOLERANCE_ANGULAIRE 1.e-15 //the reason is at least to make an accordance between transition and position computation.
44 //modified by NIZHNY-MKK Tue Feb 15 10:53:45 2000.END
46 const Standard_Real PIsur2 = 0.5*M_PI;
48 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49 IntRes2d_Position FindPositionLL(Standard_Real&,const IntRes2d_Domain&);
50 const IntRes2d_IntersectionPoint SegmentToPoint( const IntRes2d_IntersectionPoint& Pa
51 ,const IntRes2d_Transition& T1a
52 ,const IntRes2d_Transition& T2a
53 ,const IntRes2d_IntersectionPoint& Pb
54 ,const IntRes2d_Transition& T1b
55 ,const IntRes2d_Transition& T2b);
56 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
57 void ProjectOnC2AndIntersectWithC2Domain(const gp_Circ2d& Circle1
58 ,const gp_Circ2d& Circle2
59 ,PeriodicInterval& C1DomainAndRes
60 ,PeriodicInterval& DomainC2
61 ,PeriodicInterval* SolutionC1
62 ,PeriodicInterval* SolutionC2
63 ,Standard_Integer &NbSolTotal
64 ,const Standard_Boolean IdentCircles)
67 if(C1DomainAndRes.IsNull()) return;
68 //-------------------------------------------------------------------------
69 //-- On cherche l intervalle correspondant sur C2
70 //-- Puis on intersecte l intervalle avec le domaine de C2
71 //-- Enfin, on cherche l intervalle correspondant sur C1
74 ElCLib::CircleParameter(Circle2.Axis()
75 ,ElCLib::CircleValue(C1DomainAndRes.Binf
76 ,Circle1.Axis(),Circle1.Radius()));
78 ElCLib::CircleParameter(Circle2.Axis()
79 ,ElCLib::CircleValue(C1DomainAndRes.Bsup
80 ,Circle1.Axis(),Circle1.Radius()));
82 PeriodicInterval C2Inter(C2inf,C2sup);
85 if(C2Inter.Length() > M_PI)
89 if(C2sup<=C2inf) C2sup+=PIpPI;
95 C2Inter.Bsup=C2sup; //--- Verifier la longueur de l'intervalle sur C2
96 C2Inter.Bsup=C2inf+C1DomainAndRes.Bsup-C1DomainAndRes.Binf;
99 PeriodicInterval C2InterAndDomain[2];
101 for(Standard_Integer i=0; i<2 ; i++) {
102 C2InterAndDomain[i]=(i==0)? DomainC2.FirstIntersection(C2Inter)
103 : DomainC2.SecondIntersection(C2Inter);
105 if(!C2InterAndDomain[i].IsNull()) {
107 Standard_Real C1inf =
108 ElCLib::CircleParameter(Circle1.Axis()
109 ,ElCLib::CircleValue(C2InterAndDomain[i].Binf
110 ,Circle2.Axis(),Circle2.Radius()));
111 Standard_Real C1sup =
112 ElCLib::CircleParameter(Circle1.Axis()
113 ,ElCLib::CircleValue(C2InterAndDomain[i].Bsup
114 ,Circle2.Axis(),Circle2.Radius()));
116 SolutionC1[NbSolTotal]=PeriodicInterval(C1inf,C1sup);
118 if(SolutionC1[NbSolTotal].Length() > M_PI)
119 SolutionC1[NbSolTotal].Complement();
122 if(SolutionC1[NbSolTotal].Bsup <= SolutionC1[NbSolTotal].Binf) {
123 SolutionC1[NbSolTotal].Bsup+=PIpPI;
125 if(SolutionC1[NbSolTotal].Binf>=PIpPI) {
126 SolutionC1[NbSolTotal].Binf-=PIpPI;
127 SolutionC1[NbSolTotal].Bsup-=PIpPI;
130 SolutionC2[NbSolTotal]=C2InterAndDomain[i];
135 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
136 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
137 void CircleCircleGeometricIntersection(const gp_Circ2d& C1
139 ,const Standard_Real Tol
140 ,const Standard_Real TolTang
141 ,PeriodicInterval& C1_Res1
142 ,PeriodicInterval& C1_Res2
143 ,Standard_Integer& nbsol) {
145 Standard_Real C1_binf1,C1_binf2=0,C1_bsup1,C1_bsup2=0;
146 Standard_Real dO1O2=(C1.Location()).Distance(C2.Location());
147 Standard_Real R1=C1.Radius();
148 Standard_Real R2=C2.Radius();
149 Standard_Real AbsR1mR2=Abs(R1-R2);
150 //----------------------------------------------------------------
151 if(dO1O2 > (R1+R2+Tol)) {
152 if(dO1O2 > (R1+R2+TolTang)) {
162 //----------------------------------------------------------------
163 else if(dO1O2 <= Tol && AbsR1mR2<=Tol) {
168 //----------------------------------------------------------------
169 Standard_Real R1pR2=R1+R2;
170 Standard_Real R1pTol=R1+Tol;
171 Standard_Real R1mTol=R1-Tol;
172 // Standard_Real R1R1=R1*R1;
173 Standard_Real R2R2=R2*R2;
174 Standard_Real R1pTolR1pTol=R1pTol*R1pTol;
175 Standard_Real R1mTolR1mTol=R1mTol*R1mTol;
176 Standard_Real dO1O2dO1O2=dO1O2*dO1O2;
177 Standard_Real dAlpha1;
178 //--------------------------------------------------------------- Cas
179 //-- C2 coupe le cercle C1+ (=C(x1,y1,R1+Tol))
180 //-- 1 seul segment donne par Inter C2 C1+
182 if(dO1O2 > R1pR2-Tol) {
183 Standard_Real dx=(R1pTolR1pTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
184 Standard_Real dy=(R1pTolR1pTol-dx*dx);
185 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
186 dAlpha1=ATan2(dy,dx);
192 //--------------------------------------------------------------------
193 //-- 2 segments donnes par Inter C2 avec C1- C1 C1+
194 //-- Seul le signe de dx change si dO1O2 < Max(R1,R2)
196 else if(dO1O2 > AbsR1mR2-Tol) { // -- +
197 //------------------- Intersection C2 C1+ --------------------------
198 Standard_Real dx=(R1pTolR1pTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
199 Standard_Real dy=(R1pTolR1pTol-dx*dx);
200 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
202 dAlpha1=ATan2(dy,dx);
203 C1_binf1=-dAlpha1; C1_bsup2=dAlpha1; //-- |...? ?...| Sur C1
205 //------------------ Intersection C2 C1- -------------------------
206 dx=(R1mTolR1mTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
207 dy=(R1mTolR1mTol-dx*dx);
208 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
209 dAlpha1=ATan2(dy,dx);
211 C1_binf2=dAlpha1; C1_bsup1=-dAlpha1; //-- |...x x...| Sur C1
213 //------------------------------
214 //-- Les 2 intervalles sont ils
215 //-- en fait un seul inter ?
217 if(dy==0) { //-- Les 2 bornes internes sont identiques
222 if(C1_binf1>C1_bsup1) {
223 dAlpha1 = C1_binf1; C1_binf1 = C1_bsup1; C1_bsup1 = dAlpha1;
225 if(C1_binf2>C1_bsup2) {
226 dAlpha1 = C1_binf2; C1_binf2 = C1_bsup2; C1_bsup2 = dAlpha1;
228 if( ((C1_binf1<=C1_bsup2) && (C1_binf1>=C1_binf2))
229 || ((C1_bsup1<=C1_bsup2) && (C1_bsup1>=C1_binf2))) {
230 if(C1_binf1 > C1_binf2) C1_binf1 = C1_binf2;
231 if(C1_binf1 > C1_bsup2) C1_binf1 = C1_bsup2;
232 if(C1_bsup1 < C1_binf2) C1_bsup1 = C1_binf2;
233 if(C1_bsup1 < C1_bsup2) C1_bsup1 = C1_bsup2;
238 //--------------------------------------------------------------
240 if((dO1O2 > AbsR1mR2-TolTang) && (AbsR1mR2-TolTang)>0.0) {
251 //-- cout<<" C1_binf1:"<<C1_binf1;
252 //-- cout<<" C1_bsup1:"<<C1_bsup1;
253 //-- cout<<" C1_binf2:"<<C1_binf2;
254 //-- cout<<" C1_bsup2:"<<C1_bsup2<<endl;
255 //----------------------------------------------------------------
256 //-- Mise en forme des resultats :
257 //-- Les calculs ont ete fait dans le repere x1,y1, (O1,O2)
258 //-- On se ramene au repere propre a C1
260 gp_Vec2d Axe1=C1.XAxis().Direction();
261 gp_Vec2d AxeO1O2=gp_Vec2d(C1.Location(),C2.Location());
263 Standard_Real dAngle1;
264 if(AxeO1O2.Magnitude() <= gp::Resolution())
265 dAngle1=Axe1.Angle(C2.XAxis().Direction());
267 dAngle1=Axe1.Angle(AxeO1O2);
269 if(C1.IsDirect() == Standard_False) {
274 C1_binf1+=dAngle1; C1_bsup1+=dAngle1;
276 //-- par construction aucun des segments ne peut exceder PI
277 //-- (permet de ne pas gerer trop de cas differents)
279 C1_Res1.SetValues(C1_binf1,C1_bsup1);
280 if(C1_Res1.Length() > M_PI) C1_Res1.Complement();
283 C1_binf2+=dAngle1; C1_bsup2+=dAngle1;
284 C1_Res2.SetValues(C1_binf2,C1_bsup2);
285 if(C1_Res2.Length() > M_PI) C1_Res2.Complement();
291 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
292 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
293 void ProjectOnLAndIntersectWithLDomain(const gp_Circ2d& Circle
294 ,const gp_Lin2d& Line
295 ,PeriodicInterval& CDomainAndRes
297 ,PeriodicInterval* CircleSolution
298 ,Interval* LineSolution
299 ,Standard_Integer &NbSolTotal
300 ,const IntRes2d_Domain& RefLineDomain
301 // ,const IntRes2d_Domain& )
302 ,const IntRes2d_Domain& )
306 if(CDomainAndRes.IsNull()) return;
307 //-------------------------------------------------------------------------
308 //-- On cherche l intervalle correspondant sur C2
309 //-- Puis on intersecte l intervalle avec le domaine de C2
310 //-- Enfin, on cherche l intervalle correspondant sur C1
313 Standard_Real Linf=ElCLib::Parameter(Line
314 ,ElCLib::CircleValue(CDomainAndRes.Binf
317 Standard_Real Lsup=ElCLib::Parameter(Line
318 ,ElCLib::CircleValue(CDomainAndRes.Bsup
322 Interval LInter(Linf,Lsup); //-- Necessairement Borne
324 Interval LInterAndDomain=LDomain.IntersectionWithBounded(LInter);
326 if(!LInterAndDomain.IsNull) {
328 Standard_Real DomLinf = (RefLineDomain.HasFirstPoint())? RefLineDomain.FirstParameter() : -Precision::Infinite();
329 Standard_Real DomLsup = (RefLineDomain.HasLastPoint())? RefLineDomain.LastParameter() : Precision::Infinite();
331 Linf = LInterAndDomain.Binf;
332 Lsup = LInterAndDomain.Bsup;
348 LInterAndDomain.Binf = Linf;
349 LInterAndDomain.Bsup = Lsup;
353 ElCLib::CircleParameter(Circle.Axis()
354 ,ElCLib::LineValue(LInterAndDomain.Binf,
357 ElCLib::CircleParameter(Circle.Axis()
358 ,ElCLib::LineValue(LInterAndDomain.Bsup
361 if(Cinf<CDomainAndRes.Binf) Cinf = CDomainAndRes.Binf;
362 if(Csup>CDomainAndRes.Bsup) Csup = CDomainAndRes.Bsup;
364 Standard_Real Cinf=CDomainAndRes.Binf;
365 Standard_Real Csup=CDomainAndRes.Bsup;
367 if(Cinf>=Csup) { Cinf = CDomainAndRes.Binf; Csup = CDomainAndRes.Bsup; }
368 CircleSolution[NbSolTotal]=PeriodicInterval(Cinf,Csup);
369 if(CircleSolution[NbSolTotal].Length() > M_PI)
370 CircleSolution[NbSolTotal].Complement();
372 LineSolution[NbSolTotal]=LInterAndDomain;
377 //=======================================================================
378 //function : LineCircleGeometricIntersection
380 //~~ On cherche des segments d intersection dans le `tuyau`
381 //~~ R+Tol R-Tol ( Tol est TolConf : Tolerance de confusion d arc)
382 //~~ On Cherche un point d intersection a une distance TolTang du cercle.
383 //=======================================================================
384 void LineCircleGeometricIntersection(const gp_Lin2d& Line,
385 const gp_Circ2d& Circle,
386 const Standard_Real Tol,
387 const Standard_Real TolTang,
388 PeriodicInterval& CInt1,
389 PeriodicInterval& CInt2,
390 Standard_Integer& nbsol)
394 Standard_Real dO1O2=Line.Distance(Circle.Location());
395 Standard_Real R=Circle.Radius();
396 Standard_Real RmTol=R-Tol;
397 Standard_Real binf1,binf2=0,bsup1,bsup2=0;
399 //----------------------------------------------------------------
400 if(dO1O2 > (R+Tol)) { //-- pas d intersection avec le 'tuyau'
401 if(dO1O2 > (R+TolTang)) {
412 //----------------------------------------------------------------
413 Standard_Boolean b2Sol;
414 Standard_Real dAlpha1;
415 //---------------------------------------------------------------
416 //-- Line coupe le cercle Circle+ (=C(x1,y1,R1+Tol))
417 b2Sol=Standard_False;
418 if (R>dO1O2+TolTang) {
419 Standard_Real aX2, aTol2;
422 aX2=4.*(R*R-dO1O2*dO1O2);
427 if(dO1O2 > RmTol && !b2Sol) {
428 //if(dO1O2 > RmTol) {
429 Standard_Real dx=dO1O2;
430 Standard_Real dy=0.0; //(RpTol*RpTol-dx*dx); //Patch !!!
431 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
432 dAlpha1=ATan2(dy,dx);
438 //--------------------------------------------------------------------
439 //-- 2 segments donnes par Inter Line avec Circle- Circle+
442 //------------------- Intersection Line Circle+ --------------------------
443 Standard_Real dx=dO1O2;
444 Standard_Real dy=R*R-dx*dx; //(RpTol*RpTol-dx*dx); //Patch !!!
445 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
447 dAlpha1=ATan2(dy,dx);
448 binf1=-dAlpha1; bsup2=dAlpha1; //-- |...? ?...| Sur C1
450 //------------------ Intersection Line Circle- -------------------------
451 dy=R*R-dx*dx; //(RmTol*RmTol-dx*dx); //Patch !!!
452 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
453 dAlpha1=ATan2(dy,dx);
455 binf2=dAlpha1; bsup1=-dAlpha1; //-- |...x x...| Sur C1
457 if((dAlpha1*R)<(Max(Tol,TolTang))) {
466 //--------------------------------------------------------------
467 //-- Mise en forme des resultats :
468 //-- Les calculs ont ete fait dans le repere x1,y1, (O1,O2)
469 //-- On se ramene au repere propre a C1
471 Standard_Real dAngle1=(Circle.XAxis().Direction()).Angle(Line.Direction());
474 //---------------------------------------------
475 //-- Si le cercle est indirect alors l origine
476 //-- est vue en -dAngle1.
478 if(Circle.IsDirect() == Standard_False) {
484 Standard_Real a,b,c,d;
485 Line.Coefficients(a,b,c);
487 d = a*Circle.Location().X() + b*Circle.Location().Y() + c;
489 if(d>0.0) dAngle1+= PIsur2;
490 else dAngle1-= PIsur2;
493 if(dAngle1<0.0) dAngle1+=PIpPI;
494 else if(dAngle1>PIpPI) dAngle1-=PIpPI;
497 binf1+=dAngle1; bsup1+=dAngle1;
499 //-- par construction aucun des segments ne peut exceder PI
500 //-- (permet de ne pas gerer trop de cas differents)
502 if(Circle.IsDirect() == Standard_False) {
503 Standard_Real t=binf1; binf1=bsup1; bsup1=t;
509 CInt1.SetValues(binf1,bsup1);
510 if(CInt1.Length() > M_PI) CInt1.Complement();
514 binf2+=dAngle1; bsup2+=dAngle1;
516 if(Circle.IsDirect() == Standard_False) {
517 Standard_Real t=binf2; binf2=bsup2; bsup2=t;
522 CInt2.SetValues(binf2,bsup2);
523 if(CInt2.Length() > M_PI) CInt2.Complement();
525 // Modified by Sergey KHROMOV - Thu Oct 26 17:51:05 2000 Begin
527 if (CInt1.Bsup > PIpPI && CInt1.Binf < PIpPI) {
532 CInt1.SetValues(binf1,CInt1.Bsup - PIpPI);
533 if(CInt1.Length() > M_PI) CInt1.Complement();
534 CInt2.SetValues(binf2,bsup2);
535 if(CInt2.Length() > M_PI) CInt2.Complement();
538 // Modified by Sergey KHROMOV - Thu Oct 26 17:51:13 2000 End
540 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
541 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
542 void DomainIntersection(const IntRes2d_Domain& Domain
543 ,const Standard_Real U1inf
544 ,const Standard_Real U1sup
545 ,Standard_Real& Res1inf
546 ,Standard_Real& Res1sup
547 ,IntRes2d_Position& PosInf
548 ,IntRes2d_Position& PosSup) {
550 if(Domain.HasFirstPoint()) {
551 if(U1sup < (Domain.FirstParameter()-Domain.FirstTolerance())) {
552 Res1inf=1; Res1sup=-1;
555 if(U1inf>(Domain.FirstParameter()+Domain.FirstTolerance())) {
557 PosInf=IntRes2d_Middle;
560 Res1inf=Domain.FirstParameter();
561 PosInf=IntRes2d_Head;
566 PosInf=IntRes2d_Middle;
569 if(Domain.HasLastPoint()) {
570 if(U1inf >(Domain.LastParameter()+Domain.LastTolerance())) {
571 Res1inf=1; Res1sup=-1;
574 if(U1sup<(Domain.LastParameter()-Domain.LastTolerance())) {
576 PosSup=IntRes2d_Middle;
579 Res1sup=Domain.LastParameter();
585 PosSup=IntRes2d_Middle;
587 //-- Si un des points est en bout ,
588 //-- on s assure que les parametres sont corrects
589 if(Res1inf>Res1sup) {
590 if(PosSup==IntRes2d_Middle) {
597 //--- Traitement des cas ou une intersection vraie est dans la tolerance
599 /*if(PosInf==IntRes2d_Head) {
600 if(Res1sup <= (Res1inf+Domain.FirstTolerance())) {
602 PosSup=IntRes2d_Head;
605 if(PosSup==IntRes2d_End) {
606 if(Res1inf >= (Res1sup-Domain.LastTolerance())) {
612 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
613 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
614 void LineLineGeometricIntersection(const gp_Lin2d& L1
616 ,const Standard_Real Tol
619 ,Standard_Real& SinDemiAngle
620 ,Standard_Integer& nbsol) {
622 Standard_Real U1x=L1.Direction().X();
623 Standard_Real U1y=L1.Direction().Y();
624 Standard_Real U2x=L2.Direction().X();
625 Standard_Real U2y=L2.Direction().Y();
626 Standard_Real Uo21x = L2.Location().X() - L1.Location().X();
627 Standard_Real Uo21y = L2.Location().Y() - L1.Location().Y();
629 Standard_Real D=U1y*U2x-U1x*U2y;
631 //modified by NIZHNY-MKK Tue Feb 15 10:54:04 2000.BEGIN
632 // if(Abs(D)<1e-15) { //-- Droites //
633 if(Abs(D) < TOLERANCE_ANGULAIRE) {
634 //modified by NIZHNY-MKK Tue Feb 15 10:54:11 2000.END
635 D=U1y*Uo21x - U1x*Uo21y;
636 nbsol=(Abs(D)<=Tol)? 2 : 0;
639 U1=(Uo21y * U2x - Uo21x * U2y)/D;
640 U2=(Uo21y * U1x - Uo21x * U1y)/D;
642 //------------------- Calcul du Sin du demi angle entre L1 et L2
645 if(D>1.0) D=1.0; //-- Deja vu !
646 SinDemiAngle=Sin(0.5*ASin(D));
650 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
651 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
652 /*IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Lin2d& L1
653 ,const IntRes2d_Domain& D1
655 ,const IntRes2d_Domain& D2
656 ,const Standard_Real TolConf
657 ,const Standard_Real Tol) {
658 Perform(L1,D1,L2,D2,TolConf,Tol);
662 IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Lin2d& L1
663 ,const IntRes2d_Domain& D1
665 ,const IntRes2d_Domain& D2
666 ,const Standard_Real TolConf
667 ,const Standard_Real Tol) {
669 Perform(L1,D1,C2,D2,TolConf,Tol);
673 IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Circ2d& C1
674 ,const IntRes2d_Domain& D1
676 ,const IntRes2d_Domain& D2
677 ,const Standard_Real TolConf
678 ,const Standard_Real Tol) {
679 SetReversedParameters(Standard_False);
680 Perform(C1,D1,C2,D2,TolConf,Tol);
682 //----------------------------------------------------------------------
683 void IntCurve_IntConicConic::Perform(const gp_Circ2d& Circle1
684 ,const IntRes2d_Domain& DomainCirc1
685 ,const gp_Circ2d& _Circle2
686 ,const IntRes2d_Domain& _DomainCirc2
687 ,const Standard_Real TolConf,const Standard_Real Tol) {
690 //-- TRES TRES MAL FAIT A REPRENDRE UN JOUR .... (lbr Octobre 98)
691 gp_Circ2d Circle2=_Circle2;
692 IntRes2d_Domain DomainCirc2=_DomainCirc2;
693 Standard_Boolean IndirectCircles=Standard_False;
694 if(Circle1.IsDirect() != _Circle2.IsDirect())
696 IndirectCircles=Standard_True;
697 Circle2=_Circle2.Reversed();
698 DomainCirc2.SetValues(_DomainCirc2.LastPoint(),
699 PIpPI-_DomainCirc2.LastParameter(),
700 _DomainCirc2.LastTolerance(),
701 _DomainCirc2.FirstPoint(),
702 PIpPI-_DomainCirc2.FirstParameter(),
703 _DomainCirc2.FirstTolerance());
704 DomainCirc2.SetEquivalentParameters(0.0,PIpPI);
708 Standard_Integer nbsol=0;
709 PeriodicInterval C1_Int1,C1_Int2;
711 //------- Intersection sans tenir compte du domaine ----> nbsol=0,1,2,3
712 CircleCircleGeometricIntersection(Circle1,Circle2,TolConf,Tol,C1_Int1,C1_Int2,nbsol);
715 if(nbsol==0) { //-- Pas de solutions
719 PeriodicInterval C1Domain(DomainCirc1);
720 //-- On se ramene entre 0 et 2PI
721 Standard_Real deltat = C1Domain.Bsup-C1Domain.Binf;
722 if(deltat>=PIpPI) { deltat=PIpPI-1e-14; }
724 while(C1Domain.Binf >= PIpPI)
725 C1Domain.Binf-=PIpPI;
726 while(C1Domain.Binf < 0.0)
727 C1Domain.Binf+=PIpPI;
729 C1Domain.Bsup=C1Domain.Binf+deltat;
731 PeriodicInterval C2Domain(DomainCirc2);
732 deltat = C2Domain.Bsup-C2Domain.Binf;
738 while(C2Domain.Binf >= PIpPI)
739 C2Domain.Binf-=PIpPI;
740 while(C2Domain.Binf < 0.0)
741 C2Domain.Binf+=PIpPI;
743 C2Domain.Bsup=C2Domain.Binf+deltat;
745 Standard_Boolean IdentCircles=Standard_False;
749 //-- Les 2 cercles sont confondus a Tol pres
750 C1_Int1.SetValues(0,PIpPI);
752 //---------------------------------------------------------------
753 //-- Flag utilise pour specifier que les intervalles manipules
754 //-- peuvent etre de longueur superieure a pi.
755 //-- Pour des cercles non identiques, on a necessairement cette
756 //-- condition sur les resultats de l intersection geometrique
757 //-- ce qui permet de normaliser rapidement les intervalles.
758 //-- ex: -1 4 -> longueur > PI
759 //-- donc -1 4 devient 4 , 2*pi-1
760 //---------------------------------------------------------------
761 IdentCircles=Standard_True;
764 Standard_Integer NbSolTotal=0;
765 PeriodicInterval SolutionC1[4];
766 PeriodicInterval SolutionC2[4];
768 //----------------------------------------------------------------------
769 //----------- Traitement du premier intervalle Geometrique C1_Int1 ----
770 //----------------------------------------------------------------------
771 //-- NbSolTotal est incremente a chaque Intervalle solution.
772 //-- On stocke les intervalles dans les tableaux : SolutionC1(C2)
773 //-- Dimensionnes a 4 elements.
774 //-- des Exemples faciles donnent 3 Intersections
775 //-- des Problemes numeriques peuvent en donner 4 ??????
777 PeriodicInterval C1DomainAndRes=C1Domain.FirstIntersection(C1_Int1);
779 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
782 ,SolutionC1,SolutionC2
785 //----------------------------------------------------------------------
786 //-- Seconde Intersection : Par exemple : 2*PI-1 2*PI+1
787 //-- Intersecte avec 0.5 2*PI-0.5
788 //-- Donne les intervalles : 0.5,1 et 2*PI-1,2*PI-0.5
790 C1DomainAndRes=C1Domain.SecondIntersection(C1_Int1);
792 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
795 ,SolutionC1,SolutionC2
799 //----------------------------------------------------------------------
800 //----------- Traitement du second intervalle Geometrique C1_Int2 ----
801 //----------------------------------------------------------------------
804 C1DomainAndRes=C1Domain.FirstIntersection(C1_Int2);
806 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
809 ,SolutionC1,SolutionC2
812 //--------------------------------------------------------------------
813 C1DomainAndRes=C1Domain.SecondIntersection(C1_Int2);
815 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
818 ,SolutionC1,SolutionC2
822 //----------------------------------------------------------------------
823 //-- Calcul de toutes les transitions et Positions.
825 //----------------------------------------------------------------------
826 //-- On determine si des intervalles sont reduit a des points
827 //-- ( Rayon * Intervalle.Length() < Tol )
829 Standard_Real R1=Circle1.Radius();
830 Standard_Real R2=Circle2.Radius();
831 Standard_Real Tol2=Tol+Tol; //---- Pour eviter de toujours retourner
837 for( i=0; i<NbSolTotal ; i++)
839 if(((R1 * SolutionC1[i].Length()) <=Tol2) &&
840 ((R2 * SolutionC2[i].Length())<=Tol2))
842 Standard_Real t=(SolutionC1[i].Binf+SolutionC1[i].Bsup)*0.5;
843 SolutionC1[i].Binf=SolutionC1[i].Bsup=t;
845 t=(SolutionC2[i].Binf+SolutionC2[i].Bsup)*0.5;
846 SolutionC2[i].Binf=SolutionC2[i].Bsup=t;
850 //----------------------------------------------------------------------
851 //-- Traitement des intervalles (ou des points obtenus)
853 gp_Ax22d Axis2C1=Circle1.Axis();
854 gp_Ax22d Axis2C2=Circle2.Axis();
855 gp_Pnt2d P1a,P1b,P2a,P2b;
856 gp_Vec2d Tan1,Tan2,Norm1,Norm2;
857 IntRes2d_Transition T1a,T1b,T2a,T2b;
858 IntRes2d_Position Pos1a,Pos1b,Pos2a,Pos2b;
860 Standard_Boolean Opposite =
861 ((Circle1.Location().SquareDistance(Circle2.Location())) > (R1*R1+R2*R2)) ?
862 Standard_True : Standard_False;
864 //if(Circle1.IsDirect()) { cout<<" C1 Direct"<<endl; } else { cout<<" C1 INDirect"<<endl; }
865 //if(Circle2.IsDirect()) { cout<<" C2 Direct"<<endl; } else { cout<<" C2 INDirect"<<endl; }
867 for(i=0; i<NbSolTotal; i++)
869 Standard_Real C2inf=(Opposite)? SolutionC2[i].Bsup : SolutionC2[i].Binf;
870 Standard_Real C2sup=(Opposite)? SolutionC2[i].Binf : SolutionC2[i].Bsup;
871 Standard_Real C1tinf = SolutionC1[i].Binf, C2tinf = C2inf;
872 Standard_Real C1inf=NormalizeOnCircleDomain(C1tinf,DomainCirc1);
873 C2inf=NormalizeOnCircleDomain(C2tinf,DomainCirc2);
875 Standard_Boolean isOutOfRange = Standard_False;
876 if(C1inf < DomainCirc1.FirstParameter())
878 if(C1tinf < DomainCirc1.FirstParameter())
880 C1inf = DomainCirc1.FirstParameter();
881 isOutOfRange = Standard_True;
889 if(C1inf > DomainCirc1.LastParameter())
891 if(C1tinf > DomainCirc1.LastParameter())
893 C1inf = DomainCirc1.LastParameter();
894 isOutOfRange = Standard_True;
902 if(C2inf < DomainCirc2.FirstParameter())
904 if(C2tinf < DomainCirc2.FirstParameter())
906 C2inf = DomainCirc2.FirstParameter();
907 isOutOfRange = Standard_True;
915 if(C2inf > DomainCirc2.LastParameter())
917 if(C2tinf > DomainCirc2.LastParameter())
919 C2inf = DomainCirc2.LastParameter();
920 isOutOfRange = Standard_True;
934 ElCLib::CircleD2(C1inf,Axis2C1,R1,aP1,aV11,aV12);
935 ElCLib::CircleD2(C2inf,Axis2C2,R2,aP2,aV21,aV22);
937 if(aP1.SquareDistance(aP2) > Tol2*Tol2)
938 {//there are not any solutions in given parametric range.
945 ElCLib::CircleD2(C1inf,Axis2C1,R1,P1a,Tan1,Norm1);
946 ElCLib::CircleD2(C2inf,Axis2C2,R2,P2a,Tan2,Norm2);
949 IntImpParGen::DeterminePosition(Pos1a,DomainCirc1,P1a,C1inf);
950 IntImpParGen::DeterminePosition(Pos2a,_DomainCirc2,P2a,PIpPI-C2inf);
951 Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
954 IntRes2d_IntersectionPoint NewPoint1(P1a,C1inf,PIpPI-C2inf,T1a,T2a,Standard_False);
956 if((SolutionC1[i].Length()>0.0 ) || (SolutionC2[i].Length() >0.0))
958 //-- On traite un intervalle non reduit a un point
959 Standard_Real C1sup=NormalizeOnCircleDomain(SolutionC1[i].Bsup,DomainCirc1);
960 if(C1sup<C1inf) C1sup+=PIpPI;
961 C2sup=NormalizeOnCircleDomain(C2sup,DomainCirc2);
963 ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1);
964 ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
967 IntImpParGen::DeterminePosition(Pos1b,DomainCirc1,P1b,C1sup);
968 IntImpParGen::DeterminePosition(Pos2b,_DomainCirc2,P2b,PIpPI-C2sup);
969 Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
971 //--------------------------------------------------
985 if(C2sup<C2inf) C2sup+=PIpPI;
989 IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,PIpPI-C2sup,T1b,T2b,Standard_False);
990 IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2,
991 (Opposite==Standard_True)? Standard_False : Standard_True,
1002 ElCLib::CircleD2(C1inf,Axis2C1,R1,P1a,Tan1,Norm1);
1003 ElCLib::CircleD2(C2inf,Axis2C2,R2,P2a,Tan2,Norm2);
1005 IntImpParGen::DeterminePosition(Pos1a,DomainCirc1,P1a,C1inf);
1006 IntImpParGen::DeterminePosition(Pos2a,DomainCirc2,P2a,C2inf);
1007 Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
1010 IntRes2d_IntersectionPoint NewPoint1(P1a,C1inf,C2inf,T1a,T2a,Standard_False);
1012 if((SolutionC1[i].Length()>0.0 ) || (SolutionC2[i].Length() >0.0))
1014 //-- On traite un intervalle non reduit a un point
1015 Standard_Real C1sup=NormalizeOnCircleDomain(SolutionC1[i].Bsup,DomainCirc1);
1016 if(C1sup<C1inf) C1sup+=PIpPI;
1017 C2sup=NormalizeOnCircleDomain(C2sup,DomainCirc2);
1019 ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1);
1020 ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
1022 IntImpParGen::DeterminePosition(Pos1b,DomainCirc1,P1b,C1sup);
1023 IntImpParGen::DeterminePosition(Pos2b,DomainCirc2,P2b,C2sup);
1024 Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
1026 //--------------------------------------------------
1045 IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,C2sup,T1b,T2b,Standard_False);
1046 IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2,Opposite,Standard_False);
1056 //----------------------------------------------------------------------
1057 IntRes2d_Position FindPositionLL(Standard_Real &Param
1058 ,const IntRes2d_Domain& Domain)
1060 Standard_Real aDPar = Precision::Infinite();
1061 IntRes2d_Position aPos = IntRes2d_Middle;
1062 Standard_Real aResPar = Param;
1063 if(Domain.HasFirstPoint()) {
1064 aDPar = Abs(Param-Domain.FirstParameter());
1065 if( aDPar <= Domain.FirstTolerance()) {
1066 aResPar=Domain.FirstParameter();
1067 aPos = IntRes2d_Head;
1071 if(Domain.HasLastPoint()) {
1072 Standard_Real aD2 = Abs(Param-Domain.LastParameter());
1073 if( aD2 <= Domain.LastTolerance() && (aPos == IntRes2d_Middle || aD2 < aDPar ))
1075 aResPar=Domain.LastParameter();
1076 aPos = IntRes2d_End;
1082 //--------------------------------------------------------------------
1084 // Method to compute of point of intersection for case
1085 //when specified domain less than specified tolerance for intersection
1086 static inline void getDomainParametrs(const IntRes2d_Domain& theDomain,
1087 Standard_Real& theFirst,
1088 Standard_Real& theLast,
1089 Standard_Real& theTol1,
1090 Standard_Real& theTol2)
1092 theFirst = (theDomain.HasFirstPoint() ? theDomain.FirstParameter() : -Precision::Infinite());
1093 theLast = (theDomain.HasLastPoint() ? theDomain.LastParameter() : Precision::Infinite());
1094 theTol1 = (theDomain.HasFirstPoint() ? theDomain.FirstTolerance() : 0.);
1095 theTol2 = (theDomain.HasLastPoint() ? theDomain.LastTolerance() : 0.);
1099 //=======================================================================
1100 //function : computeIntPoint
1102 //=======================================================================
1103 static Standard_Boolean computeIntPoint(const IntRes2d_Domain& theCurDomain,
1104 const IntRes2d_Domain& theDomainOther,
1105 const gp_Lin2d& theCurLin,
1106 const gp_Lin2d& theOtherLin,
1107 Standard_Real theCosT1T2,
1108 Standard_Real theParCur, Standard_Real theParOther,
1109 Standard_Real& theResInf, Standard_Real& theResSup,
1110 Standard_Integer theNum,
1111 IntRes2d_TypeTrans theCurTrans,
1112 IntRes2d_IntersectionPoint& theNewPoint)
1114 if(fabs(theResSup-theParCur) > fabs(theResInf-theParCur))
1115 theResSup = theResInf;
1117 Standard_Real aRes2 = theParOther + (theResSup - theParCur) * theCosT1T2;
1119 Standard_Real aFirst2, aLast2, aTol21, aTol22, aTol11, aTol12 ;
1121 getDomainParametrs(theDomainOther,aFirst2, aLast2, aTol21, aTol22);
1123 if( aRes2 < aFirst2 - aTol21 || aRes2 > aLast2 + aTol22 ) {
1124 return Standard_False;
1127 //------ compute parameters of intersection point --
1128 IntRes2d_Transition aT1,aT2;
1129 IntRes2d_Position aPos1a = FindPositionLL(theResSup,theCurDomain);
1130 IntRes2d_Position aPos2a = FindPositionLL(aRes2,theDomainOther);
1131 IntRes2d_TypeTrans anOtherTrans = ( theCurTrans == IntRes2d_Out ?
1132 IntRes2d_In : ( theCurTrans == IntRes2d_In ? IntRes2d_Out : IntRes2d_Undecided ) );
1134 if( theCurTrans != IntRes2d_Undecided )
1136 aT1.SetValue(Standard_False, aPos1a, theCurTrans);
1137 aT2.SetValue(Standard_False, aPos2a, anOtherTrans);
1141 Standard_Boolean anOpposite = theCosT1T2 < 0.;
1142 aT1.SetValue(Standard_False,aPos1a,IntRes2d_Unknown,anOpposite);
1143 aT2.SetValue(Standard_False,aPos2a,IntRes2d_Unknown,anOpposite);
1145 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1146 //--------------------------------------------------
1148 Standard_Real aResU1 = theParCur;
1149 Standard_Real aResU2 = theParOther;
1151 Standard_Real aFirst1, aLast1;
1152 getDomainParametrs(theCurDomain,aFirst1, aLast1, aTol11, aTol12);
1154 Standard_Boolean isInside1 = (theParCur >= aFirst1 && theParCur <= aLast1);
1155 Standard_Boolean isInside2 = (theParOther >= aFirst2 && theParOther <= aLast2);
1157 if(!isInside1 || !isInside2)
1161 gp_Pnt2d Pt1=ElCLib::Value(aRes2,theOtherLin);
1163 Standard_Real aPar1 = ElCLib::Parameter(theCurLin,Pt1);
1164 aResU1 =((aPar1 >= aFirst1 && aPar1<= aLast1) ? aPar1 : theResSup);
1169 gp_Pnt2d aPt1=ElCLib::Value(theResSup,theCurLin);
1171 Standard_Real aPar2 = ElCLib::Parameter(theOtherLin,aPt1);
1172 aResU2= ((aPar2 >= aFirst2 && aPar2<= aLast2) ? aPar2 : aRes2);
1177 // check that parameters are within range on both curves
1178 if ( theParCur < aFirst1-aTol11 || theParCur > aLast1+aTol12 ||
1179 theParOther < aFirst2-aTol21 || theParOther > aLast2+aTol22) {
1180 return Standard_False;
1187 gp_Pnt2d aPres((ElCLib::Value(aResU1,theCurLin).XY() + ElCLib::Value(aResU2,theOtherLin).XY()) * 0.5 );
1189 theNewPoint.SetValues(aPres, aResU1, aResU2 ,aT1, aT2, Standard_False);
1191 theNewPoint.SetValues(aPres, aResU2, aResU1 ,aT2, aT1, Standard_False);
1192 return Standard_True;
1195 //----------------------------------------------------------------------
1196 void IntCurve_IntConicConic::Perform(const gp_Lin2d& L1
1197 ,const IntRes2d_Domain& Domain1
1199 ,const IntRes2d_Domain& Domain2
1200 ,const Standard_Real,const Standard_Real TolR) {
1201 this->ResetFields();
1203 //-- Coordonnees du point d intersection sur chacune des 2 droites
1204 Standard_Real U1,U2;
1205 //-- Nombre de points solution : 1 : Intersection
1206 //-- 0 : Non Confondues
1207 //-- 2 : Confondues a la tolerance pres
1208 Standard_Integer nbsol;
1209 IntRes2d_IntersectionPoint PtSeg1,PtSeg2;
1210 Standard_Real SINL1L2;
1211 Standard_Real Tol = TolR;
1212 if(TolR< 1e-10) Tol = 1e-10;
1215 LineLineGeometricIntersection(L1,L2,Tol,U1,U2,SINL1L2,nbsol);
1217 gp_Vec2d Tan1=L1.Direction();
1218 gp_Vec2d Tan2=L2.Direction();
1220 Standard_Real aCosT1T2 = Tan1.Dot(Tan2);
1221 Standard_Boolean Opposite=(aCosT1T2 < 0.0)? Standard_True : Standard_False;
1226 //---------------------------------------------------
1227 //-- d: distance du point I a partir de laquelle les
1228 //-- points de parametre U1+d et U2+-d sont ecartes
1229 //-- d une distance superieure a Tol.
1230 //---------------------------------------------------
1231 IntRes2d_Position Pos1a,Pos2a,Pos1b,Pos2b;
1232 Standard_Real d=Tol/(SINL1L2);
1233 Standard_Real U1inf=U1-d;
1234 Standard_Real U1sup=U1+d;
1235 Standard_Real U1mU2=U1-U2;
1236 Standard_Real U1pU2=U1+U2;
1237 Standard_Real Res1inf,Res1sup;
1238 Standard_Real ProdVectTan;
1241 //---------------------------------------------------
1242 //-- On agrandit la zone U1inf U1sup pour tenir compte
1243 //-- des tolerances des points en bout
1245 if(Domain1.HasFirstPoint()) {
1246 if(L2.Distance(Domain1.FirstPoint()) < Domain1.FirstTolerance()) {
1247 if(U1inf > Domain1.FirstParameter()) {
1248 U1inf = Domain1.FirstParameter();
1250 if(U1sup < Domain1.FirstParameter()) {
1251 U1sup = Domain1.FirstParameter();
1255 if(Domain1.HasLastPoint()) {
1256 if(L2.Distance(Domain1.LastPoint()) < Domain1.LastTolerance()) {
1257 if(U1inf > Domain1.LastParameter()) {
1258 U1inf = Domain1.LastParameter();
1260 if(U1sup < Domain1.LastParameter()) {
1261 U1sup = Domain1.LastParameter();
1265 if(Domain2.HasFirstPoint()) {
1266 if(L1.Distance(Domain2.FirstPoint()) < Domain2.FirstTolerance()) {
1267 Standard_Real p = ElCLib::Parameter(L1,Domain2.FirstPoint());
1276 if(Domain2.HasLastPoint()) {
1277 if(L1.Distance(Domain2.LastPoint()) < Domain2.LastTolerance()) {
1278 Standard_Real p = ElCLib::Parameter(L1,Domain2.LastPoint());
1287 //-----------------------------------------------------------------
1289 DomainIntersection(Domain1,U1inf,U1sup,Res1inf,Res1sup,Pos1a,Pos1b);
1291 if((Res1sup-Res1inf)<0.0) {
1292 //-- Si l intersection est vide
1295 else { //-- (Domain1 INTER Zone Intersection) non vide
1297 ProdVectTan=Tan1.Crossed(Tan2);
1299 //#####################################################################
1300 //## Longueur Minimale d un segment Sur Courbe 1
1301 //#####################################################################
1303 Standard_Real LongMiniSeg=Tol;
1306 if(((Res1sup-Res1inf)<=LongMiniSeg)
1307 || ((Pos1a==Pos1b)&&(Pos1a!=IntRes2d_Middle)))
1309 //------------------------------- Un seul Point -------------------
1310 //--- lorsque la longueur du segment est inferieure a ??
1311 //--- ou si deux points designent le meme bout
1313 IntRes2d_TypeTrans aCurTrans = ( ProdVectTan >= TOLERANCE_ANGULAIRE ?
1314 IntRes2d_Out : ( ProdVectTan <= -TOLERANCE_ANGULAIRE ? IntRes2d_In : IntRes2d_Undecided ) );
1316 IntRes2d_IntersectionPoint NewPoint1;
1317 if( computeIntPoint(Domain1, Domain2, L1, L2, aCosT1T2, U1, U2, Res1inf, Res1sup, 1, aCurTrans, NewPoint1 ) )
1320 //------------------------------------------------------
1323 } //--------------- Fin du cas : 1 seul point --------------------
1326 //-- Intersection AND Domain1 --------> Segment ---------------------
1327 Standard_Real U2inf,U2sup;
1328 Standard_Real Res2inf,Res2sup;
1330 if(Opposite) { U2inf = U1pU2 -Res1sup; U2sup= U1pU2-Res1inf; }
1331 else { U2inf = Res1inf-U1mU2; U2sup= Res1sup-U1mU2; }
1333 DomainIntersection(Domain2,U2inf,U2sup,Res2inf,Res2sup,Pos2a,Pos2b);
1335 //####################################################################
1336 //## Test sur la longueur minimale d un segment sur Ligne2
1337 //####################################################################
1338 Standard_Real Res2sup_m_Res2inf = Res2sup-Res2inf;
1339 if(Res2sup_m_Res2inf < 0.0) {
1340 //-- Pas de solutions On retourne Vide
1342 else if(((Res2sup-Res2inf) > LongMiniSeg)
1343 || ((Pos2a==Pos2b)&&(Pos2a!=IntRes2d_Middle))) {
1344 //----------- Calcul des attributs du segment --------------
1345 //-- Attention, les bornes Res1inf(sup) bougent donc il faut
1346 //-- eventuellement recalculer les attributs
1348 if(Opposite) { Res1inf=U1pU2-Res2sup; Res1sup=U1pU2-Res2inf;
1349 Standard_Real Tampon=Res2inf; Res2inf=Res2sup; Res2sup=Tampon;
1350 IntRes2d_Position Pos=Pos2a; Pos2a=Pos2b; Pos2b=Pos;
1352 else { Res1inf=U1mU2+Res2inf; Res1sup=U1mU2+Res2sup; }
1354 Pos1a=FindPositionLL(Res1inf,Domain1);
1355 Pos1b=FindPositionLL(Res1sup,Domain1);
1357 IntRes2d_Transition T1a,T2a,T1b,T2b;
1359 if(ProdVectTan>=TOLERANCE_ANGULAIRE) { // &&&&&&&&&&&&&&&
1360 T1a.SetValue(Standard_False,Pos1a,IntRes2d_Out);
1361 T2a.SetValue(Standard_False,Pos2a,IntRes2d_In);
1363 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1364 T1a.SetValue(Standard_False,Pos1a,IntRes2d_In);
1365 T2a.SetValue(Standard_False,Pos2a,IntRes2d_Out);
1368 T1a.SetValue(Standard_False,Pos1a,IntRes2d_Unknown,Opposite);
1369 T2a.SetValue(Standard_False,Pos2a,IntRes2d_Unknown,Opposite);
1373 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1374 //~~~~~~~ C O N V E N T I O N - S E G M E N T ~~~~~~~
1375 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1376 //~~ On Renvoie un segment dans les cas suivants : ~~
1377 //~~ (1) Extremite L1 L2 ------> Extremite L1 L2 ~~
1378 //~~ (2) Extremite L1 L2 ------> Intersection ~~
1379 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1381 Standard_Boolean ResultIsAPoint=Standard_False;
1383 if(((Res1sup-Res1inf)<=LongMiniSeg)
1384 || (Abs(Res2sup-Res2inf)<=LongMiniSeg)) {
1385 //-- On force la creation d un point
1386 ResultIsAPoint=Standard_True;
1389 //------------------------------------------------------------
1390 //-- On traite les cas ou l intersection est situee du
1391 //-- Mauvais cote du domaine
1392 //-- Attention : Res2inf <-> Pos2a Res2sup <-> Pos2b
1393 //-- et Res1inf <-> Pos1a Res1sup <-> Pos1b
1394 //-- avec Res1inf <= Res1sup
1395 //------------------------------------------------------------
1396 //-- Le point sera : Res1inf,Res2inf,T1a(Pos1a),T2a(Pos2a)
1397 //------------------------------------------------------------
1399 if(Pos1a==IntRes2d_Head) {
1400 if(Pos1b!=IntRes2d_End && U1<Res1inf) { ResultIsAPoint=Standard_True; U1=Res1inf; U2=Res2inf; }
1402 if(Pos1b==IntRes2d_End) {
1403 if(Pos1a!=IntRes2d_Head && U1>Res1sup) { ResultIsAPoint=Standard_True; U1=Res1sup; U2=Res2sup; }
1406 if(Pos2a==IntRes2d_Head) {
1407 if(Pos2b!=IntRes2d_End && U2<Res2inf) { ResultIsAPoint=Standard_True; U2=Res2inf; U1=Res1inf; }
1410 if(Pos2a==IntRes2d_End) {
1411 if(Pos2b!=IntRes2d_Head && U2>Res2inf) { ResultIsAPoint=Standard_True; U2=Res2inf; U1=Res1inf; }
1414 if(Pos2b==IntRes2d_Head) {
1415 if(Pos2a!=IntRes2d_End && U2<Res2sup) { ResultIsAPoint=Standard_True; U2=Res2sup; U1=Res1sup; }
1418 if(Pos2b==IntRes2d_End) {
1419 if(Pos2a!=IntRes2d_Head && U2>Res2sup) { ResultIsAPoint=Standard_True; U2=Res2sup; U1=Res1sup; }
1426 if((!ResultIsAPoint) && (Pos1a!=IntRes2d_Middle || Pos2a!=IntRes2d_Middle)) {
1427 IntRes2d_Transition T1b,T2b;
1428 if(ProdVectTan>=TOLERANCE_ANGULAIRE) { //&&&&&&&&&&&&&&
1429 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1430 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1432 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) { //&&&&&&&&&&&&&&
1433 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1434 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1437 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1438 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1441 if(Pos1a==IntRes2d_Middle) {
1444 t3 = (Pos2a == IntRes2d_Head)? Res2sup : Res2inf;
1447 t3 = (Pos2a == IntRes2d_Head)? Res2inf : Res2sup;
1449 Ptdebut=ElCLib::Value(t3,L2);
1450 Res1inf=ElCLib::Parameter(L1,Ptdebut);
1453 Standard_Real t4 = (Pos1a == IntRes2d_Head)? Res1inf : Res1sup;
1454 Ptdebut=ElCLib::Value(t4,L1);
1455 Res2inf=ElCLib::Parameter(L2,Ptdebut);
1457 PtSeg1.SetValues(Ptdebut,Res1inf,Res2inf,T1a,T2a,Standard_False);
1458 if(Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle) {
1459 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1460 //~~ Ajustement des parametres et du point renvoye
1462 if(Pos1b==IntRes2d_Middle) {
1463 Ptfin=ElCLib::Value(Res2sup,L2);
1464 Res1sup=ElCLib::Parameter(L1,Ptfin);
1467 Ptfin=ElCLib::Value(Res1sup,L1);
1468 Res2sup=ElCLib::Parameter(L2,Ptfin);
1470 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1471 IntRes2d_IntersectionSegment Segment(PtSeg1,PtSeg2
1472 ,Opposite,Standard_False);
1475 else { //-- Extremite(L1 ou L2) ------> Point Middle(L1 et L2)
1477 Pos1b=FindPositionLL(U1,Domain1);
1478 Pos2b=FindPositionLL(U2,Domain2);
1479 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1480 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1481 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1483 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1484 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1485 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1488 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1489 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1492 PtSeg2.SetValues(ElCLib::Value(U2,L2),U1,U2,T1b,T2b,Standard_False);
1494 if((Abs(Res1inf-U1) >LongMiniSeg) && (Abs(Res2inf-U2) >LongMiniSeg)) {
1495 IntRes2d_IntersectionSegment Segment(PtSeg1,PtSeg2,Opposite,Standard_False);
1499 Append(SegmentToPoint(PtSeg1,T1a,T2a,PtSeg2,T1b,T2b));
1503 } //-- (Pos1a!=IntRes2d_Middle || Pos2a!=IntRes2d_Middle) --
1504 else { //-- Pos1a == Pos2a == Middle
1505 if(Pos1b==IntRes2d_Middle) Pos1b=Pos1a;
1506 if(Pos2b==IntRes2d_Middle) Pos2b=Pos2a;
1507 if(ResultIsAPoint) {
1508 //-- Middle sur le segment A
1510 if(Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle) {
1512 if(Pos1b==IntRes2d_Middle) {
1515 t2 = (Pos2b == IntRes2d_Head)? Res2sup : Res2inf;
1518 t2 = (Pos2b == IntRes2d_Head)? Res2inf : Res2sup;
1520 Ptfin=ElCLib::Value(t2,L2);
1521 Res1sup=ElCLib::Parameter(L1,Ptfin);
1522 //modified by NIZHNY-MKK Tue Feb 15 10:54:51 2000.BEGIN
1523 Pos1b=FindPositionLL(Res1sup,Domain1);
1524 //modified by NIZHNY-MKK Tue Feb 15 10:54:55 2000.END
1528 Standard_Real t1 = (Pos1b == IntRes2d_Head)? Res1inf : Res1sup;
1529 Ptfin=ElCLib::Value(t1,L1);
1530 Res2sup=ElCLib::Parameter(L2,Ptfin);
1531 //modified by NIZHNY-MKK Tue Feb 15 10:55:08 2000.BEGIN
1532 Pos2b=FindPositionLL(Res2sup,Domain2);
1533 //modified by NIZHNY-MKK Tue Feb 15 10:55:11 2000.END
1535 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1536 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1537 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1539 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1540 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1541 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1544 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1545 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1547 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1551 Pos1b=FindPositionLL(U1,Domain1);
1552 Pos2b=FindPositionLL(U2,Domain2);
1554 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1555 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1556 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1558 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1559 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1560 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1563 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1564 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1566 PtSeg1.SetValues(ElCLib::Value(U2,L2),U1,U2,T1b,T2b,Standard_False);
1571 PtSeg1.SetValues(ElCLib::Value(U2,L2),U1,U2,T1a,T2a,Standard_False);
1573 if((Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle)) {
1574 IntRes2d_Transition T1b,T2b;
1575 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1576 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1577 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1579 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1580 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1581 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1584 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1585 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1587 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1588 //~~ Ajustement des parametres et du point renvoye
1590 if(Pos1b==IntRes2d_Middle) {
1591 Ptfin=ElCLib::Value(Res2sup,L2);
1592 Res1sup=ElCLib::Parameter(L1,Ptfin);
1595 Ptfin=ElCLib::Value(Res1sup,L1);
1596 Res2sup=ElCLib::Parameter(L2,Ptfin);
1599 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1601 if((Abs(U1-Res1sup)>LongMiniSeg)
1602 ||(Abs(U2-Res2sup)>LongMiniSeg)) {
1603 //-- Modif du 1er Octobre 92 (Pour Composites)
1605 IntRes2d_IntersectionSegment Segment(PtSeg1,PtSeg2
1606 ,Opposite,Standard_False);
1610 Append(SegmentToPoint(PtSeg1,T1a,T2a,PtSeg2,T1b,T2b));
1618 } //----- Fin Creation Segment ----(Res2sup-Res2inf>Tol)-------------
1620 //------ (Intersection And Domain1) AND Domain2 --> Point ------
1621 //-- Attention Res1sup peut etre different de U2
1622 //-- Mais on a Res1sup-Res1inf < Tol
1625 IntRes2d_TypeTrans aCurTrans = ( ProdVectTan >= TOLERANCE_ANGULAIRE ?
1626 IntRes2d_In : ( ProdVectTan <= -TOLERANCE_ANGULAIRE ? IntRes2d_Out : IntRes2d_Undecided ) );
1628 IntRes2d_IntersectionPoint NewPoint1;
1629 if( computeIntPoint(Domain2, Domain1, L2, L1, aCosT1T2, U2, U1, Res2inf, Res2sup, 2, aCurTrans, NewPoint1 ) )
1637 if(nbsol==2) { //== Droites confondues a la tolerance pres
1638 //--On traite ici le cas de segments resultats non neccess. bornes
1640 //--On prend la droite D1 comme reference ( pour le sens positif )
1642 Standard_Integer ResHasFirstPoint=0;
1643 Standard_Integer ResHasLastPoint=0;
1644 Standard_Real ParamStart = 0.,ParamStart2,ParamEnd = 0.,ParamEnd2;
1645 Standard_Real Org2SurL1=ElCLib::Parameter(L1,L2.Location());
1646 //== 3 : L1 et L2 bornent
1649 if(Domain1.HasFirstPoint()) ResHasFirstPoint=1;
1650 if(Domain1.HasLastPoint()) ResHasLastPoint=1;
1652 if(Domain2.HasLastPoint()) ResHasFirstPoint+=2;
1653 if(Domain2.HasFirstPoint()) ResHasLastPoint+=2;
1656 if(Domain2.HasLastPoint()) ResHasLastPoint+=2;
1657 if(Domain2.HasFirstPoint()) ResHasFirstPoint+=2;
1659 if(ResHasFirstPoint==0 && ResHasLastPoint==0) {
1660 //~~~~ Creation d un segment infini avec Opposite
1661 Append(IntRes2d_IntersectionSegment(Opposite));
1663 else { //-- On obtient au pire une demi-droite
1664 switch(ResHasFirstPoint) {
1666 ParamStart=Domain1.FirstParameter();
1667 ParamStart2=(Opposite)? (Org2SurL1-ParamStart)
1668 :(ParamStart-Org2SurL1);
1672 ParamStart2=Domain2.LastParameter();
1673 ParamStart=Org2SurL1 - ParamStart2;
1676 ParamStart2=Domain2.FirstParameter();
1677 ParamStart=Org2SurL1 + ParamStart2;
1682 ParamStart2=Domain2.LastParameter();
1683 ParamStart=Org2SurL1 - ParamStart2;
1684 if(ParamStart < Domain1.FirstParameter()) {
1685 ParamStart=Domain1.FirstParameter();
1686 ParamStart2=Org2SurL1 - ParamStart;
1690 ParamStart2=Domain2.FirstParameter();
1691 ParamStart=Org2SurL1 + ParamStart2;
1692 if(ParamStart < Domain1.FirstParameter()) {
1693 ParamStart=Domain1.FirstParameter();
1694 ParamStart2=ParamStart - Org2SurL1;
1698 default: //~~~ Segment Infini a gauche
1702 switch(ResHasLastPoint) {
1704 ParamEnd=Domain1.LastParameter();
1705 ParamEnd2=(Opposite)? (Org2SurL1-ParamEnd)
1706 :(ParamEnd-Org2SurL1);
1710 ParamEnd2=Domain2.FirstParameter();
1711 ParamEnd=Org2SurL1 - ParamEnd2;
1714 ParamEnd2=Domain2.LastParameter();
1715 ParamEnd=Org2SurL1 + ParamEnd2;
1720 ParamEnd2=Domain2.FirstParameter();
1721 ParamEnd=Org2SurL1 - ParamEnd2;
1722 if(ParamEnd > Domain1.LastParameter()) {
1723 ParamEnd=Domain1.LastParameter();
1724 ParamEnd2=Org2SurL1 - ParamEnd;
1728 ParamEnd2=Domain2.LastParameter();
1729 ParamEnd=Org2SurL1 + ParamEnd2;
1730 if(ParamEnd > Domain1.LastParameter()) {
1731 ParamEnd=Domain1.LastParameter();
1732 ParamEnd2=ParamEnd - Org2SurL1;
1735 default: //~~~ Segment Infini a droite
1739 IntRes2d_Transition Tinf,Tsup;
1741 if(ResHasFirstPoint) {
1742 if(ResHasLastPoint) {
1743 //~~~ Creation de la borne superieure
1744 //~~~ L1 : |-------------> ou |-------------->
1745 //~~~ L2 : <------------| ou <----|
1746 if(ParamEnd >= (ParamStart-Tol)) {
1747 //~~~ Creation d un segment
1748 IntRes2d_Position Pos1,Pos2;
1749 Pos1=FindPositionLL(ParamStart,Domain1);
1750 Pos2=FindPositionLL(ParamStart2,Domain2);
1751 Tinf.SetValue(Standard_True,Pos1,IntRes2d_Unknown,Opposite);
1752 Tsup.SetValue(Standard_True,Pos2,IntRes2d_Unknown,Opposite);
1753 IntRes2d_IntersectionPoint P1(ElCLib::Value(ParamStart,L1)
1754 ,ParamStart,ParamStart2
1755 ,Tinf,Tsup,Standard_False);
1756 if(ParamEnd > (ParamStart+Tol)) {
1757 //~~~ Le segment est assez long
1758 Pos1=FindPositionLL(ParamEnd,Domain1);
1759 Pos2=FindPositionLL(ParamEnd2,Domain2);
1760 Tinf.SetValue(Standard_True,Pos1,IntRes2d_Unknown,Opposite);
1761 Tsup.SetValue(Standard_True,Pos2,IntRes2d_Unknown,Opposite);
1763 IntRes2d_IntersectionPoint P2(ElCLib::Value(ParamEnd,L1)
1765 ,Tinf,Tsup,Standard_False);
1766 IntRes2d_IntersectionSegment Seg(P1,P2,Opposite,Standard_False);
1769 else { //~~~~ le segment est de longueur inferieure a Tol
1772 } //-- if( ParamEnd >= ...)
1773 } //-- if(ResHasLastPoint)
1775 //~~~ Creation de la demi droite |----------->
1776 IntRes2d_Position Pos1=FindPositionLL(ParamStart,Domain1);
1777 IntRes2d_Position Pos2=FindPositionLL(ParamStart2,Domain2);
1778 Tinf.SetValue(Standard_True,Pos1,IntRes2d_Unknown,Opposite);
1779 Tsup.SetValue(Standard_True,Pos2,IntRes2d_Unknown,Opposite);
1781 IntRes2d_IntersectionPoint P(ElCLib::Value(ParamStart,L1)
1782 ,ParamStart,ParamStart2
1783 ,Tinf,Tsup,Standard_False);
1784 IntRes2d_IntersectionSegment Seg(P,Standard_True,Opposite,Standard_False);
1789 IntRes2d_Position Pos1=FindPositionLL(ParamEnd,Domain1);
1790 IntRes2d_Position Pos2=FindPositionLL(ParamEnd2,Domain2);
1791 Tinf.SetValue(Standard_True,Pos1,IntRes2d_Unknown,Opposite);
1792 Tsup.SetValue(Standard_True,Pos2,IntRes2d_Unknown,Opposite);
1794 IntRes2d_IntersectionPoint P2(ElCLib::Value(ParamEnd,L1)
1796 ,Tinf,Tsup,Standard_False);
1797 IntRes2d_IntersectionSegment Seg(P2,Standard_False,Opposite,Standard_False);
1799 //~~~ Creation de la demi droite <-----------|
1807 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1808 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1809 void IntCurve_IntConicConic::Perform(const gp_Lin2d& Line
1810 ,const IntRes2d_Domain& LIG_Domain
1811 ,const gp_Circ2d& Circle
1812 ,const IntRes2d_Domain& CIRC_Domain
1813 ,const Standard_Real TolConf,const Standard_Real Tol) {
1815 //-- if(! CIRC_Domain.IsClosed()) {
1816 //-- Standard_ConstructionError::Raise("Domaine incorrect");
1819 Standard_Boolean TheReversedParameters=ReversedParameters();
1820 this->ResetFields();
1821 this->SetReversedParameters(TheReversedParameters);
1823 Standard_Integer nbsol=0;
1824 PeriodicInterval CInt1,CInt2;
1826 LineCircleGeometricIntersection(Line,Circle,TolConf,Tol
1832 if(nbsol==0) { //-- Pas de solutions
1836 // Modified by Sergey KHROMOV - Mon Dec 18 11:13:18 2000 Begin
1837 if (nbsol == 2 && CInt2.Bsup == CInt1.Binf + PIpPI) {
1838 Standard_Real FirstBound = CIRC_Domain.FirstParameter();
1839 Standard_Real LastBound = CIRC_Domain.LastParameter();
1840 Standard_Real FirstTol = CIRC_Domain.FirstTolerance();
1841 Standard_Real LastTol = CIRC_Domain.LastTolerance();
1842 if (CInt1.Binf == 0 && FirstBound - FirstTol > CInt1.Bsup) {
1844 CInt1.SetValues(CInt2.Binf, CInt2.Bsup);
1845 } else if (CInt2.Bsup == PIpPI && LastBound + LastTol < CInt2.Binf)
1848 // Modified by Sergey KHROMOV - Mon Dec 18 11:13:20 2000 End
1850 PeriodicInterval CDomain(CIRC_Domain);
1851 Standard_Real deltat = CDomain.Bsup-CDomain.Binf;
1852 while(CDomain.Binf >= PIpPI) CDomain.Binf-=PIpPI;
1853 while(CDomain.Binf < 0.0) CDomain.Binf+=PIpPI;
1854 CDomain.Bsup=CDomain.Binf+deltat;
1856 //------------------------------------------------------------
1857 //-- Ajout : Jeudi 28 mars 96
1858 //-- On agrandit artificiellement les domaines
1859 Standard_Real BinfModif = CDomain.Binf;
1860 Standard_Real BsupModif = CDomain.Bsup;
1861 BinfModif-=CIRC_Domain.FirstTolerance() / Circle.Radius();
1862 BsupModif+=CIRC_Domain.LastTolerance() / Circle.Radius();
1863 deltat = BsupModif-BinfModif;
1865 CDomain.Binf = BinfModif;
1866 CDomain.Bsup = BsupModif;
1869 Standard_Real t=PIpPI-deltat;
1871 CDomain.Binf = BinfModif+t;
1872 CDomain.Bsup = BsupModif-t;
1874 deltat = CDomain.Bsup-CDomain.Binf;
1875 while(CDomain.Binf >= PIpPI) CDomain.Binf-=PIpPI;
1876 while(CDomain.Binf < 0.0) CDomain.Binf+=PIpPI;
1877 CDomain.Bsup=CDomain.Binf+deltat;
1878 //-- ------------------------------------------------------------
1880 Interval LDomain(LIG_Domain);
1882 Standard_Integer NbSolTotal=0;
1884 PeriodicInterval SolutionCircle[4];
1885 Interval SolutionLine[4];
1887 //----------------------------------------------------------------------
1888 //----------- Traitement du premier intervalle Geometrique CInt1 ----
1889 //----------------------------------------------------------------------
1890 //-- NbSolTotal est incremente a chaque Intervalle solution.
1891 //-- On stocke les intervalles dans les tableaux : SolutionCircle[4]
1892 //-- et SolutionLine[4]
1893 //-- des Exemples faciles donnent 3 Intersections
1894 //-- des Problemes numeriques peuvent peut etre en donner 4 ??????
1896 PeriodicInterval CDomainAndRes=CDomain.FirstIntersection(CInt1);
1898 ProjectOnLAndIntersectWithLDomain(Circle,Line
1907 CDomainAndRes=CDomain.SecondIntersection(CInt1);
1909 ProjectOnLAndIntersectWithLDomain(Circle,Line
1918 //----------------------------------------------------------------------
1919 //----------- Traitement du second intervalle Geometrique C1_Int2 ----
1920 //----------------------------------------------------------------------
1922 CDomainAndRes=CDomain.FirstIntersection(CInt2);
1924 ProjectOnLAndIntersectWithLDomain(Circle,Line
1933 //--------------------------------------------------------------------
1934 CDomainAndRes=CDomain.SecondIntersection(CInt2);
1937 ProjectOnLAndIntersectWithLDomain(Circle,Line
1955 //----------------------------------------------------------------------
1956 //-- Calcul de toutes les transitions et Positions.
1958 //-- On determine si des intervalles sont reduit a des points
1959 //-- ( Rayon * Intervalle.Length() < TolConf ) ### Modif 19 Nov Tol-->TolConf
1961 Standard_Real R=Circle.Radius();
1962 Standard_Integer i ;
1963 Standard_Real MaxTol = TolConf;
1964 if(MaxTol<Tol) MaxTol = Tol;
1965 if(MaxTol<1.0e-10) MaxTol = 1.0e-10;
1967 for( i=0; i<NbSolTotal ; i++) {
1968 if((R * SolutionCircle[i].Length())<MaxTol
1969 && (SolutionLine[i].Length())<MaxTol) {
1971 Standard_Real t=(SolutionCircle[i].Binf+SolutionCircle[i].Bsup)*0.5;
1972 SolutionCircle[i].Binf=SolutionCircle[i].Bsup=t;
1974 t=(SolutionLine[i].Binf+SolutionLine[i].Bsup)*0.5;
1975 SolutionLine[i].Binf=SolutionLine[i].Bsup=t;
1979 if(NbSolTotal == 2) {
1980 if(SolutionLine[0].Binf==SolutionLine[0].BSup) {
1981 if(SolutionLine[1].Binf==SolutionLine[1].BSup) {
1982 if(Abs(SolutionLine[0].Binf-SolutionLine[1].Binf)<TolConf) {
1983 SolutionLine[0].Binf=0.5*(SolutionLine[0].BSup+SolutionLine[1].BSup);
1984 SolutionLine[0].BSup=SolutionLine[0].Binf;
1991 //----------------------------------------------------------------------
1992 //-- Traitement des intervalles (ou des points obtenus)
1995 gp_Ax22d CircleAxis=Circle.Axis();
1996 gp_Ax2d LineAxis=Line.Position();
1997 gp_Pnt2d P1a,P2a,P1b,P2b;
1998 gp_Vec2d Tan1,Tan2,Norm1;
1999 gp_Vec2d Norm2(0.0,0.0);
2000 IntRes2d_Transition T1a,T2a,T1b,T2b;
2001 IntRes2d_Position Pos1a,Pos1b,Pos2a,Pos2b;
2003 ElCLib::CircleD1(SolutionCircle[0].Binf,CircleAxis,R,P1a,Tan1);
2004 ElCLib::LineD1(SolutionLine[0].Binf,LineAxis,P2a,Tan2);
2006 Standard_Boolean Opposite=((Tan1.Dot(Tan2))<0.0)? Standard_True : Standard_False;
2009 for(i=0; i<NbSolTotal; i++ ) {
2013 //-- On recentre Bin et Bsup de facon a avoir une portion commune avec CIRC_Domain
2014 Standard_Real p1=SolutionCircle[i].Binf;
2015 Standard_Real p2=SolutionCircle[i].Bsup;
2016 Standard_Real q1=CIRC_Domain.FirstParameter();
2017 Standard_Real q2=CIRC_Domain.LastParameter();
2018 //-- |------ CircDomain ------| [-- Sol --]
2033 if(p1<q1 && p2>q1) {
2036 if(p1<q2 && p2>q2) {
2041 if(SolutionCircle[i].Binf!=p1 || SolutionCircle[i].Bsup!=p2) {
2042 printf("\n IntCurve_IntConicConic_1.cxx : (%g , %g) --> (%g , %g)\n",
2043 SolutionCircle[i].Binf,SolutionCircle[i].Bsup,p1,p2);
2046 SolutionCircle[i].Binf=p1;
2047 SolutionCircle[i].Bsup=p2;
2052 Standard_Real Linf=(Opposite)? SolutionLine[i].Bsup : SolutionLine[i].Binf;
2053 Standard_Real Lsup=(Opposite)? SolutionLine[i].Binf : SolutionLine[i].Bsup;
2055 //---------------------------------------------------------------
2056 //-- Si les parametres sur le cercle sont en premier
2057 //-- On doit retourner ces parametres dans l ordre croissant
2058 //---------------------------------------------------------------
2060 Standard_Real T=SolutionCircle[i].Binf;
2061 SolutionCircle[i].Binf=SolutionCircle[i].Bsup;
2062 SolutionCircle[i].Bsup=T;
2064 T=Linf; Linf=Lsup; Lsup=T;
2068 ElCLib::CircleD2(SolutionCircle[i].Binf,CircleAxis,R,P1a,Tan1,Norm1);
2069 ElCLib::LineD1(Linf,LineAxis,P2a,Tan2);
2071 IntImpParGen::DeterminePosition(Pos1a,CIRC_Domain,P1a,SolutionCircle[i].Binf);
2072 IntImpParGen::DeterminePosition(Pos2a,LIG_Domain,P2a,Linf);
2073 Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
2075 if(Pos1a==IntRes2d_End) {
2076 Cinf = CIRC_Domain.LastParameter();
2077 P1a = CIRC_Domain.LastPoint();
2078 Linf = ElCLib::Parameter(Line,P1a);
2080 ElCLib::CircleD2(Cinf,CircleAxis,R,P1a,Tan1,Norm1);
2081 ElCLib::LineD1(Linf,LineAxis,P2a,Tan2);
2082 IntImpParGen::DeterminePosition(Pos1a,CIRC_Domain,P1a,Cinf);
2083 IntImpParGen::DeterminePosition(Pos2a,LIG_Domain,P2a,Linf);
2084 Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
2086 else if(Pos1a==IntRes2d_Head) {
2087 Cinf = CIRC_Domain.FirstParameter();
2088 P1a = CIRC_Domain.FirstPoint();
2089 Linf = ElCLib::Parameter(Line,P1a);
2091 ElCLib::CircleD2(Cinf,CircleAxis,R,P1a,Tan1,Norm1);
2092 ElCLib::LineD1(Linf,LineAxis,P2a,Tan2);
2093 IntImpParGen::DeterminePosition(Pos1a,CIRC_Domain,P1a,Cinf);
2094 IntImpParGen::DeterminePosition(Pos2a,LIG_Domain,P2a,Linf);
2095 Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
2098 Cinf=NormalizeOnCircleDomain(SolutionCircle[i].Binf,CIRC_Domain);
2101 IntRes2d_IntersectionPoint NewPoint1(P1a,Linf,Cinf,T2a,T1a,ReversedParameters());
2103 if((SolutionLine[i].Length()+SolutionCircle[i].Length()) >0.0) {
2105 ElCLib::CircleD2(SolutionCircle[i].Bsup,CircleAxis,R,P1b,Tan1,Norm1);
2106 ElCLib::LineD1(Lsup,LineAxis,P2b,Tan2);
2108 IntImpParGen::DeterminePosition(Pos1b,CIRC_Domain,P1b,SolutionCircle[i].Bsup);
2109 IntImpParGen::DeterminePosition(Pos2b,LIG_Domain,P2b,Lsup);
2110 Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
2112 if(Pos1b==IntRes2d_End) {
2113 Csup = CIRC_Domain.LastParameter();
2114 P1b = CIRC_Domain.LastPoint();
2115 Lsup = ElCLib::Parameter(Line,P1b);
2116 ElCLib::CircleD2(Csup,CircleAxis,R,P1b,Tan1,Norm1);
2117 ElCLib::LineD1(Lsup,LineAxis,P2b,Tan2);
2119 IntImpParGen::DeterminePosition(Pos1b,CIRC_Domain,P1b,Csup);
2120 IntImpParGen::DeterminePosition(Pos2b,LIG_Domain,P2b,Lsup);
2121 Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
2123 else if(Pos1b==IntRes2d_Head) {
2124 Csup = CIRC_Domain.FirstParameter();
2125 P1b = CIRC_Domain.FirstPoint();
2126 Lsup = ElCLib::Parameter(Line,P1b);
2127 ElCLib::CircleD2(Csup,CircleAxis,R,P1b,Tan1,Norm1);
2128 ElCLib::LineD1(Lsup,LineAxis,P2b,Tan2);
2130 IntImpParGen::DeterminePosition(Pos1b,CIRC_Domain,P1b,Csup);
2131 IntImpParGen::DeterminePosition(Pos2b,LIG_Domain,P2b,Lsup);
2132 Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
2135 Csup=NormalizeOnCircleDomain(SolutionCircle[i].Bsup,CIRC_Domain);
2138 IntRes2d_IntersectionPoint NewPoint2(P1b,Lsup,Csup,T2b,T1b,ReversedParameters());
2140 if(((Abs(Csup-Cinf)*R > MaxTol) && (Abs(Lsup-Linf) > MaxTol))
2141 || (T1a.TransitionType() != T2a.TransitionType())) {
2142 //-- Verifier egalement les transitions
2144 IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2
2145 ,Opposite,ReversedParameters());
2149 if(Pos1a!=IntRes2d_Middle || Pos2a!=IntRes2d_Middle) {
2152 if(Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle) {
2159 //--Standard_Real Cmid=NormalizeOnCircleDomain(0.5*(SolutionCircle[i].Bsup+SolutionCircle[i].Binf)
2161 //--IntRes2d_IntersectionPoint NewPoint(P2a,0.5*(Linf+Lsup)
2163 //-- ,T2a,T1a,ReversedParameters());
2173 const IntRes2d_IntersectionPoint SegmentToPoint( const IntRes2d_IntersectionPoint& Pa
2174 ,const IntRes2d_Transition& T1a
2175 ,const IntRes2d_Transition& T2a
2176 ,const IntRes2d_IntersectionPoint& Pb
2177 ,const IntRes2d_Transition& T1b
2178 ,const IntRes2d_Transition& T2b) {
2180 if((T1b.PositionOnCurve() == IntRes2d_Middle)
2181 && (T2b.PositionOnCurve() == IntRes2d_Middle)) {
2184 if((T1a.PositionOnCurve() == IntRes2d_Middle)
2185 && (T2a.PositionOnCurve() == IntRes2d_Middle)) {
2189 IntRes2d_Transition t1 = T1a;
2190 IntRes2d_Transition t2 = T2a;
2191 Standard_Real u1 = Pa.ParamOnFirst();
2192 Standard_Real u2 = Pa.ParamOnSecond();
2195 if(t1.PositionOnCurve() == IntRes2d_Middle) {
2196 t1.SetPosition(T1b.PositionOnCurve());
2197 u1 = Pb.ParamOnFirst();
2199 if(t2.PositionOnCurve() == IntRes2d_Middle) {
2200 t2.SetPosition(T2b.PositionOnCurve());
2201 u2 = Pb.ParamOnSecond();
2203 return(IntRes2d_IntersectionPoint(Pa.Value(),u1,u2,t1,t2,Standard_False));