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
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.
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.
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.
21 // a modifier le cas de 2 points confondus ( Insert a la place d'append ? )
23 #include <IntCurve_IntConicConic.jxx>
25 #include <IntCurve_IConicTool.hxx>
26 #include <IntCurve_PConic.hxx>
27 #include <IntRes2d_Domain.hxx>
29 #include <IntCurve_IntConicConic_Tool.hxx>
30 #include <IntImpParGen.hxx>
31 #include <IntCurve_IntConicConic_1.hxx>
33 #include <Standard_ConstructionError.hxx>
34 #include <IntRes2d_IntersectionPoint.hxx>
35 #include <IntRes2d_IntersectionSegment.hxx>
37 #include <gp_Pnt2d.hxx>
38 #include <gp_Vec2d.hxx>
39 #include <Precision.hxx>
40 #include <IntRes2d_TypeTrans.hxx>
42 Standard_Boolean Affichage=Standard_False;
43 Standard_Boolean AffichageGraph=Standard_True;
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
50 const Standard_Real PIsur2 = 0.5*M_PI;
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)
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
78 ElCLib::CircleParameter(Circle2.Axis()
79 ,ElCLib::CircleValue(C1DomainAndRes.Binf
80 ,Circle1.Axis(),Circle1.Radius()));
82 ElCLib::CircleParameter(Circle2.Axis()
83 ,ElCLib::CircleValue(C1DomainAndRes.Bsup
84 ,Circle1.Axis(),Circle1.Radius()));
86 PeriodicInterval C2Inter(C2inf,C2sup);
89 if(C2Inter.Length() > M_PI)
93 if(C2sup<=C2inf) C2sup+=PIpPI;
99 C2Inter.Bsup=C2sup; //--- Verifier la longueur de l'intervalle sur C2
100 C2Inter.Bsup=C2inf+C1DomainAndRes.Bsup-C1DomainAndRes.Binf;
103 PeriodicInterval C2InterAndDomain[2];
105 for(Standard_Integer i=0; i<2 ; i++) {
106 C2InterAndDomain[i]=(i==0)? DomainC2.FirstIntersection(C2Inter)
107 : DomainC2.SecondIntersection(C2Inter);
109 if(!C2InterAndDomain[i].IsNull()) {
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()));
120 SolutionC1[NbSolTotal]=PeriodicInterval(C1inf,C1sup);
122 if(SolutionC1[NbSolTotal].Length() > M_PI)
123 SolutionC1[NbSolTotal].Complement();
126 if(SolutionC1[NbSolTotal].Bsup <= SolutionC1[NbSolTotal].Binf) {
127 SolutionC1[NbSolTotal].Bsup+=PIpPI;
129 if(SolutionC1[NbSolTotal].Binf>=PIpPI) {
130 SolutionC1[NbSolTotal].Binf-=PIpPI;
131 SolutionC1[NbSolTotal].Bsup-=PIpPI;
134 SolutionC2[NbSolTotal]=C2InterAndDomain[i];
139 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
140 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141 void CircleCircleGeometricIntersection(const gp_Circ2d& C1
143 ,const Standard_Real Tol
144 ,const Standard_Real TolTang
145 ,PeriodicInterval& C1_Res1
146 ,PeriodicInterval& C1_Res2
147 ,Standard_Integer& nbsol) {
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)) {
166 //----------------------------------------------------------------
167 else if(dO1O2 <= Tol && AbsR1mR2<=Tol) {
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+
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);
196 //--------------------------------------------------------------------
197 //-- 2 segments donnes par Inter C2 avec C1- C1 C1+
198 //-- Seul le signe de dx change si dO1O2 < Max(R1,R2)
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;
206 dAlpha1=ATan2(dy,dx);
207 C1_binf1=-dAlpha1; C1_bsup2=dAlpha1; //-- |...? ?...| Sur C1
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);
215 C1_binf2=dAlpha1; C1_bsup1=-dAlpha1; //-- |...x x...| Sur C1
217 //------------------------------
218 //-- Les 2 intervalles sont ils
219 //-- en fait un seul inter ?
221 if(dy==0) { //-- Les 2 bornes internes sont identiques
226 if(C1_binf1>C1_bsup1) {
227 dAlpha1 = C1_binf1; C1_binf1 = C1_bsup1; C1_bsup1 = dAlpha1;
229 if(C1_binf2>C1_bsup2) {
230 dAlpha1 = C1_binf2; C1_binf2 = C1_bsup2; C1_bsup2 = dAlpha1;
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;
242 //--------------------------------------------------------------
243 //-- 1 seul segment donne par Inter C2 avec C1- ou C1+
244 else if(dO1O2 > AbsR1mR2-Tol) {
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);
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);
256 if(dAlpha2>dAlpha1) dAlpha1 = dAlpha2;
257 C1_binf1=-dAlpha1; C1_bsup1=dAlpha1;
260 //--------------------------------------------------------------
262 if((dO1O2 > AbsR1mR2-TolTang) && (AbsR1mR2-TolTang)>0.0) {
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
282 gp_Vec2d Axe1=C1.XAxis().Direction();
283 gp_Vec2d AxeO1O2=gp_Vec2d(C1.Location(),C2.Location());
285 Standard_Real dAngle1;
286 if(AxeO1O2.Magnitude() <= gp::Resolution())
287 dAngle1=Axe1.Angle(C2.XAxis().Direction());
289 dAngle1=Axe1.Angle(AxeO1O2);
291 if(C1.IsDirect() == Standard_False) {
296 C1_binf1+=dAngle1; C1_bsup1+=dAngle1;
298 //-- par construction aucun des segments ne peut exceder PI
299 //-- (permet de ne pas gerer trop de cas differents)
301 C1_Res1.SetValues(C1_binf1,C1_bsup1);
302 if(C1_Res1.Length() > M_PI) C1_Res1.Complement();
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();
313 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
314 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
315 void ProjectOnLAndIntersectWithLDomain(const gp_Circ2d& Circle
316 ,const gp_Lin2d& Line
317 ,PeriodicInterval& CDomainAndRes
319 ,PeriodicInterval* CircleSolution
320 ,Interval* LineSolution
321 ,Standard_Integer &NbSolTotal
322 ,const IntRes2d_Domain& RefLineDomain
323 // ,const IntRes2d_Domain& )
324 ,const IntRes2d_Domain& )
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
335 Standard_Real Linf=ElCLib::Parameter(Line
336 ,ElCLib::CircleValue(CDomainAndRes.Binf
339 Standard_Real Lsup=ElCLib::Parameter(Line
340 ,ElCLib::CircleValue(CDomainAndRes.Bsup
344 Interval LInter(Linf,Lsup); //-- Necessairement Borne
346 Interval LInterAndDomain=LDomain.IntersectionWithBounded(LInter);
348 if(!LInterAndDomain.IsNull) {
350 Standard_Real DomLinf = (RefLineDomain.HasFirstPoint())? RefLineDomain.FirstParameter() : -Precision::Infinite();
351 Standard_Real DomLsup = (RefLineDomain.HasLastPoint())? RefLineDomain.LastParameter() : Precision::Infinite();
353 Linf = LInterAndDomain.Binf;
354 Lsup = LInterAndDomain.Bsup;
370 LInterAndDomain.Binf = Linf;
371 LInterAndDomain.Bsup = Lsup;
375 ElCLib::CircleParameter(Circle.Axis()
376 ,ElCLib::LineValue(LInterAndDomain.Binf,
379 ElCLib::CircleParameter(Circle.Axis()
380 ,ElCLib::LineValue(LInterAndDomain.Bsup
383 if(Cinf<CDomainAndRes.Binf) Cinf = CDomainAndRes.Binf;
384 if(Csup>CDomainAndRes.Bsup) Csup = CDomainAndRes.Bsup;
386 Standard_Real Cinf=CDomainAndRes.Binf;
387 Standard_Real Csup=CDomainAndRes.Bsup;
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();
394 LineSolution[NbSolTotal]=LInterAndDomain;
399 //=======================================================================
400 //function : LineCircleGeometricIntersection
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)
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;
421 //----------------------------------------------------------------
422 if(dO1O2 > (R+Tol)) { //-- pas d intersection avec le 'tuyau'
423 if(dO1O2 > (R+TolTang)) {
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;
444 aX2=4.*(R*R-dO1O2*dO1O2);
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);
460 //--------------------------------------------------------------------
461 //-- 2 segments donnes par Inter Line avec Circle- Circle+
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;
469 dAlpha1=ATan2(dy,dx);
470 binf1=-dAlpha1; bsup2=dAlpha1; //-- |...? ?...| Sur C1
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);
477 binf2=dAlpha1; bsup1=-dAlpha1; //-- |...x x...| Sur C1
479 if((dAlpha1*R)<(Max(Tol,TolTang))) {
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
493 Standard_Real dAngle1=(Circle.XAxis().Direction()).Angle(Line.Direction());
496 //---------------------------------------------
497 //-- Si le cercle est indirect alors l origine
498 //-- est vue en -dAngle1.
500 if(Circle.IsDirect() == Standard_False) {
506 Standard_Real a,b,c,d;
507 Line.Coefficients(a,b,c);
509 d = a*Circle.Location().X() + b*Circle.Location().Y() + c;
511 if(d>0.0) dAngle1+= PIsur2;
512 else dAngle1-= PIsur2;
515 if(dAngle1<0.0) dAngle1+=PIpPI;
516 else if(dAngle1>PIpPI) dAngle1-=PIpPI;
519 binf1+=dAngle1; bsup1+=dAngle1;
521 //-- par construction aucun des segments ne peut exceder PI
522 //-- (permet de ne pas gerer trop de cas differents)
524 if(Circle.IsDirect() == Standard_False) {
525 Standard_Real t=binf1; binf1=bsup1; bsup1=t;
531 CInt1.SetValues(binf1,bsup1);
532 if(CInt1.Length() > M_PI) CInt1.Complement();
536 binf2+=dAngle1; bsup2+=dAngle1;
538 if(Circle.IsDirect() == Standard_False) {
539 Standard_Real t=binf2; binf2=bsup2; bsup2=t;
544 CInt2.SetValues(binf2,bsup2);
545 if(CInt2.Length() > M_PI) CInt2.Complement();
547 // Modified by Sergey KHROMOV - Thu Oct 26 17:51:05 2000 Begin
549 if (CInt1.Bsup > PIpPI && CInt1.Binf < PIpPI) {
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();
560 // Modified by Sergey KHROMOV - Thu Oct 26 17:51:13 2000 End
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) {
572 if(Domain.HasFirstPoint()) {
573 if(U1sup < (Domain.FirstParameter()-Domain.FirstTolerance())) {
574 Res1inf=1; Res1sup=-1;
577 if(U1inf>(Domain.FirstParameter()+Domain.FirstTolerance())) {
579 PosInf=IntRes2d_Middle;
582 Res1inf=Domain.FirstParameter();
583 PosInf=IntRes2d_Head;
588 PosInf=IntRes2d_Middle;
591 if(Domain.HasLastPoint()) {
592 if(U1inf >(Domain.LastParameter()+Domain.LastTolerance())) {
593 Res1inf=1; Res1sup=-1;
596 if(U1sup<(Domain.LastParameter()-Domain.LastTolerance())) {
598 PosSup=IntRes2d_Middle;
601 Res1sup=Domain.LastParameter();
607 PosSup=IntRes2d_Middle;
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) {
619 //--- Traitement des cas ou une intersection vraie est dans la tolerance
621 /*if(PosInf==IntRes2d_Head) {
622 if(Res1sup <= (Res1inf+Domain.FirstTolerance())) {
624 PosSup=IntRes2d_Head;
627 if(PosSup==IntRes2d_End) {
628 if(Res1inf >= (Res1sup-Domain.LastTolerance())) {
634 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
635 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
636 void LineLineGeometricIntersection(const gp_Lin2d& L1
638 ,const Standard_Real Tol
641 ,Standard_Real& SinDemiAngle
642 ,Standard_Integer& nbsol) {
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();
651 Standard_Real D=U1y*U2x-U1x*U2y;
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;
661 U1=(Uo21y * U2x - Uo21x * U2y)/D;
662 U2=(Uo21y * U1x - Uo21x * U1y)/D;
664 //------------------- Calcul du Sin du demi angle entre L1 et L2
667 if(D>1.0) D=1.0; //-- Deja vu !
668 SinDemiAngle=Sin(0.5*ASin(D));
672 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
673 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
674 /*IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Lin2d& L1
675 ,const IntRes2d_Domain& D1
677 ,const IntRes2d_Domain& D2
678 ,const Standard_Real TolConf
679 ,const Standard_Real Tol) {
680 Perform(L1,D1,L2,D2,TolConf,Tol);
684 IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Lin2d& L1
685 ,const IntRes2d_Domain& D1
687 ,const IntRes2d_Domain& D2
688 ,const Standard_Real TolConf
689 ,const Standard_Real Tol) {
691 Perform(L1,D1,C2,D2,TolConf,Tol);
695 IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Circ2d& C1
696 ,const IntRes2d_Domain& D1
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);
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) {
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);
729 Standard_Integer nbsol=0;
730 PeriodicInterval C1_Int1,C1_Int2;
732 //------- Intersection sans tenir compte du domaine ----> nbsol=0,1,2,3
733 CircleCircleGeometricIntersection(Circle1,Circle2,TolConf,Tol,C1_Int1,C1_Int2,nbsol);
736 if(nbsol==0) { //-- Pas de solutions
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; }
745 while(C1Domain.Binf >= PIpPI) C1Domain.Binf-=PIpPI;
746 while(C1Domain.Binf < 0.0) C1Domain.Binf+=PIpPI;
747 C1Domain.Bsup=C1Domain.Binf+deltat;
749 PeriodicInterval C2Domain(DomainCirc2);
750 deltat = C2Domain.Bsup-C2Domain.Binf;
751 if(deltat>=PIpPI) { deltat=PIpPI-1e-14; }
753 while(C2Domain.Binf >= PIpPI) C2Domain.Binf-=PIpPI;
754 while(C2Domain.Binf < 0.0) C2Domain.Binf+=PIpPI;
755 C2Domain.Bsup=C2Domain.Binf+deltat;
757 Standard_Boolean IdentCircles=Standard_False;
760 //-- Les 2 cercles sont confondus a Tol pres
761 C1_Int1.SetValues(0,PIpPI);
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;
775 Standard_Integer NbSolTotal=0;
776 PeriodicInterval SolutionC1[4];
777 PeriodicInterval SolutionC2[4];
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 ??????
788 PeriodicInterval C1DomainAndRes=C1Domain.FirstIntersection(C1_Int1);
790 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
793 ,SolutionC1,SolutionC2
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
801 C1DomainAndRes=C1Domain.SecondIntersection(C1_Int1);
803 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
806 ,SolutionC1,SolutionC2
810 //----------------------------------------------------------------------
811 //----------- Traitement du second intervalle Geometrique C1_Int2 ----
812 //----------------------------------------------------------------------
814 C1DomainAndRes=C1Domain.FirstIntersection(C1_Int2);
816 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
819 ,SolutionC1,SolutionC2
822 //--------------------------------------------------------------------
823 C1DomainAndRes=C1Domain.SecondIntersection(C1_Int2);
825 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
828 ,SolutionC1,SolutionC2
832 //----------------------------------------------------------------------
833 //-- Calcul de toutes les transitions et Positions.
835 //----------------------------------------------------------------------
836 //-- On determine si des intervalles sont reduit a des points
837 //-- ( Rayon * Intervalle.Length() < Tol )
839 Standard_Real R1=Circle1.Radius();
840 Standard_Real R2=Circle2.Radius();
841 Standard_Real Tol2=Tol+Tol; //---- Pour eviter de toujours retourner
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) {
849 Standard_Real t=(SolutionC1[i].Binf+SolutionC1[i].Bsup)*0.5;
850 SolutionC1[i].Binf=SolutionC1[i].Bsup=t;
852 t=(SolutionC2[i].Binf+SolutionC2[i].Bsup)*0.5;
853 SolutionC2[i].Binf=SolutionC2[i].Bsup=t;
857 //----------------------------------------------------------------------
858 //-- Traitement des intervalles (ou des points obtenus)
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;
867 Standard_Boolean Opposite=((Circle1.Location().SquareDistance(Circle2.Location()))
868 >(R1*R1+R2*R2))? Standard_True : Standard_False;
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; }
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;
877 Standard_Real C1inf=NormalizeOnCircleDomain(SolutionC1[i].Binf,DomainCirc1);
878 C2inf=NormalizeOnCircleDomain(C2inf,DomainCirc2);
880 if(IndirectCircles) {
882 ElCLib::CircleD2(C1inf,Axis2C1,R1,P1a,Tan1,Norm1);
883 ElCLib::CircleD2(C2inf,Axis2C2,R2,P2a,Tan2,Norm2);
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);
891 IntRes2d_IntersectionPoint NewPoint1(P1a,C1inf,PIpPI-C2inf,T1a,T2a,Standard_False);
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);
899 ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1);
900 ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
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);
907 //--------------------------------------------------
911 if(C2inf<C2sup) C2inf+=PIpPI;
916 if(C2sup<C2inf) C2sup+=PIpPI;
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,
934 ElCLib::CircleD2(C1inf,Axis2C1,R1,P1a,Tan1,Norm1);
935 ElCLib::CircleD2(C2inf,Axis2C2,R2,P2a,Tan2,Norm2);
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);
942 IntRes2d_IntersectionPoint NewPoint1(P1a,C1inf,C2inf,T1a,T2a,Standard_False);
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);
950 ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1);
951 ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
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);
957 //--------------------------------------------------
961 if(C2inf<C2sup) C2inf+=PIpPI;
966 if(C2sup<C2inf) C2sup+=PIpPI;
970 IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,C2sup,T1b,T2b,Standard_False);
971 IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2,Opposite,Standard_False);
981 //----------------------------------------------------------------------
982 IntRes2d_Position FindPositionLL(Standard_Real &Param
983 ,const IntRes2d_Domain& Domain)
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;
996 if(Domain.HasLastPoint()) {
997 Standard_Real aD2 = Abs(Param-Domain.LastParameter());
998 if( aD2 <= Domain.LastTolerance() && (aPos == IntRes2d_Middle || aD2 < aDPar ))
1000 aResPar=Domain.LastParameter();
1001 aPos = IntRes2d_End;
1007 //--------------------------------------------------------------------
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)
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.);
1024 //=======================================================================
1025 //function : computeIntPoint
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)
1039 if(fabs(theResSup-theParCur) > fabs(theResInf-theParCur))
1040 theResSup = theResInf;
1042 Standard_Real aRes2 = theParOther + (theResSup - theParCur) * theCosT1T2;
1044 Standard_Real aFirst2, aLast2, aTol21, aTol22, aTol11, aTol12 ;
1046 getDomainParametrs(theDomainOther,aFirst2, aLast2, aTol21, aTol22);
1048 if( aRes2 < aFirst2 - aTol21 || aRes2 > aLast2 + aTol22 ) {
1049 return Standard_False;
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 ) );
1059 if( theCurTrans != IntRes2d_Undecided )
1061 aT1.SetValue(Standard_False, aPos1a, theCurTrans);
1062 aT2.SetValue(Standard_False, aPos2a, anOtherTrans);
1066 Standard_Boolean anOpposite = theCosT1T2 < 0.;
1067 aT1.SetValue(Standard_False,aPos1a,IntRes2d_Unknown,anOpposite);
1068 aT2.SetValue(Standard_False,aPos2a,IntRes2d_Unknown,anOpposite);
1070 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1071 //--------------------------------------------------
1073 Standard_Real aResU1 = theParCur;
1074 Standard_Real aResU2 = theParOther;
1076 Standard_Real aFirst1, aLast1;
1077 getDomainParametrs(theCurDomain,aFirst1, aLast1, aTol11, aTol12);
1079 Standard_Boolean isInside1 = (theParCur >= aFirst1 && theParCur <= aLast1);
1080 Standard_Boolean isInside2 = (theParOther >= aFirst2 && theParOther <= aLast2);
1082 if(!isInside1 || !isInside2)
1086 gp_Pnt2d Pt1=ElCLib::Value(aRes2,theOtherLin);
1088 Standard_Real aPar1 = ElCLib::Parameter(theCurLin,Pt1);
1089 aResU1 =((aPar1 >= aFirst1 && aPar1<= aLast1) ? aPar1 : theResSup);
1094 gp_Pnt2d aPt1=ElCLib::Value(theResSup,theCurLin);
1096 Standard_Real aPar2 = ElCLib::Parameter(theOtherLin,aPt1);
1097 aResU2= ((aPar2 >= aFirst2 && aPar2<= aLast2) ? aPar2 : aRes2);
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;
1112 gp_Pnt2d aPres((ElCLib::Value(aResU1,theCurLin).XY() + ElCLib::Value(aResU2,theOtherLin).XY()) * 0.5 );
1114 theNewPoint.SetValues(aPres, aResU1, aResU2 ,aT1, aT2, Standard_False);
1116 theNewPoint.SetValues(aPres, aResU2, aResU1 ,aT2, aT1, Standard_False);
1117 return Standard_True;
1120 //----------------------------------------------------------------------
1121 void IntCurve_IntConicConic::Perform(const gp_Lin2d& L1
1122 ,const IntRes2d_Domain& Domain1
1124 ,const IntRes2d_Domain& Domain2
1125 ,const Standard_Real,const Standard_Real TolR) {
1126 this->ResetFields();
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;
1140 LineLineGeometricIntersection(L1,L2,Tol,U1,U2,SINL1L2,nbsol);
1142 gp_Vec2d Tan1=L1.Direction();
1143 gp_Vec2d Tan2=L2.Direction();
1145 Standard_Real aCosT1T2 = Tan1.Dot(Tan2);
1146 Standard_Boolean Opposite=(aCosT1T2 < 0.0)? Standard_True : Standard_False;
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;
1166 //---------------------------------------------------
1167 //-- On agrandit la zone U1inf U1sup pour tenir compte
1168 //-- des tolerances des points en bout
1170 if(Domain1.HasFirstPoint()) {
1171 if(L2.Distance(Domain1.FirstPoint()) < Domain1.FirstTolerance()) {
1172 if(U1inf > Domain1.FirstParameter()) {
1173 U1inf = Domain1.FirstParameter();
1175 if(U1sup < Domain1.FirstParameter()) {
1176 U1sup = Domain1.FirstParameter();
1180 if(Domain1.HasLastPoint()) {
1181 if(L2.Distance(Domain1.LastPoint()) < Domain1.LastTolerance()) {
1182 if(U1inf > Domain1.LastParameter()) {
1183 U1inf = Domain1.LastParameter();
1185 if(U1sup < Domain1.LastParameter()) {
1186 U1sup = Domain1.LastParameter();
1190 if(Domain2.HasFirstPoint()) {
1191 if(L1.Distance(Domain2.FirstPoint()) < Domain2.FirstTolerance()) {
1192 Standard_Real p = ElCLib::Parameter(L1,Domain2.FirstPoint());
1201 if(Domain2.HasLastPoint()) {
1202 if(L1.Distance(Domain2.LastPoint()) < Domain2.LastTolerance()) {
1203 Standard_Real p = ElCLib::Parameter(L1,Domain2.LastPoint());
1212 //-----------------------------------------------------------------
1214 DomainIntersection(Domain1,U1inf,U1sup,Res1inf,Res1sup,Pos1a,Pos1b);
1216 if((Res1sup-Res1inf)<0.0) {
1217 //-- Si l intersection est vide
1220 else { //-- (Domain1 INTER Zone Intersection) non vide
1222 ProdVectTan=Tan1.Crossed(Tan2);
1224 //#####################################################################
1225 //## Longueur Minimale d un segment Sur Courbe 1
1226 //#####################################################################
1228 Standard_Real LongMiniSeg=Tol;
1231 if(((Res1sup-Res1inf)<=LongMiniSeg)
1232 || ((Pos1a==Pos1b)&&(Pos1a!=IntRes2d_Middle)))
1234 //------------------------------- Un seul Point -------------------
1235 //--- lorsque la longueur du segment est inferieure a ??
1236 //--- ou si deux points designent le meme bout
1238 IntRes2d_TypeTrans aCurTrans = ( ProdVectTan >= TOLERANCE_ANGULAIRE ?
1239 IntRes2d_Out : ( ProdVectTan <= -TOLERANCE_ANGULAIRE ? IntRes2d_In : IntRes2d_Undecided ) );
1241 IntRes2d_IntersectionPoint NewPoint1;
1242 if( computeIntPoint(Domain1, Domain2, L1, L2, aCosT1T2, U1, U2, Res1inf, Res1sup, 1, aCurTrans, NewPoint1 ) )
1245 //------------------------------------------------------
1248 } //--------------- Fin du cas : 1 seul point --------------------
1251 //-- Intersection AND Domain1 --------> Segment ---------------------
1252 Standard_Real U2inf,U2sup;
1253 Standard_Real Res2inf,Res2sup;
1255 if(Opposite) { U2inf = U1pU2 -Res1sup; U2sup= U1pU2-Res1inf; }
1256 else { U2inf = Res1inf-U1mU2; U2sup= Res1sup-U1mU2; }
1258 DomainIntersection(Domain2,U2inf,U2sup,Res2inf,Res2sup,Pos2a,Pos2b);
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
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
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;
1277 else { Res1inf=U1mU2+Res2inf; Res1sup=U1mU2+Res2sup; }
1279 Pos1a=FindPositionLL(Res1inf,Domain1);
1280 Pos1b=FindPositionLL(Res1sup,Domain1);
1282 IntRes2d_Transition T1a,T2a,T1b,T2b;
1284 if(ProdVectTan>=TOLERANCE_ANGULAIRE) { // &&&&&&&&&&&&&&&
1285 T1a.SetValue(Standard_False,Pos1a,IntRes2d_Out);
1286 T2a.SetValue(Standard_False,Pos2a,IntRes2d_In);
1288 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1289 T1a.SetValue(Standard_False,Pos1a,IntRes2d_In);
1290 T2a.SetValue(Standard_False,Pos2a,IntRes2d_Out);
1293 T1a.SetValue(Standard_False,Pos1a,IntRes2d_Unknown,Opposite);
1294 T2a.SetValue(Standard_False,Pos2a,IntRes2d_Unknown,Opposite);
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 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1306 Standard_Boolean ResultIsAPoint=Standard_False;
1308 if(((Res1sup-Res1inf)<=LongMiniSeg)
1309 || (Abs(Res2sup-Res2inf)<=LongMiniSeg)) {
1310 //-- On force la creation d un point
1311 ResultIsAPoint=Standard_True;
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 //------------------------------------------------------------
1324 if(Pos1a==IntRes2d_Head) {
1325 if(Pos1b!=IntRes2d_End && U1<Res1inf) { ResultIsAPoint=Standard_True; U1=Res1inf; U2=Res2inf; }
1327 if(Pos1b==IntRes2d_End) {
1328 if(Pos1a!=IntRes2d_Head && U1>Res1sup) { ResultIsAPoint=Standard_True; U1=Res1sup; U2=Res2sup; }
1331 if(Pos2a==IntRes2d_Head) {
1332 if(Pos2b!=IntRes2d_End && U2<Res2inf) { ResultIsAPoint=Standard_True; U2=Res2inf; U1=Res1inf; }
1335 if(Pos2a==IntRes2d_End) {
1336 if(Pos2b!=IntRes2d_Head && U2>Res2inf) { ResultIsAPoint=Standard_True; U2=Res2inf; U1=Res1inf; }
1339 if(Pos2b==IntRes2d_Head) {
1340 if(Pos2a!=IntRes2d_End && U2<Res2sup) { ResultIsAPoint=Standard_True; U2=Res2sup; U1=Res1sup; }
1343 if(Pos2b==IntRes2d_End) {
1344 if(Pos2a!=IntRes2d_Head && U2>Res2sup) { ResultIsAPoint=Standard_True; U2=Res2sup; U1=Res1sup; }
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);
1357 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) { //&&&&&&&&&&&&&&
1358 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1359 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1362 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1363 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1366 if(Pos1a==IntRes2d_Middle) {
1369 t3 = (Pos2a == IntRes2d_Head)? Res2sup : Res2inf;
1372 t3 = (Pos2a == IntRes2d_Head)? Res2inf : Res2sup;
1374 Ptdebut=ElCLib::Value(t3,L2);
1375 Res1inf=ElCLib::Parameter(L1,Ptdebut);
1378 Standard_Real t4 = (Pos1a == IntRes2d_Head)? Res1inf : Res1sup;
1379 Ptdebut=ElCLib::Value(t4,L1);
1380 Res2inf=ElCLib::Parameter(L2,Ptdebut);
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
1387 if(Pos1b==IntRes2d_Middle) {
1388 Ptfin=ElCLib::Value(Res2sup,L2);
1389 Res1sup=ElCLib::Parameter(L1,Ptfin);
1392 Ptfin=ElCLib::Value(Res1sup,L1);
1393 Res2sup=ElCLib::Parameter(L2,Ptfin);
1395 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1396 IntRes2d_IntersectionSegment Segment(PtSeg1,PtSeg2
1397 ,Opposite,Standard_False);
1400 else { //-- Extremite(L1 ou L2) ------> Point Middle(L1 et L2)
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);
1408 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1409 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1410 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1413 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1414 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1417 PtSeg2.SetValues(ElCLib::Value(U2,L2),U1,U2,T1b,T2b,Standard_False);
1419 if((Abs(Res1inf-U1) >LongMiniSeg) && (Abs(Res2inf-U2) >LongMiniSeg)) {
1420 IntRes2d_IntersectionSegment Segment(PtSeg1,PtSeg2,Opposite,Standard_False);
1424 Append(SegmentToPoint(PtSeg1,T1a,T2a,PtSeg2,T1b,T2b));
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
1435 if(Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle) {
1437 if(Pos1b==IntRes2d_Middle) {
1440 t2 = (Pos2b == IntRes2d_Head)? Res2sup : Res2inf;
1443 t2 = (Pos2b == IntRes2d_Head)? Res2inf : Res2sup;
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
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
1460 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1461 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1462 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1464 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1465 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1466 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1469 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1470 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1472 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1476 Pos1b=FindPositionLL(U1,Domain1);
1477 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);
1491 PtSeg1.SetValues(ElCLib::Value(U2,L2),U1,U2,T1b,T2b,Standard_False);
1496 PtSeg1.SetValues(ElCLib::Value(U2,L2),U1,U2,T1a,T2a,Standard_False);
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);
1504 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1505 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1506 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1509 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Unknown,Opposite);
1510 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Unknown,Opposite);
1512 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1513 //~~ Ajustement des parametres et du point renvoye
1515 if(Pos1b==IntRes2d_Middle) {
1516 Ptfin=ElCLib::Value(Res2sup,L2);
1517 Res1sup=ElCLib::Parameter(L1,Ptfin);
1520 Ptfin=ElCLib::Value(Res1sup,L1);
1521 Res2sup=ElCLib::Parameter(L2,Ptfin);
1524 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1526 if((Abs(U1-Res1sup)>LongMiniSeg)
1527 ||(Abs(U2-Res2sup)>LongMiniSeg)) {
1528 //-- Modif du 1er Octobre 92 (Pour Composites)
1530 IntRes2d_IntersectionSegment Segment(PtSeg1,PtSeg2
1531 ,Opposite,Standard_False);
1535 Append(SegmentToPoint(PtSeg1,T1a,T2a,PtSeg2,T1b,T2b));
1543 } //----- Fin Creation Segment ----(Res2sup-Res2inf>Tol)-------------
1545 //------ (Intersection And Domain1) AND Domain2 --> Point ------
1546 //-- Attention Res1sup peut etre different de U2
1547 //-- Mais on a Res1sup-Res1inf < Tol
1550 IntRes2d_TypeTrans aCurTrans = ( ProdVectTan >= TOLERANCE_ANGULAIRE ?
1551 IntRes2d_In : ( ProdVectTan <= -TOLERANCE_ANGULAIRE ? IntRes2d_Out : IntRes2d_Undecided ) );
1553 IntRes2d_IntersectionPoint NewPoint1;
1554 if( computeIntPoint(Domain2, Domain1, L2, L1, aCosT1T2, U2, U1, Res2inf, Res2sup, 2, aCurTrans, NewPoint1 ) )
1562 if(nbsol==2) { //== Droites confondues a la tolerance pres
1563 //--On traite ici le cas de segments resultats non neccess. bornes
1565 //--On prend la droite D1 comme reference ( pour le sens positif )
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
1574 if(Domain1.HasFirstPoint()) ResHasFirstPoint=1;
1575 if(Domain1.HasLastPoint()) ResHasLastPoint=1;
1577 if(Domain2.HasLastPoint()) ResHasFirstPoint+=2;
1578 if(Domain2.HasFirstPoint()) ResHasLastPoint+=2;
1581 if(Domain2.HasLastPoint()) ResHasLastPoint+=2;
1582 if(Domain2.HasFirstPoint()) ResHasFirstPoint+=2;
1584 if(ResHasFirstPoint==0 && ResHasLastPoint==0) {
1585 //~~~~ Creation d un segment infini avec Opposite
1586 Append(IntRes2d_IntersectionSegment(Opposite));
1588 else { //-- On obtient au pire une demi-droite
1589 switch(ResHasFirstPoint) {
1591 ParamStart=Domain1.FirstParameter();
1592 ParamStart2=(Opposite)? (Org2SurL1-ParamStart)
1593 :(ParamStart-Org2SurL1);
1597 ParamStart2=Domain2.LastParameter();
1598 ParamStart=Org2SurL1 - ParamStart2;
1601 ParamStart2=Domain2.FirstParameter();
1602 ParamStart=Org2SurL1 + ParamStart2;
1607 ParamStart2=Domain2.LastParameter();
1608 ParamStart=Org2SurL1 - ParamStart2;
1609 if(ParamStart < Domain1.FirstParameter()) {
1610 ParamStart=Domain1.FirstParameter();
1611 ParamStart2=Org2SurL1 - ParamStart;
1615 ParamStart2=Domain2.FirstParameter();
1616 ParamStart=Org2SurL1 + ParamStart2;
1617 if(ParamStart < Domain1.FirstParameter()) {
1618 ParamStart=Domain1.FirstParameter();
1619 ParamStart2=ParamStart - Org2SurL1;
1623 default: //~~~ Segment Infini a gauche
1627 switch(ResHasLastPoint) {
1629 ParamEnd=Domain1.LastParameter();
1630 ParamEnd2=(Opposite)? (Org2SurL1-ParamEnd)
1631 :(ParamEnd-Org2SurL1);
1635 ParamEnd2=Domain2.FirstParameter();
1636 ParamEnd=Org2SurL1 - ParamEnd2;
1639 ParamEnd2=Domain2.LastParameter();
1640 ParamEnd=Org2SurL1 + ParamEnd2;
1645 ParamEnd2=Domain2.FirstParameter();
1646 ParamEnd=Org2SurL1 - ParamEnd2;
1647 if(ParamEnd > Domain1.LastParameter()) {
1648 ParamEnd=Domain1.LastParameter();
1649 ParamEnd2=Org2SurL1 - ParamEnd;
1653 ParamEnd2=Domain2.LastParameter();
1654 ParamEnd=Org2SurL1 + ParamEnd2;
1655 if(ParamEnd > Domain1.LastParameter()) {
1656 ParamEnd=Domain1.LastParameter();
1657 ParamEnd2=ParamEnd - Org2SurL1;
1660 default: //~~~ Segment Infini a droite
1664 IntRes2d_Transition Tinf,Tsup;
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);
1688 IntRes2d_IntersectionPoint P2(ElCLib::Value(ParamEnd,L1)
1690 ,Tinf,Tsup,Standard_False);
1691 IntRes2d_IntersectionSegment Seg(P1,P2,Opposite,Standard_False);
1694 else { //~~~~ le segment est de longueur inferieure a Tol
1697 } //-- if( ParamEnd >= ...)
1698 } //-- if(ResHasLastPoint)
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);
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);
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);
1719 IntRes2d_IntersectionPoint P2(ElCLib::Value(ParamEnd,L1)
1721 ,Tinf,Tsup,Standard_False);
1722 IntRes2d_IntersectionSegment Seg(P2,Standard_False,Opposite,Standard_False);
1724 //~~~ Creation de la demi droite <-----------|
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) {
1740 //-- if(! CIRC_Domain.IsClosed()) {
1741 //-- Standard_ConstructionError::Raise("Domaine incorrect");
1744 Standard_Boolean TheReversedParameters=ReversedParameters();
1745 this->ResetFields();
1746 this->SetReversedParameters(TheReversedParameters);
1748 Standard_Integer nbsol=0;
1749 PeriodicInterval CInt1,CInt2;
1751 LineCircleGeometricIntersection(Line,Circle,TolConf,Tol
1757 if(nbsol==0) { //-- Pas de solutions
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) {
1769 CInt1.SetValues(CInt2.Binf, CInt2.Bsup);
1770 } else if (CInt2.Bsup == PIpPI && LastBound + LastTol < CInt2.Binf)
1773 // Modified by Sergey KHROMOV - Mon Dec 18 11:13:20 2000 End
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;
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;
1790 CDomain.Binf = BinfModif;
1791 CDomain.Bsup = BsupModif;
1794 Standard_Real t=PIpPI-deltat;
1796 CDomain.Binf = BinfModif+t;
1797 CDomain.Bsup = BsupModif-t;
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 //-- ------------------------------------------------------------
1805 Interval LDomain(LIG_Domain);
1807 Standard_Integer NbSolTotal=0;
1809 PeriodicInterval SolutionCircle[4];
1810 Interval SolutionLine[4];
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 ??????
1821 PeriodicInterval CDomainAndRes=CDomain.FirstIntersection(CInt1);
1823 ProjectOnLAndIntersectWithLDomain(Circle,Line
1832 CDomainAndRes=CDomain.SecondIntersection(CInt1);
1834 ProjectOnLAndIntersectWithLDomain(Circle,Line
1843 //----------------------------------------------------------------------
1844 //----------- Traitement du second intervalle Geometrique C1_Int2 ----
1845 //----------------------------------------------------------------------
1847 CDomainAndRes=CDomain.FirstIntersection(CInt2);
1849 ProjectOnLAndIntersectWithLDomain(Circle,Line
1858 //--------------------------------------------------------------------
1859 CDomainAndRes=CDomain.SecondIntersection(CInt2);
1862 ProjectOnLAndIntersectWithLDomain(Circle,Line
1880 //----------------------------------------------------------------------
1881 //-- Calcul de toutes les transitions et Positions.
1883 //-- On determine si des intervalles sont reduit a des points
1884 //-- ( Rayon * Intervalle.Length() < TolConf ) ### Modif 19 Nov Tol-->TolConf
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;
1892 for( i=0; i<NbSolTotal ; i++) {
1893 if((R * SolutionCircle[i].Length())<MaxTol
1894 && (SolutionLine[i].Length())<MaxTol) {
1896 Standard_Real t=(SolutionCircle[i].Binf+SolutionCircle[i].Bsup)*0.5;
1897 SolutionCircle[i].Binf=SolutionCircle[i].Bsup=t;
1899 t=(SolutionLine[i].Binf+SolutionLine[i].Bsup)*0.5;
1900 SolutionLine[i].Binf=SolutionLine[i].Bsup=t;
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;
1916 //----------------------------------------------------------------------
1917 //-- Traitement des intervalles (ou des points obtenus)
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;
1928 ElCLib::CircleD1(SolutionCircle[0].Binf,CircleAxis,R,P1a,Tan1);
1929 ElCLib::LineD1(SolutionLine[0].Binf,LineAxis,P2a,Tan2);
1931 Standard_Boolean Opposite=((Tan1.Dot(Tan2))<0.0)? Standard_True : Standard_False;
1934 for(i=0; i<NbSolTotal; i++ ) {
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 --]
1958 if(p1<q1 && p2>q1) {
1961 if(p1<q2 && p2>q2) {
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);
1971 SolutionCircle[i].Binf=p1;
1972 SolutionCircle[i].Bsup=p2;
1977 Standard_Real Linf=(Opposite)? SolutionLine[i].Bsup : SolutionLine[i].Binf;
1978 Standard_Real Lsup=(Opposite)? SolutionLine[i].Binf : SolutionLine[i].Bsup;
1980 //---------------------------------------------------------------
1981 //-- Si les parametres sur le cercle sont en premier
1982 //-- On doit retourner ces parametres dans l ordre croissant
1983 //---------------------------------------------------------------
1985 Standard_Real T=SolutionCircle[i].Binf;
1986 SolutionCircle[i].Binf=SolutionCircle[i].Bsup;
1987 SolutionCircle[i].Bsup=T;
1989 T=Linf; Linf=Lsup; Lsup=T;
1993 ElCLib::CircleD2(SolutionCircle[i].Binf,CircleAxis,R,P1a,Tan1,Norm1);
1994 ElCLib::LineD1(Linf,LineAxis,P2a,Tan2);
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);
2000 if(Pos1a==IntRes2d_End) {
2001 Cinf = CIRC_Domain.LastParameter();
2002 P1a = CIRC_Domain.LastPoint();
2003 Linf = ElCLib::Parameter(Line,P1a);
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);
2011 else if(Pos1a==IntRes2d_Head) {
2012 Cinf = CIRC_Domain.FirstParameter();
2013 P1a = CIRC_Domain.FirstPoint();
2014 Linf = ElCLib::Parameter(Line,P1a);
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);
2023 Cinf=NormalizeOnCircleDomain(SolutionCircle[i].Binf,CIRC_Domain);
2026 IntRes2d_IntersectionPoint NewPoint1(P1a,Linf,Cinf,T2a,T1a,ReversedParameters());
2028 if((SolutionLine[i].Length()+SolutionCircle[i].Length()) >0.0) {
2030 ElCLib::CircleD2(SolutionCircle[i].Bsup,CircleAxis,R,P1b,Tan1,Norm1);
2031 ElCLib::LineD1(Lsup,LineAxis,P2b,Tan2);
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);
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);
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);
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);
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);
2060 Csup=NormalizeOnCircleDomain(SolutionCircle[i].Bsup,CIRC_Domain);
2063 IntRes2d_IntersectionPoint NewPoint2(P1b,Lsup,Csup,T2b,T1b,ReversedParameters());
2065 if(((Abs(Csup-Cinf)*R > MaxTol) && (Abs(Lsup-Linf) > MaxTol))
2066 || (T1a.TransitionType() != T2a.TransitionType())) {
2067 //-- Verifier egalement les transitions
2069 IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2
2070 ,Opposite,ReversedParameters());
2074 if(Pos1a!=IntRes2d_Middle || Pos2a!=IntRes2d_Middle) {
2077 if(Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle) {
2084 //--Standard_Real Cmid=NormalizeOnCircleDomain(0.5*(SolutionCircle[i].Bsup+SolutionCircle[i].Binf)
2086 //--IntRes2d_IntersectionPoint NewPoint(P2a,0.5*(Linf+Lsup)
2088 //-- ,T2a,T1a,ReversedParameters());
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) {
2105 if((T1b.PositionOnCurve() == IntRes2d_Middle)
2106 && (T2b.PositionOnCurve() == IntRes2d_Middle)) {
2109 if((T1a.PositionOnCurve() == IntRes2d_Middle)
2110 && (T2a.PositionOnCurve() == IntRes2d_Middle)) {
2114 IntRes2d_Transition t1 = T1a;
2115 IntRes2d_Transition t2 = T2a;
2116 Standard_Real u1 = Pa.ParamOnFirst();
2117 Standard_Real u2 = Pa.ParamOnSecond();
2120 if(t1.PositionOnCurve() == IntRes2d_Middle) {
2121 t1.SetPosition(T1b.PositionOnCurve());
2122 u1 = Pb.ParamOnFirst();
2124 if(t2.PositionOnCurve() == IntRes2d_Middle) {
2125 t2.SetPosition(T2b.PositionOnCurve());
2126 u2 = Pb.ParamOnSecond();
2128 return(IntRes2d_IntersectionPoint(Pa.Value(),u1,u2,t1,t2,Standard_False));