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