0031939: Coding - correction of spelling errors in comments [part 4]
[occt.git] / src / IntCurve / IntCurve_IntConicConic_1.cxx
CommitLineData
b311480e 1// Created on: 1992-05-06
2// Created by: Laurent BUCHARD
3// Copyright (c) 1992-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17// a modifier le cas de 2 points confondus ( Insert a la place d'append ? )
18
42cf5bc1 19#include <ElCLib.hxx>
7fd59977 20#include <gp.hxx>
42cf5bc1 21#include <gp_Circ2d.hxx>
22#include <gp_Elips2d.hxx>
23#include <gp_Hypr2d.hxx>
24#include <gp_Lin2d.hxx>
25#include <gp_Parab2d.hxx>
26#include <gp_Pnt2d.hxx>
27#include <gp_Vec2d.hxx>
28#include <IntCurve_IConicTool.hxx>
29#include <IntCurve_IntConicConic.hxx>
7fd59977 30#include <IntCurve_IntConicConic_Tool.hxx>
42cf5bc1 31#include <IntCurve_PConic.hxx>
7fd59977 32#include <IntImpParGen.hxx>
42cf5bc1 33#include <IntRes2d_Domain.hxx>
7fd59977 34#include <IntRes2d_IntersectionPoint.hxx>
35#include <IntRes2d_IntersectionSegment.hxx>
c2b14317 36#include <IntRes2d_TypeTrans.hxx>
42cf5bc1 37#include <Precision.hxx>
38#include <Standard_ConstructionError.hxx>
69f87d09 39#include <Extrema_ExtElC2d.hxx>
7fd59977 40
41Standard_Boolean Affichage=Standard_False;
42Standard_Boolean AffichageGraph=Standard_True;
43
44//modified by NIZHNY-MKK Tue Feb 15 10:53:34 2000.BEGIN
45// #define TOLERANCE_ANGULAIRE 0.00000001
46#define TOLERANCE_ANGULAIRE 1.e-15 //the reason is at least to make an accordance between transition and position computation.
47//modified by NIZHNY-MKK Tue Feb 15 10:53:45 2000.END
48
c6541a0c 49const Standard_Real PIsur2 = 0.5*M_PI;
7fd59977 50
51//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
52IntRes2d_Position FindPositionLL(Standard_Real&,const IntRes2d_Domain&);
53const IntRes2d_IntersectionPoint SegmentToPoint( const IntRes2d_IntersectionPoint& Pa
54 ,const IntRes2d_Transition& T1a
55 ,const IntRes2d_Transition& T2a
56 ,const IntRes2d_IntersectionPoint& Pb
57 ,const IntRes2d_Transition& T1b
58 ,const IntRes2d_Transition& T2b);
59//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
60void ProjectOnC2AndIntersectWithC2Domain(const gp_Circ2d& Circle1
61 ,const gp_Circ2d& Circle2
62 ,PeriodicInterval& C1DomainAndRes
63 ,PeriodicInterval& DomainC2
64 ,PeriodicInterval* SolutionC1
65 ,PeriodicInterval* SolutionC2
66 ,Standard_Integer &NbSolTotal
67 ,const Standard_Boolean IdentCircles)
68{
69
70 if(C1DomainAndRes.IsNull()) return;
71 //-------------------------------------------------------------------------
72 //-- On cherche l intervalle correspondant sur C2
73 //-- Puis on intersecte l intervalle avec le domaine de C2
74 //-- Enfin, on cherche l intervalle correspondant sur C1
75 //--
76 Standard_Real C2inf =
77 ElCLib::CircleParameter(Circle2.Axis()
78 ,ElCLib::CircleValue(C1DomainAndRes.Binf
79 ,Circle1.Axis(),Circle1.Radius()));
80 Standard_Real C2sup =
81 ElCLib::CircleParameter(Circle2.Axis()
82 ,ElCLib::CircleValue(C1DomainAndRes.Bsup
83 ,Circle1.Axis(),Circle1.Radius()));
84
85 PeriodicInterval C2Inter(C2inf,C2sup);
86
87 if(!IdentCircles) {
c6541a0c 88 if(C2Inter.Length() > M_PI)
7fd59977 89 C2Inter.Complement();
90 }
91 else {
92 if(C2sup<=C2inf) C2sup+=PIpPI;
93 if(C2inf>=PIpPI) {
94 C2sup-=PIpPI;
95 C2inf-=PIpPI;
96 }
97 C2Inter.Binf=C2inf;
98 C2Inter.Bsup=C2sup; //--- Verifier la longueur de l'intervalle sur C2
99 C2Inter.Bsup=C2inf+C1DomainAndRes.Bsup-C1DomainAndRes.Binf;
100 }
101
102 PeriodicInterval C2InterAndDomain[2];
103
104 for(Standard_Integer i=0; i<2 ; i++) {
105 C2InterAndDomain[i]=(i==0)? DomainC2.FirstIntersection(C2Inter)
106 : DomainC2.SecondIntersection(C2Inter);
107
108 if(!C2InterAndDomain[i].IsNull()) {
109
110 Standard_Real C1inf =
111 ElCLib::CircleParameter(Circle1.Axis()
112 ,ElCLib::CircleValue(C2InterAndDomain[i].Binf
113 ,Circle2.Axis(),Circle2.Radius()));
114 Standard_Real C1sup =
115 ElCLib::CircleParameter(Circle1.Axis()
116 ,ElCLib::CircleValue(C2InterAndDomain[i].Bsup
117 ,Circle2.Axis(),Circle2.Radius()));
118
119 SolutionC1[NbSolTotal]=PeriodicInterval(C1inf,C1sup);
120 if(!IdentCircles) {
c6541a0c 121 if(SolutionC1[NbSolTotal].Length() > M_PI)
7fd59977 122 SolutionC1[NbSolTotal].Complement();
123 }
124 else {
125 if(SolutionC1[NbSolTotal].Bsup <= SolutionC1[NbSolTotal].Binf) {
126 SolutionC1[NbSolTotal].Bsup+=PIpPI;
127 }
128 if(SolutionC1[NbSolTotal].Binf>=PIpPI) {
129 SolutionC1[NbSolTotal].Binf-=PIpPI;
130 SolutionC1[NbSolTotal].Bsup-=PIpPI;
131 }
132 }
133 SolutionC2[NbSolTotal]=C2InterAndDomain[i];
134 NbSolTotal++;
135 }
136 }
137}
138//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
139//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
140void CircleCircleGeometricIntersection(const gp_Circ2d& C1
141 ,const gp_Circ2d& C2
142 ,const Standard_Real Tol
143 ,const Standard_Real TolTang
144 ,PeriodicInterval& C1_Res1
145 ,PeriodicInterval& C1_Res2
146 ,Standard_Integer& nbsol) {
147
148 Standard_Real C1_binf1,C1_binf2=0,C1_bsup1,C1_bsup2=0;
149 Standard_Real dO1O2=(C1.Location()).Distance(C2.Location());
150 Standard_Real R1=C1.Radius();
151 Standard_Real R2=C2.Radius();
152 Standard_Real AbsR1mR2=Abs(R1-R2);
153 //----------------------------------------------------------------
154 if(dO1O2 > (R1+R2+Tol)) {
155 if(dO1O2 > (R1+R2+TolTang)) {
156 nbsol=0;
157 return;
158 }
159 else {
160 C1_binf1 = 0.0;
161 C1_bsup1 = 0.0;
162 nbsol = 1;
163 }
164 }
165 //----------------------------------------------------------------
166 else if(dO1O2 <= Tol && AbsR1mR2<=Tol) {
167 nbsol=3;
168 return;
169 }
170 else {
171 //----------------------------------------------------------------
172 Standard_Real R1pR2=R1+R2;
173 Standard_Real R1pTol=R1+Tol;
174 Standard_Real R1mTol=R1-Tol;
175// Standard_Real R1R1=R1*R1;
176 Standard_Real R2R2=R2*R2;
177 Standard_Real R1pTolR1pTol=R1pTol*R1pTol;
178 Standard_Real R1mTolR1mTol=R1mTol*R1mTol;
179 Standard_Real dO1O2dO1O2=dO1O2*dO1O2;
180 Standard_Real dAlpha1;
181 //--------------------------------------------------------------- Cas
182 //-- C2 coupe le cercle C1+ (=C(x1,y1,R1+Tol))
183 //-- 1 seul segment donne par Inter C2 C1+
184 //--
185 if(dO1O2 > R1pR2-Tol) {
186 Standard_Real dx=(R1pTolR1pTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
187 Standard_Real dy=(R1pTolR1pTol-dx*dx);
188 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
189 dAlpha1=ATan2(dy,dx);
190
191 C1_binf1=-dAlpha1;
192 C1_bsup1=dAlpha1;
193 nbsol=1;
194 }
195 //--------------------------------------------------------------------
196 //-- 2 segments donnes par Inter C2 avec C1- C1 C1+
197 //-- Seul le signe de dx change si dO1O2 < Max(R1,R2)
198 //--
199 else if(dO1O2 > AbsR1mR2-Tol) { // -- +
200 //------------------- Intersection C2 C1+ --------------------------
201 Standard_Real dx=(R1pTolR1pTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
202 Standard_Real dy=(R1pTolR1pTol-dx*dx);
203 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
204
205 dAlpha1=ATan2(dy,dx);
206 C1_binf1=-dAlpha1; C1_bsup2=dAlpha1; //-- |...? ?...| Sur C1
207
208 //------------------ Intersection C2 C1- -------------------------
209 dx=(R1mTolR1mTol+dO1O2dO1O2-R2R2)/(dO1O2+dO1O2);
210 dy=(R1mTolR1mTol-dx*dx);
211 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
212 dAlpha1=ATan2(dy,dx);
213
214 C1_binf2=dAlpha1; C1_bsup1=-dAlpha1; //-- |...x x...| Sur C1
215 nbsol=2;
216 //------------------------------
217 //-- Les 2 intervalles sont ils
218 //-- en fait un seul inter ?
219 //--
220 if(dy==0) { //-- Les 2 bornes internes sont identiques
221 C1_bsup1 = C1_bsup2;
222 nbsol = 1;
223 }
224 else {
225 if(C1_binf1>C1_bsup1) {
226 dAlpha1 = C1_binf1; C1_binf1 = C1_bsup1; C1_bsup1 = dAlpha1;
227 }
228 if(C1_binf2>C1_bsup2) {
229 dAlpha1 = C1_binf2; C1_binf2 = C1_bsup2; C1_bsup2 = dAlpha1;
230 }
231 if( ((C1_binf1<=C1_bsup2) && (C1_binf1>=C1_binf2))
232 || ((C1_bsup1<=C1_bsup2) && (C1_bsup1>=C1_binf2))) {
233 if(C1_binf1 > C1_binf2) C1_binf1 = C1_binf2;
234 if(C1_binf1 > C1_bsup2) C1_binf1 = C1_bsup2;
235 if(C1_bsup1 < C1_binf2) C1_bsup1 = C1_binf2;
236 if(C1_bsup1 < C1_bsup2) C1_bsup1 = C1_bsup2;
237 nbsol=1;
238 }
239 }
240 }
241 //--------------------------------------------------------------
7fd59977 242 else {
243 if((dO1O2 > AbsR1mR2-TolTang) && (AbsR1mR2-TolTang)>0.0) {
244 C1_binf1=0.0;
245 C1_bsup1=0.0;
246 nbsol = 1;
247 }
248 else {
249 nbsol=0; return ;
250 }
251 }
252 }
253
04232180 254 //-- std::cout<<" C1_binf1:"<<C1_binf1;
255 //-- std::cout<<" C1_bsup1:"<<C1_bsup1;
256 //-- std::cout<<" C1_binf2:"<<C1_binf2;
257 //-- std::cout<<" C1_bsup2:"<<C1_bsup2<<std::endl;
7fd59977 258 //----------------------------------------------------------------
259 //-- Mise en forme des resultats :
260 //-- Les calculs ont ete fait dans le repere x1,y1, (O1,O2)
261 //-- On se ramene au repere propre a C1
262
263 gp_Vec2d Axe1=C1.XAxis().Direction();
264 gp_Vec2d AxeO1O2=gp_Vec2d(C1.Location(),C2.Location());
265
266 Standard_Real dAngle1;
267 if(AxeO1O2.Magnitude() <= gp::Resolution())
268 dAngle1=Axe1.Angle(C2.XAxis().Direction());
269 else
270 dAngle1=Axe1.Angle(AxeO1O2);
271
272 if(C1.IsDirect() == Standard_False) {
273 dAngle1 = -dAngle1;
274 }
275
276
277 C1_binf1+=dAngle1; C1_bsup1+=dAngle1;
278
279 //-- par construction aucun des segments ne peut exceder PI
280 //-- (permet de ne pas gerer trop de cas differents)
281
282 C1_Res1.SetValues(C1_binf1,C1_bsup1);
c6541a0c 283 if(C1_Res1.Length() > M_PI) C1_Res1.Complement();
7fd59977 284
285 if(nbsol==2) {
286 C1_binf2+=dAngle1; C1_bsup2+=dAngle1;
287 C1_Res2.SetValues(C1_binf2,C1_bsup2);
c6541a0c 288 if(C1_Res2.Length() > M_PI) C1_Res2.Complement();
7fd59977 289 }
290 else {
291 C1_Res2.SetNull();
292 }
293}
294//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
295//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
296void ProjectOnLAndIntersectWithLDomain(const gp_Circ2d& Circle
297 ,const gp_Lin2d& Line
298 ,PeriodicInterval& CDomainAndRes
299 ,Interval& LDomain
300 ,PeriodicInterval* CircleSolution
301 ,Interval* LineSolution
302 ,Standard_Integer &NbSolTotal
303 ,const IntRes2d_Domain& RefLineDomain
304// ,const IntRes2d_Domain& )
305 ,const IntRes2d_Domain& )
306{
307
308
309 if(CDomainAndRes.IsNull()) return;
310 //-------------------------------------------------------------------------
311 //-- On cherche l intervalle correspondant sur C2
312 //-- Puis on intersecte l intervalle avec le domaine de C2
313 //-- Enfin, on cherche l intervalle correspondant sur C1
314 //--
315
316 Standard_Real Linf=ElCLib::Parameter(Line
317 ,ElCLib::CircleValue(CDomainAndRes.Binf
318 ,Circle.Axis()
319 ,Circle.Radius()));
320 Standard_Real Lsup=ElCLib::Parameter(Line
321 ,ElCLib::CircleValue(CDomainAndRes.Bsup
322 ,Circle.Axis()
323 ,Circle.Radius()));
324
325 Interval LInter(Linf,Lsup); //-- Necessairement Borne
326
327 Interval LInterAndDomain=LDomain.IntersectionWithBounded(LInter);
328
329 if(!LInterAndDomain.IsNull) {
330
331 Standard_Real DomLinf = (RefLineDomain.HasFirstPoint())? RefLineDomain.FirstParameter() : -Precision::Infinite();
332 Standard_Real DomLsup = (RefLineDomain.HasLastPoint())? RefLineDomain.LastParameter() : Precision::Infinite();
333
334 Linf = LInterAndDomain.Binf;
335 Lsup = LInterAndDomain.Bsup;
336
337 if(Linf<DomLinf) {
338 Linf = DomLinf;
339 }
340 if(Lsup<DomLinf) {
341 Lsup = DomLinf;
342 }
343
344 if(Linf>DomLsup) {
345 Linf = DomLsup;
346 }
347 if(Lsup>DomLsup) {
348 Lsup = DomLsup;
349 }
350
351 LInterAndDomain.Binf = Linf;
352 LInterAndDomain.Bsup = Lsup;
353
354#if 0
355 Standard_Real Cinf =
356 ElCLib::CircleParameter(Circle.Axis()
357 ,ElCLib::LineValue(LInterAndDomain.Binf,
358 Line.Position()));
359 Standard_Real Csup =
360 ElCLib::CircleParameter(Circle.Axis()
361 ,ElCLib::LineValue(LInterAndDomain.Bsup
362 ,Line.Position()));
363
364 if(Cinf<CDomainAndRes.Binf) Cinf = CDomainAndRes.Binf;
365 if(Csup>CDomainAndRes.Bsup) Csup = CDomainAndRes.Bsup;
366#else
367 Standard_Real Cinf=CDomainAndRes.Binf;
368 Standard_Real Csup=CDomainAndRes.Bsup;
369#endif
370 if(Cinf>=Csup) { Cinf = CDomainAndRes.Binf; Csup = CDomainAndRes.Bsup; }
371 CircleSolution[NbSolTotal]=PeriodicInterval(Cinf,Csup);
c6541a0c 372 if(CircleSolution[NbSolTotal].Length() > M_PI)
7fd59977 373 CircleSolution[NbSolTotal].Complement();
374
375 LineSolution[NbSolTotal]=LInterAndDomain;
376 NbSolTotal++;
377 }
378}
bd05fabf
S
379
380//=======================================================================
381//function : LineCircleGeometricIntersection
382//purpose :
7fd59977 383//~~ On cherche des segments d intersection dans le `tuyau`
384//~~ R+Tol R-Tol ( Tol est TolConf : Tolerance de confusion d arc)
385//~~ On Cherche un point d intersection a une distance TolTang du cercle.
bd05fabf
S
386//=======================================================================
387void LineCircleGeometricIntersection(const gp_Lin2d& Line,
388 const gp_Circ2d& Circle,
389 const Standard_Real Tol,
390 const Standard_Real TolTang,
391 PeriodicInterval& CInt1,
392 PeriodicInterval& CInt2,
393 Standard_Integer& nbsol)
394{
7fd59977 395
396
397 Standard_Real dO1O2=Line.Distance(Circle.Location());
398 Standard_Real R=Circle.Radius();
7fd59977 399 Standard_Real RmTol=R-Tol;
400 Standard_Real binf1,binf2=0,bsup1,bsup2=0;
401
402 //----------------------------------------------------------------
403 if(dO1O2 > (R+Tol)) { //-- pas d intersection avec le 'tuyau'
404 if(dO1O2 > (R+TolTang)) {
405 nbsol=0;
406 return;
407 }
408 else {
409 binf1=0.0;
410 bsup1=0.0;
411 nbsol=1;
412 }
413 }
414 else {
415 //----------------------------------------------------------------
bd05fabf 416 Standard_Boolean b2Sol;
7fd59977 417 Standard_Real dAlpha1;
418 //---------------------------------------------------------------
419 //-- Line coupe le cercle Circle+ (=C(x1,y1,R1+Tol))
bd05fabf
S
420 b2Sol=Standard_False;
421 if (R>dO1O2+TolTang) {
422 Standard_Real aX2, aTol2;
423 //
424 aTol2=Tol*Tol;
425 aX2=4.*(R*R-dO1O2*dO1O2);
426 if (aX2>aTol2) {
427 b2Sol=!b2Sol;
428 }
429 }
430 if(dO1O2 > RmTol && !b2Sol) {
431 //if(dO1O2 > RmTol) {
7fd59977 432 Standard_Real dx=dO1O2;
433 Standard_Real dy=0.0; //(RpTol*RpTol-dx*dx); //Patch !!!
434 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
435 dAlpha1=ATan2(dy,dx);
436
437 binf1=-dAlpha1;
438 bsup1=dAlpha1;
439 nbsol=1;
440 }
441 //--------------------------------------------------------------------
442 //-- 2 segments donnes par Inter Line avec Circle- Circle+
443 //--
444 else {
445 //------------------- Intersection Line Circle+ --------------------------
446 Standard_Real dx=dO1O2;
447 Standard_Real dy=R*R-dx*dx; //(RpTol*RpTol-dx*dx); //Patch !!!
448 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
449
450 dAlpha1=ATan2(dy,dx);
451 binf1=-dAlpha1; bsup2=dAlpha1; //-- |...? ?...| Sur C1
452
453 //------------------ Intersection Line Circle- -------------------------
454 dy=R*R-dx*dx; //(RmTol*RmTol-dx*dx); //Patch !!!
455 dy=(dy>=0.0)? Sqrt(dy) : 0.0;
456 dAlpha1=ATan2(dy,dx);
457
458 binf2=dAlpha1; bsup1=-dAlpha1; //-- |...x x...| Sur C1
459
460 if((dAlpha1*R)<(Max(Tol,TolTang))) {
461 bsup1 = bsup2;
462 nbsol = 1;
463 }
464 else {
465 nbsol=2;
466 }
467 }
468 }
469 //--------------------------------------------------------------
470 //-- Mise en forme des resultats :
471 //-- Les calculs ont ete fait dans le repere x1,y1, (O1,O2)
472 //-- On se ramene au repere propre a C1
473
474 Standard_Real dAngle1=(Circle.XAxis().Direction()).Angle(Line.Direction());
475
476#if 0
477 //---------------------------------------------
478 //-- Si le cercle est indirect alors l origine
479 //-- est vue en -dAngle1.
480 //--
481 if(Circle.IsDirect() == Standard_False) {
482 dAngle1 = -dAngle1;
483 }
484#endif
485
486
487 Standard_Real a,b,c,d;
488 Line.Coefficients(a,b,c);
489
490 d = a*Circle.Location().X() + b*Circle.Location().Y() + c;
491
492 if(d>0.0) dAngle1+= PIsur2;
493 else dAngle1-= PIsur2;
494
495
496 if(dAngle1<0.0) dAngle1+=PIpPI;
497 else if(dAngle1>PIpPI) dAngle1-=PIpPI;
498
499
500 binf1+=dAngle1; bsup1+=dAngle1;
501
502 //-- par construction aucun des segments ne peut exceder PI
503 //-- (permet de ne pas gerer trop de cas differents)
504
505 if(Circle.IsDirect() == Standard_False) {
506 Standard_Real t=binf1; binf1=bsup1; bsup1=t;
507 binf1 = -binf1;
508 bsup1 = -bsup1;
509 }
510
511
512 CInt1.SetValues(binf1,bsup1);
c6541a0c 513 if(CInt1.Length() > M_PI) CInt1.Complement();
7fd59977 514
515
516 if(nbsol==2) {
517 binf2+=dAngle1; bsup2+=dAngle1;
518
519 if(Circle.IsDirect() == Standard_False) {
520 Standard_Real t=binf2; binf2=bsup2; bsup2=t;
521 binf2 = -binf2;
522 bsup2 = -bsup2;
523 }
524
525 CInt2.SetValues(binf2,bsup2);
c6541a0c 526 if(CInt2.Length() > M_PI) CInt2.Complement();
7fd59977 527 }
528// Modified by Sergey KHROMOV - Thu Oct 26 17:51:05 2000 Begin
529 else {
530 if (CInt1.Bsup > PIpPI && CInt1.Binf < PIpPI) {
531 nbsol = 2;
532 binf2 = CInt1.Binf;
533 bsup2 = PIpPI;
534 binf1 = 0.;
535 CInt1.SetValues(binf1,CInt1.Bsup - PIpPI);
c6541a0c 536 if(CInt1.Length() > M_PI) CInt1.Complement();
7fd59977 537 CInt2.SetValues(binf2,bsup2);
c6541a0c 538 if(CInt2.Length() > M_PI) CInt2.Complement();
7fd59977 539 }
540 }
541// Modified by Sergey KHROMOV - Thu Oct 26 17:51:13 2000 End
542}
543//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
544//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
545void DomainIntersection(const IntRes2d_Domain& Domain
546 ,const Standard_Real U1inf
547 ,const Standard_Real U1sup
548 ,Standard_Real& Res1inf
549 ,Standard_Real& Res1sup
550 ,IntRes2d_Position& PosInf
551 ,IntRes2d_Position& PosSup) {
552
553 if(Domain.HasFirstPoint()) {
554 if(U1sup < (Domain.FirstParameter()-Domain.FirstTolerance())) {
e784d865 555 Res1inf=1; Res1sup=-1;
556 return;
557 }
7fd59977 558 if(U1inf>(Domain.FirstParameter()+Domain.FirstTolerance())) {
e784d865 559 Res1inf=U1inf;
560 PosInf=IntRes2d_Middle;
7fd59977 561 }
562 else {
563 Res1inf=Domain.FirstParameter();
564 PosInf=IntRes2d_Head;
565 }
566 }
567 else {
568 Res1inf=U1inf;
569 PosInf=IntRes2d_Middle;
570 }
571
572 if(Domain.HasLastPoint()) {
573 if(U1inf >(Domain.LastParameter()+Domain.LastTolerance())) {
574 Res1inf=1; Res1sup=-1;
575 return;
576 }
577 if(U1sup<(Domain.LastParameter()-Domain.LastTolerance())) {
e784d865 578 Res1sup=U1sup;
579 PosSup=IntRes2d_Middle;
7fd59977 580 }
581 else {
582 Res1sup=Domain.LastParameter();
583 PosSup=IntRes2d_End;
584 }
585 }
586 else {
587 Res1sup=U1sup;
588 PosSup=IntRes2d_Middle;
589 }
590 //-- Si un des points est en bout ,
591 //-- on s assure que les parametres sont corrects
592 if(Res1inf>Res1sup) {
593 if(PosSup==IntRes2d_Middle) {
594 Res1sup=Res1inf;
595 }
596 else {
597 Res1inf=Res1sup;
598 }
599 }
600 //--- Traitement des cas ou une intersection vraie est dans la tolerance
601 //-- d un des bouts
c2b14317 602 /*if(PosInf==IntRes2d_Head) {
7fd59977 603 if(Res1sup <= (Res1inf+Domain.FirstTolerance())) {
604 Res1sup=Res1inf;
e784d865 605 PosSup=IntRes2d_Head;
606 }
7fd59977 607 }
608 if(PosSup==IntRes2d_End) {
609 if(Res1inf >= (Res1sup-Domain.LastTolerance())) {
610 Res1inf=Res1sup;
611 PosInf=IntRes2d_End;
612 }
c2b14317 613 }*/
7fd59977 614}
615//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
616//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
617void LineLineGeometricIntersection(const gp_Lin2d& L1
618 ,const gp_Lin2d& L2
619 ,const Standard_Real Tol
620 ,Standard_Real& U1
621 ,Standard_Real& U2
622 ,Standard_Real& SinDemiAngle
623 ,Standard_Integer& nbsol) {
624
625 Standard_Real U1x=L1.Direction().X();
626 Standard_Real U1y=L1.Direction().Y();
627 Standard_Real U2x=L2.Direction().X();
628 Standard_Real U2y=L2.Direction().Y();
629 Standard_Real Uo21x = L2.Location().X() - L1.Location().X();
630 Standard_Real Uo21y = L2.Location().Y() - L1.Location().Y();
631
632 Standard_Real D=U1y*U2x-U1x*U2y;
633
634//modified by NIZHNY-MKK Tue Feb 15 10:54:04 2000.BEGIN
635// if(Abs(D)<1e-15) { //-- Droites //
636 if(Abs(D) < TOLERANCE_ANGULAIRE) {
637//modified by NIZHNY-MKK Tue Feb 15 10:54:11 2000.END
638 D=U1y*Uo21x - U1x*Uo21y;
639 nbsol=(Abs(D)<=Tol)? 2 : 0;
640 }
641 else {
642 U1=(Uo21y * U2x - Uo21x * U2y)/D;
643 U2=(Uo21y * U1x - Uo21x * U1y)/D;
644
645 //------------------- Calcul du Sin du demi angle entre L1 et L2
646 //----
647 if(D<0.0) D=-D;
648 if(D>1.0) D=1.0; //-- Deja vu !
649 SinDemiAngle=Sin(0.5*ASin(D));
650 nbsol=1;
651 }
652}
653//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
654//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
655/*IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Lin2d& L1
656 ,const IntRes2d_Domain& D1
657 ,const gp_Lin2d& L2
658 ,const IntRes2d_Domain& D2
659 ,const Standard_Real TolConf
660 ,const Standard_Real Tol) {
661 Perform(L1,D1,L2,D2,TolConf,Tol);
662}
663
664
665IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Lin2d& L1
666 ,const IntRes2d_Domain& D1
667 ,const gp_Circ2d& C2
668 ,const IntRes2d_Domain& D2
669 ,const Standard_Real TolConf
670 ,const Standard_Real Tol) {
671
672 Perform(L1,D1,C2,D2,TolConf,Tol);
673}
674
675
676IntCurve_IntConicConic::IntCurve_IntConicConic(const gp_Circ2d& C1
677 ,const IntRes2d_Domain& D1
678 ,const gp_Circ2d& C2
679 ,const IntRes2d_Domain& D2
680 ,const Standard_Real TolConf
681 ,const Standard_Real Tol) {
682 SetReversedParameters(Standard_False);
683 Perform(C1,D1,C2,D2,TolConf,Tol);
684}*/ //amv OCC12547
685//----------------------------------------------------------------------
686void IntCurve_IntConicConic::Perform(const gp_Circ2d& Circle1
687 ,const IntRes2d_Domain& DomainCirc1
688 ,const gp_Circ2d& _Circle2
689 ,const IntRes2d_Domain& _DomainCirc2
690 ,const Standard_Real TolConf,const Standard_Real Tol) {
691
692
693//-- TRES TRES MAL FAIT A REPRENDRE UN JOUR .... (lbr Octobre 98)
694 gp_Circ2d Circle2=_Circle2;
695 IntRes2d_Domain DomainCirc2=_DomainCirc2;
696 Standard_Boolean IndirectCircles=Standard_False;
8696d65d 697 if(Circle1.IsDirect() != _Circle2.IsDirect())
698 {
7fd59977 699 IndirectCircles=Standard_True;
700 Circle2=_Circle2.Reversed();
701 DomainCirc2.SetValues(_DomainCirc2.LastPoint(),
8696d65d 702 PIpPI-_DomainCirc2.LastParameter(),
703 _DomainCirc2.LastTolerance(),
704 _DomainCirc2.FirstPoint(),
705 PIpPI-_DomainCirc2.FirstParameter(),
706 _DomainCirc2.FirstTolerance());
7fd59977 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;
3062fdf9 725 if(deltat>=PIpPI)
726 {
727 // make deltat not including the upper limit
728 deltat=NextAfter(PIpPI, 0.);
729 }
7fd59977 730
8696d65d 731 while(C1Domain.Binf >= PIpPI)
732 C1Domain.Binf-=PIpPI;
733 while(C1Domain.Binf < 0.0)
734 C1Domain.Binf+=PIpPI;
735
7fd59977 736 C1Domain.Bsup=C1Domain.Binf+deltat;
737
738 PeriodicInterval C2Domain(DomainCirc2);
739 deltat = C2Domain.Bsup-C2Domain.Binf;
8696d65d 740 if(deltat>=PIpPI)
741 {
3062fdf9 742 deltat=NextAfter(PIpPI, 0.);
743 }
8696d65d 744
745 while(C2Domain.Binf >= PIpPI)
746 C2Domain.Binf-=PIpPI;
747 while(C2Domain.Binf < 0.0)
748 C2Domain.Binf+=PIpPI;
7fd59977 749
7fd59977 750 C2Domain.Bsup=C2Domain.Binf+deltat;
751
752 Standard_Boolean IdentCircles=Standard_False;
753
8696d65d 754 if(nbsol>2)
755 {
7fd59977 756 //-- Les 2 cercles sont confondus a Tol pres
757 C1_Int1.SetValues(0,PIpPI);
758 C1_Int2.SetNull();
759 //---------------------------------------------------------------
760 //-- Flag utilise pour specifier que les intervalles manipules
761 //-- peuvent etre de longueur superieure a pi.
762 //-- Pour des cercles non identiques, on a necessairement cette
763 //-- condition sur les resultats de l intersection geometrique
764 //-- ce qui permet de normaliser rapidement les intervalles.
765 //-- ex: -1 4 -> longueur > PI
766 //-- donc -1 4 devient 4 , 2*pi-1
767 //---------------------------------------------------------------
768 IdentCircles=Standard_True;
769 }
770
771 Standard_Integer NbSolTotal=0;
772 PeriodicInterval SolutionC1[4];
773 PeriodicInterval SolutionC2[4];
774
775 //----------------------------------------------------------------------
776 //----------- Traitement du premier intervalle Geometrique C1_Int1 ----
777 //----------------------------------------------------------------------
778 //-- NbSolTotal est incremente a chaque Intervalle solution.
779 //-- On stocke les intervalles dans les tableaux : SolutionC1(C2)
780 //-- Dimensionnes a 4 elements.
781 //-- des Exemples faciles donnent 3 Intersections
782 //-- des Problemes numeriques peuvent en donner 4 ??????
783 //--
784 PeriodicInterval C1DomainAndRes=C1Domain.FirstIntersection(C1_Int1);
785
786 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
787 ,C1DomainAndRes
788 ,C2Domain
789 ,SolutionC1,SolutionC2
790 ,NbSolTotal
791 ,IdentCircles);
792 //----------------------------------------------------------------------
793 //-- Seconde Intersection : Par exemple : 2*PI-1 2*PI+1
794 //-- Intersecte avec 0.5 2*PI-0.5
795 //-- Donne les intervalles : 0.5,1 et 2*PI-1,2*PI-0.5
796 //--
797 C1DomainAndRes=C1Domain.SecondIntersection(C1_Int1);
798
799 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
800 ,C1DomainAndRes
801 ,C2Domain
802 ,SolutionC1,SolutionC2
803 ,NbSolTotal
804 ,IdentCircles);
805
806 //----------------------------------------------------------------------
807 //----------- Traitement du second intervalle Geometrique C1_Int2 ----
808 //----------------------------------------------------------------------
8696d65d 809 if(nbsol==2)
810 {
7fd59977 811 C1DomainAndRes=C1Domain.FirstIntersection(C1_Int2);
812
813 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
814 ,C1DomainAndRes
815 ,C2Domain
816 ,SolutionC1,SolutionC2
817 ,NbSolTotal
818 ,IdentCircles);
819 //--------------------------------------------------------------------
820 C1DomainAndRes=C1Domain.SecondIntersection(C1_Int2);
821
822 ProjectOnC2AndIntersectWithC2Domain(Circle1,Circle2
823 ,C1DomainAndRes
824 ,C2Domain
825 ,SolutionC1,SolutionC2
826 ,NbSolTotal
827 ,IdentCircles);
828 }
829 //----------------------------------------------------------------------
830 //-- Calcul de toutes les transitions et Positions.
831 //--
832 //----------------------------------------------------------------------
833 //-- On determine si des intervalles sont reduit a des points
834 //-- ( Rayon * Intervalle.Length() < Tol )
835 //--
836 Standard_Real R1=Circle1.Radius();
837 Standard_Real R2=Circle2.Radius();
838 Standard_Real Tol2=Tol+Tol; //---- Pour eviter de toujours retourner
839 //des segments
840 Standard_Integer i ;
8696d65d 841 if(Tol < (1e-10))
842 Tol2 = 1e-10;
843
844 for( i=0; i<NbSolTotal ; i++)
845 {
846 if(((R1 * SolutionC1[i].Length()) <=Tol2) &&
847 ((R2 * SolutionC2[i].Length())<=Tol2))
848 {
7fd59977 849 Standard_Real t=(SolutionC1[i].Binf+SolutionC1[i].Bsup)*0.5;
850 SolutionC1[i].Binf=SolutionC1[i].Bsup=t;
8696d65d 851
7fd59977 852 t=(SolutionC2[i].Binf+SolutionC2[i].Bsup)*0.5;
853 SolutionC2[i].Binf=SolutionC2[i].Bsup=t;
854 }
855 }
856
857 //----------------------------------------------------------------------
858 //-- Traitement des intervalles (ou des points obtenus)
859 //--
860 gp_Ax22d Axis2C1=Circle1.Axis();
861 gp_Ax22d Axis2C2=Circle2.Axis();
862 gp_Pnt2d P1a,P1b,P2a,P2b;
863 gp_Vec2d Tan1,Tan2,Norm1,Norm2;
864 IntRes2d_Transition T1a,T1b,T2a,T2b;
865 IntRes2d_Position Pos1a,Pos1b,Pos2a,Pos2b;
866
9fd2d2c3 867 Standard_Boolean isOpposite =
8696d65d 868 ((Circle1.Location().SquareDistance(Circle2.Location())) > (R1*R1+R2*R2)) ?
869 Standard_True : Standard_False;
7fd59977 870
04232180 871 //if(Circle1.IsDirect()) { std::cout<<" C1 Direct"<<std::endl; } else { std::cout<<" C1 INDirect"<<std::endl; }
872 //if(Circle2.IsDirect()) { std::cout<<" C2 Direct"<<std::endl; } else { std::cout<<" C2 INDirect"<<std::endl; }
7fd59977 873
8696d65d 874 for(i=0; i<NbSolTotal; i++)
875 {
9fd2d2c3 876 Standard_Real C2inf = isOpposite ? SolutionC2[i].Bsup : SolutionC2[i].Binf;
877 Standard_Real C2sup = isOpposite ? SolutionC2[i].Binf : SolutionC2[i].Bsup;
8696d65d 878 Standard_Real C1tinf = SolutionC1[i].Binf, C2tinf = C2inf;
879 Standard_Real C1inf=NormalizeOnCircleDomain(C1tinf,DomainCirc1);
880 C2inf=NormalizeOnCircleDomain(C2tinf,DomainCirc2);
7fd59977 881
8696d65d 882 Standard_Boolean isOutOfRange = Standard_False;
883 if(C1inf < DomainCirc1.FirstParameter())
884 {
885 if(C1tinf < DomainCirc1.FirstParameter())
886 {
887 C1inf = DomainCirc1.FirstParameter();
888 isOutOfRange = Standard_True;
889 }
890 else
891 {
892 C1inf = C1tinf;
893 }
894 }
7fd59977 895
8696d65d 896 if(C1inf > DomainCirc1.LastParameter())
897 {
898 if(C1tinf > DomainCirc1.LastParameter())
899 {
900 C1inf = DomainCirc1.LastParameter();
901 isOutOfRange = Standard_True;
902 }
903 else
904 {
905 C1inf = C1tinf;
906 }
907 }
908
909 if(C2inf < DomainCirc2.FirstParameter())
910 {
911 if(C2tinf < DomainCirc2.FirstParameter())
912 {
913 C2inf = DomainCirc2.FirstParameter();
914 isOutOfRange = Standard_True;
915 }
916 else
917 {
918 C2inf = C2tinf;
919 }
920 }
921
922 if(C2inf > DomainCirc2.LastParameter())
923 {
924 if(C2tinf > DomainCirc2.LastParameter())
925 {
926 C2inf = DomainCirc2.LastParameter();
927 isOutOfRange = Standard_True;
928 }
929 else
930 {
931 C2inf = C2tinf;
932 }
933 }
934
935 if(isOutOfRange)
936 {
937 gp_Pnt2d aP1, aP2;
938 gp_Vec2d aV11, aV12;
939 gp_Vec2d aV21, aV22;
940
941 ElCLib::CircleD2(C1inf,Axis2C1,R1,aP1,aV11,aV12);
942 ElCLib::CircleD2(C2inf,Axis2C2,R2,aP2,aV21,aV22);
943
944 if(aP1.SquareDistance(aP2) > Tol2*Tol2)
945 {//there are not any solutions in given parametric range.
946 continue;
947 }
948 }
949
950 if(IndirectCircles)
951 {
7fd59977 952 ElCLib::CircleD2(C1inf,Axis2C1,R1,P1a,Tan1,Norm1);
953 ElCLib::CircleD2(C2inf,Axis2C2,R2,P2a,Tan2,Norm2);
954 Tan2.Reverse();
955
956 IntImpParGen::DeterminePosition(Pos1a,DomainCirc1,P1a,C1inf);
957 IntImpParGen::DeterminePosition(Pos2a,_DomainCirc2,P2a,PIpPI-C2inf);
958 Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
959
960
961 IntRes2d_IntersectionPoint NewPoint1(P1a,C1inf,PIpPI-C2inf,T1a,T2a,Standard_False);
962
8696d65d 963 if((SolutionC1[i].Length()>0.0 ) || (SolutionC2[i].Length() >0.0))
964 {
965 //-- On traite un intervalle non reduit a un point
966 Standard_Real C1sup=NormalizeOnCircleDomain(SolutionC1[i].Bsup,DomainCirc1);
967 if(C1sup<C1inf) C1sup+=PIpPI;
968 C2sup=NormalizeOnCircleDomain(C2sup,DomainCirc2);
969
970 ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1);
971 ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
972 Tan2.Reverse();
973
974 IntImpParGen::DeterminePosition(Pos1b,DomainCirc1,P1b,C1sup);
975 IntImpParGen::DeterminePosition(Pos2b,_DomainCirc2,P2b,PIpPI-C2sup);
976 Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
977
978 //--------------------------------------------------
979
9fd2d2c3 980 if (isOpposite)
8696d65d 981 {
982 if(nbsol!=3)
983 {
984 if(C2inf<C2sup)
985 C2inf+=PIpPI;
986 }
987 }
988 else
989 {
990 if(nbsol!=3)
991 {
992 if(C2sup<C2inf) C2sup+=PIpPI;
993 }
994 }
995
996 IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,PIpPI-C2sup,T1b,T2b,Standard_False);
9fd2d2c3 997 IntRes2d_IntersectionSegment NewSeg (NewPoint1,NewPoint2, !isOpposite, Standard_False);
8696d65d 998 Append(NewSeg);
7fd59977 999 }
8696d65d 1000 else
1001 {
1002 Append(NewPoint1);
7fd59977 1003 }
7fd59977 1004 }
8696d65d 1005 else
1006 {
7fd59977 1007 ElCLib::CircleD2(C1inf,Axis2C1,R1,P1a,Tan1,Norm1);
1008 ElCLib::CircleD2(C2inf,Axis2C2,R2,P2a,Tan2,Norm2);
1009
1010 IntImpParGen::DeterminePosition(Pos1a,DomainCirc1,P1a,C1inf);
1011 IntImpParGen::DeterminePosition(Pos2a,DomainCirc2,P2a,C2inf);
1012 Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
1013
1014
1015 IntRes2d_IntersectionPoint NewPoint1(P1a,C1inf,C2inf,T1a,T2a,Standard_False);
1016
8696d65d 1017 if((SolutionC1[i].Length()>0.0 ) || (SolutionC2[i].Length() >0.0))
1018 {
1019 //-- On traite un intervalle non reduit a un point
1020 Standard_Real C1sup=NormalizeOnCircleDomain(SolutionC1[i].Bsup,DomainCirc1);
1021 if(C1sup<C1inf) C1sup+=PIpPI;
1022 C2sup=NormalizeOnCircleDomain(C2sup,DomainCirc2);
1023
1024 ElCLib::CircleD2(C1sup,Axis2C1,R1,P1b,Tan1,Norm1);
1025 ElCLib::CircleD2(C2sup,Axis2C2,R2,P2b,Tan2,Norm2);
1026
1027 IntImpParGen::DeterminePosition(Pos1b,DomainCirc1,P1b,C1sup);
1028 IntImpParGen::DeterminePosition(Pos2b,DomainCirc2,P2b,C2sup);
1029 Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
1030
1031 //--------------------------------------------------
1032
9fd2d2c3 1033 if (isOpposite)
8696d65d 1034 {
8696d65d 1035 if(C2inf<C2sup)
1036 C2inf+=PIpPI;
8696d65d 1037 }
1038 else
1039 {
8696d65d 1040 if(C2sup<C2inf)
1041 C2sup+=PIpPI;
8696d65d 1042 }
1043
1044 IntRes2d_IntersectionPoint NewPoint2(P1b,C1sup,C2sup,T1b,T2b,Standard_False);
9fd2d2c3 1045 IntRes2d_IntersectionSegment NewSeg(NewPoint1,NewPoint2,isOpposite,Standard_False);
8696d65d 1046 Append(NewSeg);
7fd59977 1047 }
8696d65d 1048 else
1049 {
1050 Append(NewPoint1);
7fd59977 1051 }
1052 }
1053 }
1054}
1055//----------------------------------------------------------------------
1056IntRes2d_Position FindPositionLL(Standard_Real &Param
c2b14317
G
1057 ,const IntRes2d_Domain& Domain)
1058{
1059 Standard_Real aDPar = Precision::Infinite();
1060 IntRes2d_Position aPos = IntRes2d_Middle;
1061 Standard_Real aResPar = Param;
7fd59977 1062 if(Domain.HasFirstPoint()) {
c2b14317
G
1063 aDPar = Abs(Param-Domain.FirstParameter());
1064 if( aDPar <= Domain.FirstTolerance()) {
1065 aResPar=Domain.FirstParameter();
1066 aPos = IntRes2d_Head;
1067
7fd59977 1068 }
1069 }
1070 if(Domain.HasLastPoint()) {
c2b14317
G
1071 Standard_Real aD2 = Abs(Param-Domain.LastParameter());
1072 if( aD2 <= Domain.LastTolerance() && (aPos == IntRes2d_Middle || aD2 < aDPar ))
1073 {
1074 aResPar=Domain.LastParameter();
1075 aPos = IntRes2d_End;
7fd59977 1076 }
1077 }
c2b14317
G
1078 Param = aResPar;
1079 return aPos;
7fd59977 1080}
c2b14317
G
1081//--------------------------------------------------------------------
1082//gka 0022833
1083// Method to compute of point of intersection for case
1084//when specified domain less than specified tolerance for intersection
1085static inline void getDomainParametrs(const IntRes2d_Domain& theDomain,
1086 Standard_Real& theFirst,
1087 Standard_Real& theLast,
1088 Standard_Real& theTol1,
1089 Standard_Real& theTol2)
1090{
1091 theFirst = (theDomain.HasFirstPoint() ? theDomain.FirstParameter() : -Precision::Infinite());
1092 theLast = (theDomain.HasLastPoint() ? theDomain.LastParameter() : Precision::Infinite());
1093 theTol1 = (theDomain.HasFirstPoint() ? theDomain.FirstTolerance() : 0.);
1094 theTol2 = (theDomain.HasLastPoint() ? theDomain.LastTolerance() : 0.);
1095}
1096
1097
420399e3 1098//=======================================================================
1099//function : computeIntPoint
1100//purpose :
1101//=======================================================================
c2b14317 1102static Standard_Boolean computeIntPoint(const IntRes2d_Domain& theCurDomain,
420399e3 1103 const IntRes2d_Domain& theDomainOther,
1104 const gp_Lin2d& theCurLin,
1105 const gp_Lin2d& theOtherLin,
1106 Standard_Real theCosT1T2,
1107 Standard_Real theParCur, Standard_Real theParOther,
1108 Standard_Real& theResInf, Standard_Real& theResSup,
1109 Standard_Integer theNum,
1110 IntRes2d_TypeTrans theCurTrans,
1111 IntRes2d_IntersectionPoint& theNewPoint)
c2b14317
G
1112{
1113 if(fabs(theResSup-theParCur) > fabs(theResInf-theParCur))
1114 theResSup = theResInf;
1115
1116 Standard_Real aRes2 = theParOther + (theResSup - theParCur) * theCosT1T2;
1117
420399e3 1118 Standard_Real aFirst2, aLast2, aTol21, aTol22, aTol11, aTol12 ;
1119
1120 getDomainParametrs(theDomainOther,aFirst2, aLast2, aTol21, aTol22);
1121
1122 if( aRes2 < aFirst2 - aTol21 || aRes2 > aLast2 + aTol22 ) {
1123 return Standard_False;
1124 }
c2b14317
G
1125
1126 //------ compute parameters of intersection point --
1127 IntRes2d_Transition aT1,aT2;
1128 IntRes2d_Position aPos1a = FindPositionLL(theResSup,theCurDomain);
1129 IntRes2d_Position aPos2a = FindPositionLL(aRes2,theDomainOther);
1130 IntRes2d_TypeTrans anOtherTrans = ( theCurTrans == IntRes2d_Out ?
1131 IntRes2d_In : ( theCurTrans == IntRes2d_In ? IntRes2d_Out : IntRes2d_Undecided ) );
1132
1133 if( theCurTrans != IntRes2d_Undecided )
1134 {
1135 aT1.SetValue(Standard_False, aPos1a, theCurTrans);
1136 aT2.SetValue(Standard_False, aPos2a, anOtherTrans);
1137 }
1138 else
1139 {
1140 Standard_Boolean anOpposite = theCosT1T2 < 0.;
1141 aT1.SetValue(Standard_False,aPos1a,IntRes2d_Unknown,anOpposite);
1142 aT2.SetValue(Standard_False,aPos2a,IntRes2d_Unknown,anOpposite);
1143 }
1144 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1145 //--------------------------------------------------
1146 //gka bug 0022833
1147 Standard_Real aResU1 = theParCur;
1148 Standard_Real aResU2 = theParOther;
1149
1150 Standard_Real aFirst1, aLast1;
420399e3 1151 getDomainParametrs(theCurDomain,aFirst1, aLast1, aTol11, aTol12);
c2b14317
G
1152
1153 Standard_Boolean isInside1 = (theParCur >= aFirst1 && theParCur <= aLast1);
1154 Standard_Boolean isInside2 = (theParOther >= aFirst2 && theParOther <= aLast2);
1155
1156 if(!isInside1 || !isInside2)
1157 {
1158 if(isInside1)
1159 {
1160 gp_Pnt2d Pt1=ElCLib::Value(aRes2,theOtherLin);
1161 aResU2 = aRes2;
1162 Standard_Real aPar1 = ElCLib::Parameter(theCurLin,Pt1);
1163 aResU1 =((aPar1 >= aFirst1 && aPar1<= aLast1) ? aPar1 : theResSup);
1164
1165 }
1166 else if(isInside2)
1167 {
1168 gp_Pnt2d aPt1=ElCLib::Value(theResSup,theCurLin);
1169 aResU1 = theResSup;
1170 Standard_Real aPar2 = ElCLib::Parameter(theOtherLin,aPt1);
1171 aResU2= ((aPar2 >= aFirst2 && aPar2<= aLast2) ? aPar2 : aRes2);
1172 }
1173 else
1174 {
420399e3 1175 //PKVf
1176 // check that parameters are within range on both curves
1177 if ( theParCur < aFirst1-aTol11 || theParCur > aLast1+aTol12 ||
1178 theParOther < aFirst2-aTol21 || theParOther > aLast2+aTol22) {
1179 return Standard_False;
1180 }
1181 //PKVt
c2b14317
G
1182 aResU1 = theResSup;
1183 aResU2= aRes2;
1184 }
1185 }
1186 gp_Pnt2d aPres((ElCLib::Value(aResU1,theCurLin).XY() + ElCLib::Value(aResU2,theOtherLin).XY()) * 0.5 );
1187 if(theNum == 1 )
1188 theNewPoint.SetValues(aPres, aResU1, aResU2 ,aT1, aT2, Standard_False);
1189 else
1190 theNewPoint.SetValues(aPres, aResU2, aResU1 ,aT2, aT1, Standard_False);
1191 return Standard_True;
1192}
1193
ba5ab97f 1194//=======================================================================
1195//function : CheckLLCoincidence
1196//purpose : Returns true if input are trimmed curves and they coincide
1197// within tolerance
1198//=======================================================================
1199static Standard_Boolean CheckLLCoincidence(const gp_Lin2d& L1,
1200 const gp_Lin2d& L2,
1201 const IntRes2d_Domain& Domain1,
1202 const IntRes2d_Domain& Domain2,
1203 const Standard_Real theTol)
1204{
1205 Standard_Boolean isFirst1 = (Domain1.HasFirstPoint() &&
1206 L2.Distance(Domain1.FirstPoint()) < theTol);
1207 Standard_Boolean isLast1 = (Domain1.HasLastPoint() &&
1208 L2.Distance(Domain1.LastPoint()) < theTol);
1209 if (isFirst1 && isLast1)
1210 return Standard_True;
1211 Standard_Boolean isFirst2 = (Domain2.HasFirstPoint() &&
1212 L1.Distance(Domain2.FirstPoint()) < theTol);
1213 Standard_Boolean isLast2 = (Domain2.HasLastPoint() &&
1214 L1.Distance(Domain2.LastPoint()) < theTol);
1215 return isFirst2 && isLast2;
1216}
1217
7fd59977 1218//----------------------------------------------------------------------
1219void IntCurve_IntConicConic::Perform(const gp_Lin2d& L1
c2b14317 1220 ,const IntRes2d_Domain& Domain1
7fd59977 1221 ,const gp_Lin2d& L2
1222 ,const IntRes2d_Domain& Domain2
1223 ,const Standard_Real,const Standard_Real TolR) {
1224 this->ResetFields();
1225
1226 //-- Coordonnees du point d intersection sur chacune des 2 droites
1227 Standard_Real U1,U2;
1228 //-- Nombre de points solution : 1 : Intersection
1229 //-- 0 : Non Confondues
1230 //-- 2 : Confondues a la tolerance pres
1231 Standard_Integer nbsol;
1232 IntRes2d_IntersectionPoint PtSeg1,PtSeg2;
e784d865 1233 Standard_Real aHalfSinL1L2;
7fd59977 1234 Standard_Real Tol = TolR;
6b52f125 1235 if(Tol < Precision::PConfusion())
1236 Tol = Precision::PConfusion();
7fd59977 1237
e784d865 1238 LineLineGeometricIntersection(L1,L2,Tol,U1,U2,aHalfSinL1L2,nbsol);
7fd59977 1239
1240 gp_Vec2d Tan1=L1.Direction();
1241 gp_Vec2d Tan2=L2.Direction();
c2b14317
G
1242
1243 Standard_Real aCosT1T2 = Tan1.Dot(Tan2);
9fd2d2c3 1244 Standard_Boolean isOpposite = (aCosT1T2 < 0.0) ? Standard_True : Standard_False;
7fd59977 1245
1246 done=Standard_True;
1247
ba5ab97f 1248 if(nbsol==1 && CheckLLCoincidence(L1, L2, Domain1, Domain2, Tol))
1249 nbsol = 2;
1250
7fd59977 1251 if(nbsol==1) {
1252 //---------------------------------------------------
1253 //-- d: distance du point I a partir de laquelle les
1254 //-- points de parametre U1+d et U2+-d sont ecartes
1255 //-- d une distance superieure a Tol.
1256 //---------------------------------------------------
1257 IntRes2d_Position Pos1a,Pos2a,Pos1b,Pos2b;
e784d865 1258 Standard_Real d = 0.5 * Tol / aHalfSinL1L2;
7fd59977 1259 Standard_Real U1inf=U1-d;
1260 Standard_Real U1sup=U1+d;
1261 Standard_Real U1mU2=U1-U2;
1262 Standard_Real U1pU2=U1+U2;
1263 Standard_Real Res1inf,Res1sup;
1264 Standard_Real ProdVectTan;
1265
1266
1267 //---------------------------------------------------
1268 //-- On agrandit la zone U1inf U1sup pour tenir compte
1269 //-- des tolerances des points en bout
1270 //--
1271 if(Domain1.HasFirstPoint()) {
1272 if(L2.Distance(Domain1.FirstPoint()) < Domain1.FirstTolerance()) {
1273 if(U1inf > Domain1.FirstParameter()) {
1274 U1inf = Domain1.FirstParameter();
1275 }
1276 if(U1sup < Domain1.FirstParameter()) {
1277 U1sup = Domain1.FirstParameter();
1278 }
1279 }
1280 }
1281 if(Domain1.HasLastPoint()) {
1282 if(L2.Distance(Domain1.LastPoint()) < Domain1.LastTolerance()) {
1283 if(U1inf > Domain1.LastParameter()) {
1284 U1inf = Domain1.LastParameter();
1285 }
1286 if(U1sup < Domain1.LastParameter()) {
1287 U1sup = Domain1.LastParameter();
1288 }
1289 }
1290 }
1291 if(Domain2.HasFirstPoint()) {
1292 if(L1.Distance(Domain2.FirstPoint()) < Domain2.FirstTolerance()) {
1293 Standard_Real p = ElCLib::Parameter(L1,Domain2.FirstPoint());
1294 if(U1inf > p) {
1295 U1inf = p;
1296 }
1297 if(U1sup < p) {
1298 U1sup = p;
1299 }
1300 }
1301 }
1302 if(Domain2.HasLastPoint()) {
1303 if(L1.Distance(Domain2.LastPoint()) < Domain2.LastTolerance()) {
1304 Standard_Real p = ElCLib::Parameter(L1,Domain2.LastPoint());
1305 if(U1inf > p) {
1306 U1inf = p;
1307 }
1308 if(U1sup < p) {
1309 U1sup = p;
1310 }
1311 }
1312 }
1313 //-----------------------------------------------------------------
1314
1315 DomainIntersection(Domain1,U1inf,U1sup,Res1inf,Res1sup,Pos1a,Pos1b);
1316
1317 if((Res1sup-Res1inf)<0.0) {
1318 //-- Si l intersection est vide
1319 //--
1320 }
1321 else { //-- (Domain1 INTER Zone Intersection) non vide
1322
1323 ProdVectTan=Tan1.Crossed(Tan2);
1324
7fd59977 1325 //#####################################################################
1326 //## Longueur Minimale d un segment Sur Courbe 1
1327 //#####################################################################
1328
1329 Standard_Real LongMiniSeg=Tol;
1330
1331
1332 if(((Res1sup-Res1inf)<=LongMiniSeg)
c2b14317
G
1333 || ((Pos1a==Pos1b)&&(Pos1a!=IntRes2d_Middle)))
1334 {
1335 //------------------------------- Un seul Point -------------------
1336 //--- lorsque la longueur du segment est inferieure a ??
1337 //--- ou si deux points designent le meme bout
1338 //gka #0022833
1339 IntRes2d_TypeTrans aCurTrans = ( ProdVectTan >= TOLERANCE_ANGULAIRE ?
1340 IntRes2d_Out : ( ProdVectTan <= -TOLERANCE_ANGULAIRE ? IntRes2d_In : IntRes2d_Undecided ) );
1341
1342 IntRes2d_IntersectionPoint NewPoint1;
1343 if( computeIntPoint(Domain1, Domain2, L1, L2, aCosT1T2, U1, U2, Res1inf, Res1sup, 1, aCurTrans, NewPoint1 ) )
1344 Append(NewPoint1);
1345
1346 //------------------------------------------------------
1347
1348
ba5ab97f 1349 } //--------------- Fin du cas : 1 seul point --------------------
7fd59977 1350
1351 else {
1352 //-- Intersection AND Domain1 --------> Segment ---------------------
1353 Standard_Real U2inf,U2sup;
1354 Standard_Real Res2inf,Res2sup;
1355
9fd2d2c3 1356 if (isOpposite) { U2inf = U1pU2 -Res1sup; U2sup= U1pU2-Res1inf; }
1357 else { U2inf = Res1inf-U1mU2; U2sup= Res1sup-U1mU2; }
7fd59977 1358
1359 DomainIntersection(Domain2,U2inf,U2sup,Res2inf,Res2sup,Pos2a,Pos2b);
1360
1361 //####################################################################
1362 //## Test sur la longueur minimale d un segment sur Ligne2
1363 //####################################################################
1364 Standard_Real Res2sup_m_Res2inf = Res2sup-Res2inf;
1365 if(Res2sup_m_Res2inf < 0.0) {
1366 //-- Pas de solutions On retourne Vide
1367 }
e784d865 1368 else if((Res2sup_m_Res2inf > LongMiniSeg)
7fd59977 1369 || ((Pos2a==Pos2b)&&(Pos2a!=IntRes2d_Middle))) {
1370 //----------- Calcul des attributs du segment --------------
1371 //-- Attention, les bornes Res1inf(sup) bougent donc il faut
1372 //-- eventuellement recalculer les attributs
1373
9fd2d2c3 1374 if(isOpposite) { Res1inf=U1pU2-Res2sup; Res1sup=U1pU2-Res2inf;
7fd59977 1375 Standard_Real Tampon=Res2inf; Res2inf=Res2sup; Res2sup=Tampon;
1376 IntRes2d_Position Pos=Pos2a; Pos2a=Pos2b; Pos2b=Pos;
1377 }
1378 else { Res1inf=U1mU2+Res2inf; Res1sup=U1mU2+Res2sup; }
1379
1380 Pos1a=FindPositionLL(Res1inf,Domain1);
1381 Pos1b=FindPositionLL(Res1sup,Domain1);
1382
1383 IntRes2d_Transition T1a,T2a,T1b,T2b;
1384
1385 if(ProdVectTan>=TOLERANCE_ANGULAIRE) { // &&&&&&&&&&&&&&&
1386 T1a.SetValue(Standard_False,Pos1a,IntRes2d_Out);
1387 T2a.SetValue(Standard_False,Pos2a,IntRes2d_In);
1388 }
1389 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1390 T1a.SetValue(Standard_False,Pos1a,IntRes2d_In);
1391 T2a.SetValue(Standard_False,Pos2a,IntRes2d_Out);
1392 }
1393 else {
9fd2d2c3 1394 T1a.SetValue (Standard_False, Pos1a, IntRes2d_Unknown, isOpposite);
1395 T2a.SetValue (Standard_False, Pos2a, IntRes2d_Unknown, isOpposite);
7fd59977 1396 }
1397
1398
1399 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1400 //~~~~~~~ C O N V E N T I O N - S E G M E N T ~~~~~~~
1401 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1402 //~~ On Renvoie un segment dans les cas suivants : ~~
1403 //~~ (1) Extremite L1 L2 ------> Extremite L1 L2 ~~
1404 //~~ (2) Extremite L1 L2 ------> Intersection ~~
1405 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1406
1407 Standard_Boolean ResultIsAPoint=Standard_False;
1408
1409 if(((Res1sup-Res1inf)<=LongMiniSeg)
1410 || (Abs(Res2sup-Res2inf)<=LongMiniSeg)) {
1411 //-- On force la creation d un point
1412 ResultIsAPoint=Standard_True;
1413 }
1414 else {
1415 //------------------------------------------------------------
1416 //-- On traite les cas ou l intersection est situee du
1417 //-- Mauvais cote du domaine
1418 //-- Attention : Res2inf <-> Pos2a Res2sup <-> Pos2b
1419 //-- et Res1inf <-> Pos1a Res1sup <-> Pos1b
1420 //-- avec Res1inf <= Res1sup
1421 //------------------------------------------------------------
1422 //-- Le point sera : Res1inf,Res2inf,T1a(Pos1a),T2a(Pos2a)
1423 //------------------------------------------------------------
1424
1425 if(Pos1a==IntRes2d_Head) {
1426 if(Pos1b!=IntRes2d_End && U1<Res1inf) { ResultIsAPoint=Standard_True; U1=Res1inf; U2=Res2inf; }
1427 }
1428 if(Pos1b==IntRes2d_End) {
1429 if(Pos1a!=IntRes2d_Head && U1>Res1sup) { ResultIsAPoint=Standard_True; U1=Res1sup; U2=Res2sup; }
1430 }
1431
1432 if(Pos2a==IntRes2d_Head) {
1433 if(Pos2b!=IntRes2d_End && U2<Res2inf) { ResultIsAPoint=Standard_True; U2=Res2inf; U1=Res1inf; }
1434 }
1435 else {
1436 if(Pos2a==IntRes2d_End) {
1437 if(Pos2b!=IntRes2d_Head && U2>Res2inf) { ResultIsAPoint=Standard_True; U2=Res2inf; U1=Res1inf; }
1438 }
1439 }
1440 if(Pos2b==IntRes2d_Head) {
1441 if(Pos2a!=IntRes2d_End && U2<Res2sup) { ResultIsAPoint=Standard_True; U2=Res2sup; U1=Res1sup; }
1442 }
1443 else {
1444 if(Pos2b==IntRes2d_End) {
1445 if(Pos2a!=IntRes2d_Head && U2>Res2sup) { ResultIsAPoint=Standard_True; U2=Res2sup; U1=Res1sup; }
1446 }
1447 }
1448 }
1449
1450
1451
1452 if((!ResultIsAPoint) && (Pos1a!=IntRes2d_Middle || Pos2a!=IntRes2d_Middle)) {
7fd59977 1453 if(ProdVectTan>=TOLERANCE_ANGULAIRE) { //&&&&&&&&&&&&&&
1454 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1455 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1456 }
1457 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) { //&&&&&&&&&&&&&&
1458 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1459 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1460 }
1461 else {
9fd2d2c3 1462 T1b.SetValue (Standard_False, Pos1b, IntRes2d_Unknown, isOpposite);
1463 T2b.SetValue (Standard_False, Pos2b, IntRes2d_Unknown, isOpposite);
7fd59977 1464 }
1465 gp_Pnt2d Ptdebut;
1466 if(Pos1a==IntRes2d_Middle) {
1467 Standard_Real t3;
9fd2d2c3 1468 if (isOpposite) {
7fd59977 1469 t3 = (Pos2a == IntRes2d_Head)? Res2sup : Res2inf;
1470 }
1471 else {
1472 t3 = (Pos2a == IntRes2d_Head)? Res2inf : Res2sup;
1473 }
1474 Ptdebut=ElCLib::Value(t3,L2);
1475 Res1inf=ElCLib::Parameter(L1,Ptdebut);
1476 }
1477 else {
1478 Standard_Real t4 = (Pos1a == IntRes2d_Head)? Res1inf : Res1sup;
1479 Ptdebut=ElCLib::Value(t4,L1);
1480 Res2inf=ElCLib::Parameter(L2,Ptdebut);
1481 }
1482 PtSeg1.SetValues(Ptdebut,Res1inf,Res2inf,T1a,T2a,Standard_False);
1483 if(Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle) {
1484 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1485 //~~ Ajustement des parametres et du point renvoye
1486 gp_Pnt2d Ptfin;
1487 if(Pos1b==IntRes2d_Middle) {
1488 Ptfin=ElCLib::Value(Res2sup,L2);
1489 Res1sup=ElCLib::Parameter(L1,Ptfin);
1490 }
1491 else {
1492 Ptfin=ElCLib::Value(Res1sup,L1);
1493 Res2sup=ElCLib::Parameter(L2,Ptfin);
1494 }
1495 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
9fd2d2c3 1496 IntRes2d_IntersectionSegment Segment (PtSeg1, PtSeg2, isOpposite, Standard_False);
7fd59977 1497 Append(Segment);
1498 }
1499 else { //-- Extremite(L1 ou L2) ------> Point Middle(L1 et L2)
1500
1501 Pos1b=FindPositionLL(U1,Domain1);
1502 Pos2b=FindPositionLL(U2,Domain2);
1503 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1504 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1505 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1506 }
1507 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1508 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1509 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1510 }
1511 else {
9fd2d2c3 1512 T1b.SetValue (Standard_False, Pos1b, IntRes2d_Unknown, isOpposite);
1513 T2b.SetValue (Standard_False, Pos2b, IntRes2d_Unknown, isOpposite);
7fd59977 1514 }
1515
1516 PtSeg2.SetValues(ElCLib::Value(U2,L2),U1,U2,T1b,T2b,Standard_False);
1517
1518 if((Abs(Res1inf-U1) >LongMiniSeg) && (Abs(Res2inf-U2) >LongMiniSeg)) {
9fd2d2c3 1519 IntRes2d_IntersectionSegment Segment (PtSeg1, PtSeg2, isOpposite, Standard_False);
7fd59977 1520 Append(Segment);
1521 }
1522 else {
1523 Append(SegmentToPoint(PtSeg1,T1a,T2a,PtSeg2,T1b,T2b));
1524 }
1525 }
1526
1527 } //-- (Pos1a!=IntRes2d_Middle || Pos2a!=IntRes2d_Middle) --
1528 else { //-- Pos1a == Pos2a == Middle
1529 if(Pos1b==IntRes2d_Middle) Pos1b=Pos1a;
1530 if(Pos2b==IntRes2d_Middle) Pos2b=Pos2a;
1531 if(ResultIsAPoint) {
1532 //-- Middle sur le segment A
1533 //--
1534 if(Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle) {
1535 gp_Pnt2d Ptfin;
1536 if(Pos1b==IntRes2d_Middle) {
1537 Standard_Real t2;
9fd2d2c3 1538 if (isOpposite) {
7fd59977 1539 t2 = (Pos2b == IntRes2d_Head)? Res2sup : Res2inf;
1540 }
1541 else {
1542 t2 = (Pos2b == IntRes2d_Head)? Res2inf : Res2sup;
1543 }
1544 Ptfin=ElCLib::Value(t2,L2);
1545 Res1sup=ElCLib::Parameter(L1,Ptfin);
1546//modified by NIZHNY-MKK Tue Feb 15 10:54:51 2000.BEGIN
1547 Pos1b=FindPositionLL(Res1sup,Domain1);
1548//modified by NIZHNY-MKK Tue Feb 15 10:54:55 2000.END
1549
1550 }
1551 else {
1552 Standard_Real t1 = (Pos1b == IntRes2d_Head)? Res1inf : Res1sup;
1553 Ptfin=ElCLib::Value(t1,L1);
1554 Res2sup=ElCLib::Parameter(L2,Ptfin);
1555//modified by NIZHNY-MKK Tue Feb 15 10:55:08 2000.BEGIN
1556 Pos2b=FindPositionLL(Res2sup,Domain2);
1557//modified by NIZHNY-MKK Tue Feb 15 10:55:11 2000.END
1558 }
1559 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1560 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1561 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1562 }
1563 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1564 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1565 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1566 }
1567 else {
9fd2d2c3 1568 T1b.SetValue (Standard_False, Pos1b, IntRes2d_Unknown, isOpposite);
1569 T2b.SetValue (Standard_False, Pos2b, IntRes2d_Unknown, isOpposite);
7fd59977 1570 }
1571 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1572 Append(PtSeg2);
1573 }
1574 else {
1575 Pos1b=FindPositionLL(U1,Domain1);
1576 Pos2b=FindPositionLL(U2,Domain2);
1577
1578 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1579 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1580 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1581 }
1582 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1583 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1584 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1585 }
1586 else {
9fd2d2c3 1587 T1b.SetValue (Standard_False, Pos1b, IntRes2d_Unknown, isOpposite);
1588 T2b.SetValue (Standard_False, Pos2b, IntRes2d_Unknown, isOpposite);
7fd59977 1589 }
1590 PtSeg1.SetValues(ElCLib::Value(U2,L2),U1,U2,T1b,T2b,Standard_False);
1591 Append(PtSeg1);
1592 }
1593 }
1594 else {
1595 PtSeg1.SetValues(ElCLib::Value(U2,L2),U1,U2,T1a,T2a,Standard_False);
1596
1597 if((Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle)) {
7fd59977 1598 if(ProdVectTan>=TOLERANCE_ANGULAIRE) {
1599 T1b.SetValue(Standard_False,Pos1b,IntRes2d_Out);
1600 T2b.SetValue(Standard_False,Pos2b,IntRes2d_In);
1601 }
1602 else if(ProdVectTan<=-TOLERANCE_ANGULAIRE) {
1603 T1b.SetValue(Standard_False,Pos1b,IntRes2d_In);
1604 T2b.SetValue(Standard_False,Pos2b,IntRes2d_Out);
1605 }
1606 else {
9fd2d2c3 1607 T1b.SetValue (Standard_False, Pos1b, IntRes2d_Unknown, isOpposite);
1608 T2b.SetValue (Standard_False, Pos2b, IntRes2d_Unknown, isOpposite);
7fd59977 1609 }
1610 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1611 //~~ Ajustement des parametres et du point renvoye
1612 gp_Pnt2d Ptfin;
1613 if(Pos1b==IntRes2d_Middle) {
1614 Ptfin=ElCLib::Value(Res2sup,L2);
1615 Res1sup=ElCLib::Parameter(L1,Ptfin);
1616 }
1617 else {
1618 Ptfin=ElCLib::Value(Res1sup,L1);
1619 Res2sup=ElCLib::Parameter(L2,Ptfin);
1620 }
1621
1622 PtSeg2.SetValues(Ptfin,Res1sup,Res2sup,T1b,T2b,Standard_False);
1623
1624 if((Abs(U1-Res1sup)>LongMiniSeg)
1625 ||(Abs(U2-Res2sup)>LongMiniSeg)) {
1626 //-- Modif du 1er Octobre 92 (Pour Composites)
1627
9fd2d2c3 1628 IntRes2d_IntersectionSegment Segment (PtSeg1, PtSeg2, isOpposite, Standard_False);
7fd59977 1629 Append(Segment);
1630 }
1631 else {
1632 Append(SegmentToPoint(PtSeg1,T1a,T2a,PtSeg2,T1b,T2b));
1633 }
1634 }
1635 else {
1636 Append(PtSeg1);
1637 }
1638 }
1639 }
1640 } //----- Fin Creation Segment ----(Res2sup-Res2inf>Tol)-------------
1641 else {
1642 //------ (Intersection And Domain1) AND Domain2 --> Point ------
1643 //-- Attention Res1sup peut etre different de U2
1644 //-- Mais on a Res1sup-Res1inf < Tol
c2b14317 1645
ba5ab97f 1646 //gka #0022833
c2b14317
G
1647 IntRes2d_TypeTrans aCurTrans = ( ProdVectTan >= TOLERANCE_ANGULAIRE ?
1648 IntRes2d_In : ( ProdVectTan <= -TOLERANCE_ANGULAIRE ? IntRes2d_Out : IntRes2d_Undecided ) );
1649
ba5ab97f 1650 IntRes2d_IntersectionPoint NewPoint1;
c2b14317 1651 if( computeIntPoint(Domain2, Domain1, L2, L1, aCosT1T2, U2, U1, Res2inf, Res2sup, 2, aCurTrans, NewPoint1 ) )
ba5ab97f 1652 Append(NewPoint1);
c2b14317 1653
7fd59977 1654 }
1655 }
1656 }
e784d865 1657
1658//#ifdef OCCT_DEBUG
1659// if (NbPoints() || NbSegments())
1660// {
1661// static int cnt = 0; cnt++;
1662//
1663// printf("line l1_%03d %.15g %.15g %.15g %.15g\n", cnt, L1.Location().X(), L1.Location().Y(), L1.Direction().X(), L1.Direction().Y());
1664//
1665// if (Domain1.HasFirstPoint() && Domain1.HasLastPoint())
1666// printf("trim l1_%03d l1_%03d %.15g %.15g\n", cnt, cnt, Domain1.FirstParameter(), Domain1.LastParameter());
1667//
1668// printf("line l2_%03d %.15g %.15g %.15g %.15g\n", cnt, L2.Location().X(), L2.Location().Y(), L2.Direction().X(), L2.Direction().Y());
1669//
1670// if (Domain2.HasFirstPoint() && Domain2.HasLastPoint())
1671// printf("trim l2_%03d l2_%03d %.15g %.15g\n", cnt, cnt, Domain2.FirstParameter(), Domain2.LastParameter());
1672//
1673// for (int i=1; i <= NbPoints(); i++)
1674// printf("point p%d_%03d %.15g %.15g\n", i, cnt, Point(i).Value().X(), Point(i).Value().Y());
1675//
1676// for (int i=1; i <= NbSegments(); i++)
1677// printf("point s1_%d_%03d %.15g %.15g; point s2_%d_%03d %.15g %.15g\n", i, cnt, Segment(i).FirstPoint().Value().X(), Segment(i).FirstPoint().Value().Y(), i, cnt, Segment(i).LastPoint().Value().X(), Segment(i).LastPoint().Value().Y());
1678// }
1679//#endif
1680
7fd59977 1681 }
1682 else {
1683 if(nbsol==2) { //== Droites confondues a la tolerance pres
1684 //--On traite ici le cas de segments resultats non neccess. bornes
1685 //--
1686 //--On prend la droite D1 comme reference ( pour le sens positif )
1687 //--
1688 Standard_Integer ResHasFirstPoint=0;
1689 Standard_Integer ResHasLastPoint=0;
1d47d8d0 1690 Standard_Real ParamStart = 0.,ParamStart2,ParamEnd = 0.,ParamEnd2;
7fd59977 1691 Standard_Real Org2SurL1=ElCLib::Parameter(L1,L2.Location());
1692 //== 3 : L1 et L2 bornent
1693 //== 2 : L2 borne
1694 //== 1 : L1 borne
1695 if(Domain1.HasFirstPoint()) ResHasFirstPoint=1;
1696 if(Domain1.HasLastPoint()) ResHasLastPoint=1;
9fd2d2c3 1697 if (isOpposite) {
7fd59977 1698 if(Domain2.HasLastPoint()) ResHasFirstPoint+=2;
1699 if(Domain2.HasFirstPoint()) ResHasLastPoint+=2;
1700 }
1701 else {
1702 if(Domain2.HasLastPoint()) ResHasLastPoint+=2;
1703 if(Domain2.HasFirstPoint()) ResHasFirstPoint+=2;
1704 }
1705 if(ResHasFirstPoint==0 && ResHasLastPoint==0) {
1706 //~~~~ Creation d un segment infini avec Opposite
9fd2d2c3 1707 Append (IntRes2d_IntersectionSegment (isOpposite));
7fd59977 1708 }
1709 else { //-- On obtient au pire une demi-droite
1710 switch(ResHasFirstPoint) {
1711 case 1:
1712 ParamStart=Domain1.FirstParameter();
9fd2d2c3 1713 ParamStart2 = isOpposite ? (Org2SurL1 - ParamStart) : (ParamStart - Org2SurL1);
7fd59977 1714 break;
1715 case 2:
9fd2d2c3 1716 if (isOpposite) {
7fd59977 1717 ParamStart2=Domain2.LastParameter();
1718 ParamStart=Org2SurL1 - ParamStart2;
1719 }
1720 else {
1721 ParamStart2=Domain2.FirstParameter();
1722 ParamStart=Org2SurL1 + ParamStart2;
1723 }
1724 break;
1725 case 3:
9fd2d2c3 1726 if (isOpposite) {
7fd59977 1727 ParamStart2=Domain2.LastParameter();
1728 ParamStart=Org2SurL1 - ParamStart2;
1729 if(ParamStart < Domain1.FirstParameter()) {
1730 ParamStart=Domain1.FirstParameter();
1731 ParamStart2=Org2SurL1 - ParamStart;
1732 }
1733 }
1734 else {
1735 ParamStart2=Domain2.FirstParameter();
1736 ParamStart=Org2SurL1 + ParamStart2;
1737 if(ParamStart < Domain1.FirstParameter()) {
1738 ParamStart=Domain1.FirstParameter();
1739 ParamStart2=ParamStart - Org2SurL1;
1740 }
1741 }
1742 break;
1743 default: //~~~ Segment Infini a gauche
1744 break;
1745 }
1746
1747 switch(ResHasLastPoint) {
1748 case 1:
1749 ParamEnd=Domain1.LastParameter();
9fd2d2c3 1750 ParamEnd2 = isOpposite ? (Org2SurL1 - ParamEnd) : (ParamEnd - Org2SurL1);
7fd59977 1751 break;
1752 case 2:
9fd2d2c3 1753 if (isOpposite) {
7fd59977 1754 ParamEnd2=Domain2.FirstParameter();
1755 ParamEnd=Org2SurL1 - ParamEnd2;
1756 }
1757 else {
1758 ParamEnd2=Domain2.LastParameter();
1759 ParamEnd=Org2SurL1 + ParamEnd2;
1760 }
1761 break;
1762 case 3:
9fd2d2c3 1763 if (isOpposite) {
7fd59977 1764 ParamEnd2=Domain2.FirstParameter();
1765 ParamEnd=Org2SurL1 - ParamEnd2;
1766 if(ParamEnd > Domain1.LastParameter()) {
1767 ParamEnd=Domain1.LastParameter();
1768 ParamEnd2=Org2SurL1 - ParamEnd;
1769 }
1770 }
1771 else {
1772 ParamEnd2=Domain2.LastParameter();
1773 ParamEnd=Org2SurL1 + ParamEnd2;
1774 if(ParamEnd > Domain1.LastParameter()) {
1775 ParamEnd=Domain1.LastParameter();
1776 ParamEnd2=ParamEnd - Org2SurL1;
1777 }
1778 }
1779 default: //~~~ Segment Infini a droite
1780 break;
1781 }
1782
1783 IntRes2d_Transition Tinf,Tsup;
1784
1785 if(ResHasFirstPoint) {
1786 if(ResHasLastPoint) {
1787 //~~~ Creation de la borne superieure
1788 //~~~ L1 : |-------------> ou |-------------->
1789 //~~~ L2 : <------------| ou <----|
1790 if(ParamEnd >= (ParamStart-Tol)) {
1791 //~~~ Creation d un segment
1792 IntRes2d_Position Pos1,Pos2;
1793 Pos1=FindPositionLL(ParamStart,Domain1);
1794 Pos2=FindPositionLL(ParamStart2,Domain2);
9fd2d2c3 1795 Tinf.SetValue (Standard_True, Pos1, IntRes2d_Unknown, isOpposite);
1796 Tsup.SetValue (Standard_True, Pos2, IntRes2d_Unknown, isOpposite);
7fd59977 1797 IntRes2d_IntersectionPoint P1(ElCLib::Value(ParamStart,L1)
1798 ,ParamStart,ParamStart2
1799 ,Tinf,Tsup,Standard_False);
1800 if(ParamEnd > (ParamStart+Tol)) {
1801 //~~~ Le segment est assez long
1802 Pos1=FindPositionLL(ParamEnd,Domain1);
1803 Pos2=FindPositionLL(ParamEnd2,Domain2);
9fd2d2c3 1804 Tinf.SetValue (Standard_True, Pos1, IntRes2d_Unknown, isOpposite);
1805 Tsup.SetValue (Standard_True, Pos2, IntRes2d_Unknown, isOpposite);
7fd59977 1806
1807 IntRes2d_IntersectionPoint P2(ElCLib::Value(ParamEnd,L1)
1808 ,ParamEnd,ParamEnd2
1809 ,Tinf,Tsup,Standard_False);
9fd2d2c3 1810 IntRes2d_IntersectionSegment Seg (P1, P2, isOpposite, Standard_False);
7fd59977 1811 Append(Seg);
1812 }
1813 else { //~~~~ le segment est de longueur inferieure a Tol
1814 Append(P1);
1815 }
1816 } //-- if( ParamEnd >= ...)
1817 } //-- if(ResHasLastPoint)
1818 else {
1819 //~~~ Creation de la demi droite |----------->
1820 IntRes2d_Position Pos1=FindPositionLL(ParamStart,Domain1);
1821 IntRes2d_Position Pos2=FindPositionLL(ParamStart2,Domain2);
9fd2d2c3 1822 Tinf.SetValue (Standard_True, Pos1, IntRes2d_Unknown, isOpposite);
1823 Tsup.SetValue (Standard_True, Pos2, IntRes2d_Unknown, isOpposite);
7fd59977 1824
1825 IntRes2d_IntersectionPoint P(ElCLib::Value(ParamStart,L1)
1826 ,ParamStart,ParamStart2
1827 ,Tinf,Tsup,Standard_False);
9fd2d2c3 1828 IntRes2d_IntersectionSegment Seg (P, Standard_True, isOpposite, Standard_False);
7fd59977 1829 Append(Seg);
1830 }
1831 }
1832 else {
1833 IntRes2d_Position Pos1=FindPositionLL(ParamEnd,Domain1);
1834 IntRes2d_Position Pos2=FindPositionLL(ParamEnd2,Domain2);
9fd2d2c3 1835 Tinf.SetValue (Standard_True, Pos1, IntRes2d_Unknown, isOpposite);
1836 Tsup.SetValue (Standard_True, Pos2, IntRes2d_Unknown, isOpposite);
7fd59977 1837
1838 IntRes2d_IntersectionPoint P2(ElCLib::Value(ParamEnd,L1)
1839 ,ParamEnd,ParamEnd2
1840 ,Tinf,Tsup,Standard_False);
9fd2d2c3 1841 IntRes2d_IntersectionSegment Seg (P2, Standard_False, isOpposite, Standard_False);
7fd59977 1842 Append(Seg);
1843 //~~~ Creation de la demi droite <-----------|
1844 }
1845 }
1846 }
1847 }
1848}
1849
1850
1851//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1852//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1853void IntCurve_IntConicConic::Perform(const gp_Lin2d& Line
1854 ,const IntRes2d_Domain& LIG_Domain
1855 ,const gp_Circ2d& Circle
1856 ,const IntRes2d_Domain& CIRC_Domain
1857 ,const Standard_Real TolConf,const Standard_Real Tol) {
1858
1859//-- if(! CIRC_Domain.IsClosed()) {
9775fa61 1860//-- throw Standard_ConstructionError("Domaine incorrect");
7fd59977 1861//-- }
1862
1863 Standard_Boolean TheReversedParameters=ReversedParameters();
1864 this->ResetFields();
1865 this->SetReversedParameters(TheReversedParameters);
1866
1867 Standard_Integer nbsol=0;
1868 PeriodicInterval CInt1,CInt2;
1869
1870 LineCircleGeometricIntersection(Line,Circle,TolConf,Tol
1871 ,CInt1,CInt2
1872 ,nbsol);
1873
1874 done=Standard_True;
1875
1876 if(nbsol==0) { //-- Pas de solutions
1877 return;
1878 }
1879
1880// Modified by Sergey KHROMOV - Mon Dec 18 11:13:18 2000 Begin
1881 if (nbsol == 2 && CInt2.Bsup == CInt1.Binf + PIpPI) {
1882 Standard_Real FirstBound = CIRC_Domain.FirstParameter();
1883 Standard_Real LastBound = CIRC_Domain.LastParameter();
1884 Standard_Real FirstTol = CIRC_Domain.FirstTolerance();
1885 Standard_Real LastTol = CIRC_Domain.LastTolerance();
1886 if (CInt1.Binf == 0 && FirstBound - FirstTol > CInt1.Bsup) {
1887 nbsol = 1;
1888 CInt1.SetValues(CInt2.Binf, CInt2.Bsup);
1889 } else if (CInt2.Bsup == PIpPI && LastBound + LastTol < CInt2.Binf)
1890 nbsol = 1;
1891 }
1892// Modified by Sergey KHROMOV - Mon Dec 18 11:13:20 2000 End
1893
1894 PeriodicInterval CDomain(CIRC_Domain);
1895 Standard_Real deltat = CDomain.Bsup-CDomain.Binf;
1896 while(CDomain.Binf >= PIpPI) CDomain.Binf-=PIpPI;
1897 while(CDomain.Binf < 0.0) CDomain.Binf+=PIpPI;
1898 CDomain.Bsup=CDomain.Binf+deltat;
1899
1900 //------------------------------------------------------------
1901 //-- Ajout : Jeudi 28 mars 96
1902 //-- On agrandit artificiellement les domaines
1903 Standard_Real BinfModif = CDomain.Binf;
1904 Standard_Real BsupModif = CDomain.Bsup;
1905 BinfModif-=CIRC_Domain.FirstTolerance() / Circle.Radius();
1906 BsupModif+=CIRC_Domain.LastTolerance() / Circle.Radius();
1907 deltat = BsupModif-BinfModif;
1908 if(deltat<=PIpPI) {
1909 CDomain.Binf = BinfModif;
1910 CDomain.Bsup = BsupModif;
1911 }
1912 else {
1913 Standard_Real t=PIpPI-deltat;
1914 t*=0.5;
1915 CDomain.Binf = BinfModif+t;
1916 CDomain.Bsup = BsupModif-t;
1917 }
1918 deltat = CDomain.Bsup-CDomain.Binf;
1919 while(CDomain.Binf >= PIpPI) CDomain.Binf-=PIpPI;
1920 while(CDomain.Binf < 0.0) CDomain.Binf+=PIpPI;
1921 CDomain.Bsup=CDomain.Binf+deltat;
1922 //-- ------------------------------------------------------------
1923
1924 Interval LDomain(LIG_Domain);
1925
1926 Standard_Integer NbSolTotal=0;
1927
1928 PeriodicInterval SolutionCircle[4];
1929 Interval SolutionLine[4];
1930
1931 //----------------------------------------------------------------------
1932 //----------- Traitement du premier intervalle Geometrique CInt1 ----
1933 //----------------------------------------------------------------------
1934 //-- NbSolTotal est incremente a chaque Intervalle solution.
1935 //-- On stocke les intervalles dans les tableaux : SolutionCircle[4]
1936 //-- et SolutionLine[4]
1937 //-- des Exemples faciles donnent 3 Intersections
1938 //-- des Problemes numeriques peuvent peut etre en donner 4 ??????
1939 //--
1940 PeriodicInterval CDomainAndRes=CDomain.FirstIntersection(CInt1);
1941
1942 ProjectOnLAndIntersectWithLDomain(Circle,Line
1943 ,CDomainAndRes
1944 ,LDomain
1945 ,SolutionCircle
1946 ,SolutionLine
1947 ,NbSolTotal
1948 ,LIG_Domain
1949 ,CIRC_Domain);
1950
1951 CDomainAndRes=CDomain.SecondIntersection(CInt1);
1952
1953 ProjectOnLAndIntersectWithLDomain(Circle,Line
1954 ,CDomainAndRes
1955 ,LDomain
1956 ,SolutionCircle
1957 ,SolutionLine
1958 ,NbSolTotal
1959 ,LIG_Domain
1960 ,CIRC_Domain);
1961
1962 //----------------------------------------------------------------------
1963 //----------- Traitement du second intervalle Geometrique C1_Int2 ----
1964 //----------------------------------------------------------------------
1965 if(nbsol==2) {
1966 CDomainAndRes=CDomain.FirstIntersection(CInt2);
1967
1968 ProjectOnLAndIntersectWithLDomain(Circle,Line
1969 ,CDomainAndRes
1970 ,LDomain
1971 ,SolutionCircle
1972 ,SolutionLine
1973 ,NbSolTotal
1974 ,LIG_Domain
1975 ,CIRC_Domain);
1976
1977 //--------------------------------------------------------------------
1978 CDomainAndRes=CDomain.SecondIntersection(CInt2);
1979
1980
1981 ProjectOnLAndIntersectWithLDomain(Circle,Line
1982 ,CDomainAndRes
1983 ,LDomain
1984 ,SolutionCircle
1985 ,SolutionLine
1986 ,NbSolTotal
1987 ,LIG_Domain
1988 ,CIRC_Domain);
1989 }
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999 //----------------------------------------------------------------------
2000 //-- Calcul de toutes les transitions et Positions.
2001 //--
2002 //-- On determine si des intervalles sont reduit a des points
2003 //-- ( Rayon * Intervalle.Length() < TolConf ) ### Modif 19 Nov Tol-->TolConf
2004 //--
2005 Standard_Real R=Circle.Radius();
2006 Standard_Integer i ;
2007 Standard_Real MaxTol = TolConf;
2008 if(MaxTol<Tol) MaxTol = Tol;
2009 if(MaxTol<1.0e-10) MaxTol = 1.0e-10;
2010
2011 for( i=0; i<NbSolTotal ; i++) {
2012 if((R * SolutionCircle[i].Length())<MaxTol
2013 && (SolutionLine[i].Length())<MaxTol) {
2014
2015 Standard_Real t=(SolutionCircle[i].Binf+SolutionCircle[i].Bsup)*0.5;
2016 SolutionCircle[i].Binf=SolutionCircle[i].Bsup=t;
2017
2018 t=(SolutionLine[i].Binf+SolutionLine[i].Bsup)*0.5;
2019 SolutionLine[i].Binf=SolutionLine[i].Bsup=t;
2020 }
2021 }
2022#if 0
2023 if(NbSolTotal == 2) {
2024 if(SolutionLine[0].Binf==SolutionLine[0].BSup) {
2025 if(SolutionLine[1].Binf==SolutionLine[1].BSup) {
2026 if(Abs(SolutionLine[0].Binf-SolutionLine[1].Binf)<TolConf) {
2027 SolutionLine[0].Binf=0.5*(SolutionLine[0].BSup+SolutionLine[1].BSup);
2028 SolutionLine[0].BSup=SolutionLine[0].Binf;
2029 NbSolTotal = 1;
2030 }
2031 }
2032 }
2033 }
2034#endif
2035 //----------------------------------------------------------------------
2036 //-- Traitement des intervalles (ou des points obtenus)
2037 //--
2038 if(NbSolTotal) {
2039 gp_Ax22d CircleAxis=Circle.Axis();
2040 gp_Ax2d LineAxis=Line.Position();
2041 gp_Pnt2d P1a,P2a,P1b,P2b;
2042 gp_Vec2d Tan1,Tan2,Norm1;
2043 gp_Vec2d Norm2(0.0,0.0);
2044 IntRes2d_Transition T1a,T2a,T1b,T2b;
2045 IntRes2d_Position Pos1a,Pos1b,Pos2a,Pos2b;
2046
2047 ElCLib::CircleD1(SolutionCircle[0].Binf,CircleAxis,R,P1a,Tan1);
2048 ElCLib::LineD1(SolutionLine[0].Binf,LineAxis,P2a,Tan2);
2049
9fd2d2c3 2050 Standard_Boolean isOpposite = (Tan1.Dot (Tan2) < 0.0);
7fd59977 2051
2052
2053 for(i=0; i<NbSolTotal; i++ ) {
2054
2055
2056 //-- 7 aout 97
2057 //-- On recentre Bin et Bsup de facon a avoir une portion commune avec CIRC_Domain
2058 Standard_Real p1=SolutionCircle[i].Binf;
2059 Standard_Real p2=SolutionCircle[i].Bsup;
2060 Standard_Real q1=CIRC_Domain.FirstParameter();
2061 Standard_Real q2=CIRC_Domain.LastParameter();
2062 //-- |------ CircDomain ------| [-- Sol --]
2063 if(p1>q2) {
2064 do {
2065 p1-=PIpPI;
2066 p2-=PIpPI;
2067 }
2068 while( (p1>q2) );
2069 }
2070 else if(p2<q1) {
2071 do {
2072 p1+=PIpPI;
2073 p2+=PIpPI;
2074 }
2075 while( (p2<q1) );
2076 }
2077 if(p1<q1 && p2>q1) {
2078 p1=q1;
2079 }
2080 if(p1<q2 && p2>q2) {
2081 p2=q2;
2082 }
2083
2084#if 0
2085 if(SolutionCircle[i].Binf!=p1 || SolutionCircle[i].Bsup!=p2) {
2086 printf("\n IntCurve_IntConicConic_1.cxx : (%g , %g) --> (%g , %g)\n",
2087 SolutionCircle[i].Binf,SolutionCircle[i].Bsup,p1,p2);
2088 }
2089#endif
2090 SolutionCircle[i].Binf=p1;
2091 SolutionCircle[i].Bsup=p2;
2092
2093//-- Fin 7 aout 97
2094
2095
9fd2d2c3 2096 Standard_Real Linf = isOpposite ? SolutionLine[i].Bsup : SolutionLine[i].Binf;
2097 Standard_Real Lsup = isOpposite ? SolutionLine[i].Binf : SolutionLine[i].Bsup;
7fd59977 2098
2099 //---------------------------------------------------------------
2100 //-- Si les parametres sur le cercle sont en premier
2101 //-- On doit retourner ces parametres dans l ordre croissant
2102 //---------------------------------------------------------------
2103 if(Linf > Lsup) {
2104 Standard_Real T=SolutionCircle[i].Binf;
2105 SolutionCircle[i].Binf=SolutionCircle[i].Bsup;
2106 SolutionCircle[i].Bsup=T;
2107
2108 T=Linf; Linf=Lsup; Lsup=T;
2109 }
2110
2111
2112 ElCLib::CircleD2(SolutionCircle[i].Binf,CircleAxis,R,P1a,Tan1,Norm1);
2113 ElCLib::LineD1(Linf,LineAxis,P2a,Tan2);
2114
2115 IntImpParGen::DeterminePosition(Pos1a,CIRC_Domain,P1a,SolutionCircle[i].Binf);
2116 IntImpParGen::DeterminePosition(Pos2a,LIG_Domain,P2a,Linf);
2117 Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
2118 Standard_Real Cinf;
2119 if(Pos1a==IntRes2d_End) {
2120 Cinf = CIRC_Domain.LastParameter();
2121 P1a = CIRC_Domain.LastPoint();
2122 Linf = ElCLib::Parameter(Line,P1a);
2123
2124 ElCLib::CircleD2(Cinf,CircleAxis,R,P1a,Tan1,Norm1);
2125 ElCLib::LineD1(Linf,LineAxis,P2a,Tan2);
2126 IntImpParGen::DeterminePosition(Pos1a,CIRC_Domain,P1a,Cinf);
2127 IntImpParGen::DeterminePosition(Pos2a,LIG_Domain,P2a,Linf);
2128 Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
2129 }
2130 else if(Pos1a==IntRes2d_Head) {
2131 Cinf = CIRC_Domain.FirstParameter();
2132 P1a = CIRC_Domain.FirstPoint();
2133 Linf = ElCLib::Parameter(Line,P1a);
2134
2135 ElCLib::CircleD2(Cinf,CircleAxis,R,P1a,Tan1,Norm1);
2136 ElCLib::LineD1(Linf,LineAxis,P2a,Tan2);
2137 IntImpParGen::DeterminePosition(Pos1a,CIRC_Domain,P1a,Cinf);
2138 IntImpParGen::DeterminePosition(Pos2a,LIG_Domain,P2a,Linf);
2139 Determine_Transition_LC(Pos1a,Tan1,Norm1,T1a , Pos2a,Tan2,Norm2,T2a, Tol);
2140 }
2141 else {
2142 Cinf=NormalizeOnCircleDomain(SolutionCircle[i].Binf,CIRC_Domain);
2143 }
2144
2145 IntRes2d_IntersectionPoint NewPoint1(P1a,Linf,Cinf,T2a,T1a,ReversedParameters());
2146
2147 if((SolutionLine[i].Length()+SolutionCircle[i].Length()) >0.0) {
2148
2149 ElCLib::CircleD2(SolutionCircle[i].Bsup,CircleAxis,R,P1b,Tan1,Norm1);
2150 ElCLib::LineD1(Lsup,LineAxis,P2b,Tan2);
2151
2152 IntImpParGen::DeterminePosition(Pos1b,CIRC_Domain,P1b,SolutionCircle[i].Bsup);
2153 IntImpParGen::DeterminePosition(Pos2b,LIG_Domain,P2b,Lsup);
2154 Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
2155 Standard_Real Csup;
2156 if(Pos1b==IntRes2d_End) {
2157 Csup = CIRC_Domain.LastParameter();
2158 P1b = CIRC_Domain.LastPoint();
2159 Lsup = ElCLib::Parameter(Line,P1b);
2160 ElCLib::CircleD2(Csup,CircleAxis,R,P1b,Tan1,Norm1);
2161 ElCLib::LineD1(Lsup,LineAxis,P2b,Tan2);
2162
2163 IntImpParGen::DeterminePosition(Pos1b,CIRC_Domain,P1b,Csup);
2164 IntImpParGen::DeterminePosition(Pos2b,LIG_Domain,P2b,Lsup);
2165 Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
2166 }
2167 else if(Pos1b==IntRes2d_Head) {
2168 Csup = CIRC_Domain.FirstParameter();
2169 P1b = CIRC_Domain.FirstPoint();
2170 Lsup = ElCLib::Parameter(Line,P1b);
2171 ElCLib::CircleD2(Csup,CircleAxis,R,P1b,Tan1,Norm1);
2172 ElCLib::LineD1(Lsup,LineAxis,P2b,Tan2);
2173
2174 IntImpParGen::DeterminePosition(Pos1b,CIRC_Domain,P1b,Csup);
2175 IntImpParGen::DeterminePosition(Pos2b,LIG_Domain,P2b,Lsup);
2176 Determine_Transition_LC(Pos1b,Tan1,Norm1,T1b , Pos2b,Tan2,Norm2,T2b, Tol);
2177 }
2178 else {
2179 Csup=NormalizeOnCircleDomain(SolutionCircle[i].Bsup,CIRC_Domain);
2180 }
2181
2182 IntRes2d_IntersectionPoint NewPoint2(P1b,Lsup,Csup,T2b,T1b,ReversedParameters());
2183
2184 if(((Abs(Csup-Cinf)*R > MaxTol) && (Abs(Lsup-Linf) > MaxTol))
2185 || (T1a.TransitionType() != T2a.TransitionType())) {
2186 //-- Verifier egalement les transitions
2187
9fd2d2c3 2188 IntRes2d_IntersectionSegment NewSeg (NewPoint1, NewPoint2, isOpposite, ReversedParameters());
7fd59977 2189 Append(NewSeg);
2190 }
2191 else {
2192 if(Pos1a!=IntRes2d_Middle || Pos2a!=IntRes2d_Middle) {
2193 Insert(NewPoint1);
2194 }
2195 if(Pos1b!=IntRes2d_Middle || Pos2b!=IntRes2d_Middle) {
2196 Insert(NewPoint2);
2197 }
2198
2199 }
2200 }
2201 else {
2202 //--Standard_Real Cmid=NormalizeOnCircleDomain(0.5*(SolutionCircle[i].Bsup+SolutionCircle[i].Binf)
2203 //-- ,CIRC_Domain);
2204 //--IntRes2d_IntersectionPoint NewPoint(P2a,0.5*(Linf+Lsup)
2205 //-- ,Cmid
2206 //-- ,T2a,T1a,ReversedParameters());
2207 Insert(NewPoint1);
2208 }
2209 }
2210 }
2211}
2212
2213
2214
2215
2216const IntRes2d_IntersectionPoint SegmentToPoint( const IntRes2d_IntersectionPoint& Pa
2217 ,const IntRes2d_Transition& T1a
2218 ,const IntRes2d_Transition& T2a
2219 ,const IntRes2d_IntersectionPoint& Pb
2220 ,const IntRes2d_Transition& T1b
2221 ,const IntRes2d_Transition& T2b) {
2222
2223 if((T1b.PositionOnCurve() == IntRes2d_Middle)
2224 && (T2b.PositionOnCurve() == IntRes2d_Middle)) {
2225 return(Pa);
2226 }
2227 if((T1a.PositionOnCurve() == IntRes2d_Middle)
2228 && (T2a.PositionOnCurve() == IntRes2d_Middle)) {
2229 return(Pb);
2230 }
2231
2232 IntRes2d_Transition t1 = T1a;
2233 IntRes2d_Transition t2 = T2a;
2234 Standard_Real u1 = Pa.ParamOnFirst();
2235 Standard_Real u2 = Pa.ParamOnSecond();
2236
2237
2238 if(t1.PositionOnCurve() == IntRes2d_Middle) {
2239 t1.SetPosition(T1b.PositionOnCurve());
2240 u1 = Pb.ParamOnFirst();
2241 }
2242 if(t2.PositionOnCurve() == IntRes2d_Middle) {
2243 t2.SetPosition(T2b.PositionOnCurve());
2244 u2 = Pb.ParamOnSecond();
2245 }
2246 return(IntRes2d_IntersectionPoint(Pa.Value(),u1,u2,t1,t2,Standard_False));
2247}
69f87d09 2248
2249//=======================================================================
2250//function : LineEllipseGeometricIntersection
2251//purpose :
2252//=======================================================================
2253void LineEllipseGeometricIntersection(const gp_Lin2d& Line,
2254 const gp_Elips2d& Ellipse,
2255 const Standard_Real ,
2256 const Standard_Real TolTang,
2257 PeriodicInterval& EInt1,
2258 PeriodicInterval& EInt2,
2259 Standard_Integer& nbsol)
2260{
2261
2262 const gp_Ax22d& anElAxis = Ellipse.Axis();
2263 gp_Trsf2d aTr;
2264 aTr.SetTransformation(anElAxis.XAxis());
2265 gp_Elips2d aTEllipse = Ellipse.Transformed(aTr);
2266 gp_Lin2d aTLine = Line.Transformed(aTr);
2267 Standard_Real aDY = aTLine.Position().Direction().Y();
2268 Standard_Boolean IsVert = Abs(aDY) > 1. - 2. * Epsilon(1.);
2269 //
2270 Standard_Real a = aTEllipse.MajorRadius();
2271 Standard_Real b = aTEllipse.MinorRadius();
2272 Standard_Real a2 = a * a;
2273 Standard_Real b2 = b * b;
2274 //
2275 Standard_Real eps0 = 1.e-12;
2276 if (b / a < 1.e-5)
2277 {
2278 eps0 = 1.e-6;
2279 }
2280 //
2281 Standard_Real anA, aB, aC;
2282 aTLine.Coefficients(anA, aB, aC);
2283 if (IsVert)
2284 {
2285 aC += aB * aTLine.Position().Location().Y();
2286 aB = 0.;
2287 }
2288 //
2289 Standard_Real x1 = 0., y1 = 0., x2 = 0., y2 = 0.;
2290 if (Abs(aB) > eps0 )
2291 {
2292 Standard_Real m = -anA / aB;
2293 Standard_Real m2 = m * m;
2294 Standard_Real c = -aC / aB;
2295 Standard_Real c2 = c * c;
2296 Standard_Real D = a2 * m2 + b2 - c2;
2297 if (D < 0.)
2298 {
2299 Extrema_ExtElC2d anExt(aTLine, aTEllipse);
2300 Standard_Integer i, imin = 0;
2301 Standard_Real dmin = RealLast();
2302 for (i = 1; i <= anExt.NbExt(); ++i)
2303 {
2304 if (anExt.SquareDistance(i) < dmin)
2305 {
2306 dmin = anExt.SquareDistance(i);
2307 imin = i;
2308 }
2309 }
2310 if (imin > 0 && dmin <= TolTang * TolTang)
2311 {
2312 nbsol = 1;
2313 Extrema_POnCurv2d aP1, aP2;
2314 anExt.Points(imin, aP1, aP2);
2315 Standard_Real pe1 = aP2.Parameter();
2316 EInt1.SetValues(pe1, pe1);
2317 }
2318 else
2319 {
2320 nbsol = 0;
2321 }
2322 return;
2323 }
2324 D = Sqrt(D);
2325 Standard_Real n = a2 * m2 + b2;
2326 Standard_Real k = a * b * D / n;
2327 Standard_Real l = -a2 * m * c / n;
2328 x1 = l + k;
2329 y1 = m * x1 + c;
2330 x2 = l - k;
2331 y2 = m * x2 + c;
2332 nbsol = 2;
2333 }
2334 else
2335 {
2336 x1 = -aC / anA;
2337 if (Abs(x1) > a + TolTang)
2338 {
2339 nbsol = 0;
2340 return;
2341 }
2342 else if (Abs(x1) >= a - Epsilon(1. + a))
2343 {
2344 nbsol = 1;
2345 y1 = 0.;
2346 }
2347 else
2348 {
2349 y1 = b * Sqrt(1. - x1 * x1 / a2);
2350 x2 = x1;
2351 y2 = -y1;
2352 nbsol = 2;
2353 }
2354 }
2355
2356 gp_Pnt2d aP1(x1, y1);
2357 gp_Pnt2d aP2(x2, y2);
2358 Standard_Real pe1 = 0., pe2 = 0.;
2359 pe1 = ElCLib::Parameter(aTEllipse, aP1);
2360 if (nbsol > 1)
2361 {
2362 pe2 = ElCLib::Parameter(aTEllipse, aP2);
2363 if (pe2 < pe1)
2364 {
2365 Standard_Real t = pe1;
2366 pe1 = pe2;
2367 pe2 = t;
2368 }
2369 EInt2.SetValues(pe2, pe2);
2370 }
2371 EInt1.SetValues(pe1, pe1);
2372
2373
2374}
2375//=======================================================================
2376//function : ProjectOnLAndIntersectWithLDomain
2377//purpose :
2378//=======================================================================
2379void ProjectOnLAndIntersectWithLDomain(const gp_Elips2d& Ellipse
2380 , const gp_Lin2d& Line
2381 , PeriodicInterval& EDomainAndRes
2382 , Interval& LDomain
2383 , PeriodicInterval* EllipseSolution
2384 , Interval* LineSolution
2385 , Standard_Integer &NbSolTotal
2386 , const IntRes2d_Domain& RefLineDomain
2387 , const IntRes2d_Domain&)
2388{
2389
2390 if (EDomainAndRes.IsNull()) return;
2391 //-------------------------------------------------------------------------
2392 //-- On cherche l intervalle correspondant sur C2
2393 //-- Puis on intersecte l intervalle avec le domaine de C2
2394 //-- Enfin, on cherche l intervalle correspondant sur C1
2395 //--
2396
2397 Standard_Real Linf = ElCLib::Parameter(Line
2398 , ElCLib::Value(EDomainAndRes.Binf, Ellipse));
2399 Standard_Real Lsup = ElCLib::Parameter(Line
2400 , ElCLib::Value(EDomainAndRes.Bsup, Ellipse));
2401
2402 Interval LInter(Linf, Lsup); //-- Necessairement Borne
2403
2404 Interval LInterAndDomain = LDomain.IntersectionWithBounded(LInter);
2405
2406 if (!LInterAndDomain.IsNull) {
2407
2408 Standard_Real DomLinf = (RefLineDomain.HasFirstPoint()) ? RefLineDomain.FirstParameter() : -Precision::Infinite();
2409 Standard_Real DomLsup = (RefLineDomain.HasLastPoint()) ? RefLineDomain.LastParameter() : Precision::Infinite();
2410
2411 Linf = LInterAndDomain.Binf;
2412 Lsup = LInterAndDomain.Bsup;
2413
2414 if (Linf<DomLinf) {
2415 Linf = DomLinf;
2416 }
2417 if (Lsup<DomLinf) {
2418 Lsup = DomLinf;
2419 }
2420
2421 if (Linf>DomLsup) {
2422 Linf = DomLsup;
2423 }
2424 if (Lsup>DomLsup) {
2425 Lsup = DomLsup;
2426 }
2427
2428 LInterAndDomain.Binf = Linf;
2429 LInterAndDomain.Bsup = Lsup;
2430
2431
2432 Standard_Real Einf = EDomainAndRes.Binf;
2433 Standard_Real Esup = EDomainAndRes.Bsup;
2434
2435 if (Einf >= Esup) { Einf = EDomainAndRes.Binf; Esup = EDomainAndRes.Bsup; }
2436 EllipseSolution[NbSolTotal] = PeriodicInterval(Einf, Esup);
2437 if (EllipseSolution[NbSolTotal].Length() > M_PI)
2438 EllipseSolution[NbSolTotal].Complement();
2439
2440 LineSolution[NbSolTotal] = LInterAndDomain;
2441 NbSolTotal++;
2442 }
2443}
2444
2445//=======================================================================
2446//function : Perform
0177fe26 2447//purpose : Line - Ellipse
69f87d09 2448//=======================================================================
2449void IntCurve_IntConicConic::Perform(const gp_Lin2d& L, const
2450 IntRes2d_Domain& DL, const gp_Elips2d& E,
2451 const IntRes2d_Domain& DE, const Standard_Real TolConf,
2452 const Standard_Real Tol)
2453{
2454 Standard_Boolean TheReversedParameters = ReversedParameters();
2455 this->ResetFields();
2456 this->SetReversedParameters(TheReversedParameters);
2457
2458 Standard_Integer nbsol = 0;
2459 PeriodicInterval EInt1, EInt2;
2460
2461 LineEllipseGeometricIntersection(L, E, TolConf, Tol, EInt1, EInt2, nbsol);
2462 done = Standard_True;
2463 if (nbsol == 0)
2464 {
2465 return;
2466 }
2467 //
2468 if (nbsol == 2 && EInt2.Bsup == EInt1.Binf + PIpPI) {
2469 Standard_Real FirstBound = DE.FirstParameter();
2470 Standard_Real LastBound = DE.LastParameter();
2471 Standard_Real FirstTol = DE.FirstTolerance();
2472 Standard_Real LastTol = DE.LastTolerance();
2473 if (EInt1.Binf == 0 && FirstBound - FirstTol > EInt1.Bsup)
2474 {
2475 nbsol = 1;
2476 EInt1.SetValues(EInt2.Binf, EInt2.Bsup);
2477 }
2478 else if (EInt2.Bsup == PIpPI && LastBound + LastTol < EInt2.Binf)
2479 {
2480 nbsol = 1;
2481 }
2482 }
2483 //
2484 PeriodicInterval EDomain(DE);
2485 Standard_Real deltat = EDomain.Bsup - EDomain.Binf;
2486 while (EDomain.Binf >= PIpPI) EDomain.Binf -= PIpPI;
2487 while (EDomain.Binf < 0.0) EDomain.Binf += PIpPI;
2488 EDomain.Bsup = EDomain.Binf + deltat;
2489 //
2490 Standard_Real BinfModif = EDomain.Binf;
2491 Standard_Real BsupModif = EDomain.Bsup;
2492 BinfModif -= DE.FirstTolerance() / E.MinorRadius();
2493 BsupModif += DE.LastTolerance() / E.MinorRadius();
2494 deltat = BsupModif - BinfModif;
2495 if (deltat <= PIpPI) {
2496 EDomain.Binf = BinfModif;
2497 EDomain.Bsup = BsupModif;
2498 }
2499 else {
2500 Standard_Real t = PIpPI - deltat;
2501 t *= 0.5;
2502 EDomain.Binf = BinfModif + t;
2503 EDomain.Bsup = BsupModif - t;
2504 }
2505 deltat = EDomain.Bsup - EDomain.Binf;
2506 while (EDomain.Binf >= PIpPI) EDomain.Binf -= PIpPI;
2507 while (EDomain.Binf < 0.0) EDomain.Binf += PIpPI;
2508 EDomain.Bsup = EDomain.Binf + deltat;
2509 //
2510 Interval LDomain(DL);
2511
2512 Standard_Integer NbSolTotal = 0;
2513
2514 PeriodicInterval SolutionEllipse[4];
2515 Interval SolutionLine[4];
2516 //----------------------------------------------------------------------
2517 //----------- Treatment of first geometric interval EInt1 ----
2518 //----------------------------------------------------------------------
2519 PeriodicInterval EDomainAndRes = EDomain.FirstIntersection(EInt1);
2520
2521 ProjectOnLAndIntersectWithLDomain(E, L, EDomainAndRes, LDomain, SolutionEllipse
2522 , SolutionLine, NbSolTotal, DL, DE);
2523
2524 EDomainAndRes = EDomain.SecondIntersection(EInt1);
2525
2526 ProjectOnLAndIntersectWithLDomain(E, L, EDomainAndRes, LDomain, SolutionEllipse
2527 , SolutionLine, NbSolTotal, DL, DE);
2528
2529
2530 //----------------------------------------------------------------------
2531 //----------- Treatment of second geometric interval EInt2 ----
2532 //----------------------------------------------------------------------
2533 if (nbsol == 2)
2534 {
2535 EDomainAndRes = EDomain.FirstIntersection(EInt2);
2536
2537 ProjectOnLAndIntersectWithLDomain(E, L, EDomainAndRes, LDomain, SolutionEllipse
2538 , SolutionLine, NbSolTotal, DL, DE);
2539
2540 EDomainAndRes = EDomain.SecondIntersection(EInt2);
2541
2542 ProjectOnLAndIntersectWithLDomain(E, L, EDomainAndRes, LDomain, SolutionEllipse
2543 , SolutionLine, NbSolTotal, DL, DE);
2544 }
2545
2546 //----------------------------------------------------------------------
2547 //-- Calculation of Transitions at Positions.
2548 //----------------------------------------------------------------------
2549 Standard_Real R = E.MinorRadius();
2550 Standard_Integer i;
2551 Standard_Real MaxTol = TolConf;
2552 if (MaxTol<Tol) MaxTol = Tol;
2553 if (MaxTol<1.0e-10) MaxTol = 1.0e-10;
2554
2555 for (i = 0; i<NbSolTotal; i++) {
2556 if ((R * SolutionEllipse[i].Length())<MaxTol
2557 && (SolutionLine[i].Length())<MaxTol) {
2558
2559 Standard_Real t = (SolutionEllipse[i].Binf + SolutionEllipse[i].Bsup)*0.5;
2560 SolutionEllipse[i].Binf = SolutionEllipse[i].Bsup = t;
2561
2562 t = (SolutionLine[i].Binf + SolutionLine[i].Bsup)*0.5;
2563 SolutionLine[i].Binf = SolutionLine[i].Bsup = t;
2564 }
2565 }
2566 //
2567 if (NbSolTotal) {
2568 gp_Ax22d EllipseAxis = E.Axis();
2569 gp_Ax2d LineAxis = L.Position();
2570 gp_Pnt2d P1a, P2a, P1b, P2b;
2571 gp_Vec2d Tan1, Tan2, Norm1;
2572 gp_Vec2d Norm2(0.0, 0.0);
2573 IntRes2d_Transition T1a, T2a, T1b, T2b;
2574 IntRes2d_Position Pos1a, Pos1b, Pos2a, Pos2b;
2575
2576 ElCLib::EllipseD1(SolutionEllipse[0].Binf, EllipseAxis, E.MajorRadius(), E.MinorRadius(), P1a, Tan1);
2577 ElCLib::LineD1(SolutionLine[0].Binf, LineAxis, P2a, Tan2);
2578
2579 Standard_Boolean isOpposite = (Tan1.Dot(Tan2) < 0.0);
2580 for (i = 0; i<NbSolTotal; i++)
2581 {
2582 Standard_Real p1 = SolutionEllipse[i].Binf;
2583 Standard_Real p2 = SolutionEllipse[i].Bsup;
2584 Standard_Real q1 = DE.FirstParameter();
2585 Standard_Real q2 = DE.LastParameter();
2586
2587 if (p1>q2) {
2588 do {
2589 p1 -= PIpPI;
2590 p2 -= PIpPI;
2591 } while ((p1>q2));
2592 }
2593 else if (p2<q1) {
2594 do {
2595 p1 += PIpPI;
2596 p2 += PIpPI;
2597 } while ((p2<q1));
2598 }
2599 if (p1<q1 && p2>q1) {
2600 p1 = q1;
2601 }
2602 if (p1<q2 && p2>q2) {
2603 p2 = q2;
2604 }
2605
2606 SolutionEllipse[i].Binf = p1;
2607 SolutionEllipse[i].Bsup = p2;
2608
2609 Standard_Real Linf = isOpposite ? SolutionLine[i].Bsup : SolutionLine[i].Binf;
2610 Standard_Real Lsup = isOpposite ? SolutionLine[i].Binf : SolutionLine[i].Bsup;
2611
2612 if (Linf > Lsup) {
2613 Standard_Real T = SolutionEllipse[i].Binf;
2614 SolutionEllipse[i].Binf = SolutionEllipse[i].Bsup;
2615 SolutionEllipse[i].Bsup = T;
2616 T = Linf; Linf = Lsup; Lsup = T;
2617 }
2618
2619
2620 ElCLib::EllipseD2(SolutionEllipse[i].Binf, EllipseAxis, E.MajorRadius(),
2621 E.MinorRadius(), P1a, Tan1, Norm1);
2622 ElCLib::LineD1(Linf, LineAxis, P2a, Tan2);
2623
2624 IntImpParGen::DeterminePosition(Pos1a, DE, P1a, SolutionEllipse[i].Binf);
2625 IntImpParGen::DeterminePosition(Pos2a, DL, P2a, Linf);
2626 Determine_Transition_LC(Pos1a, Tan1, Norm1, T1a, Pos2a, Tan2, Norm2, T2a, Tol);
2627 Standard_Real Einf;
2628 if (Pos1a == IntRes2d_End) {
2629 Einf = DE.LastParameter();
2630 P1a = DE.LastPoint();
2631 Linf = ElCLib::Parameter(L, P1a);
2632
2633 ElCLib::EllipseD2(Einf, EllipseAxis, E.MajorRadius(),
2634 E.MinorRadius(), P1a, Tan1, Norm1);
2635 ElCLib::LineD1(Linf, LineAxis, P2a, Tan2);
2636 IntImpParGen::DeterminePosition(Pos1a, DE, P1a, Einf);
2637 IntImpParGen::DeterminePosition(Pos2a, DL, P2a, Linf);
2638 Determine_Transition_LC(Pos1a, Tan1, Norm1, T1a, Pos2a, Tan2, Norm2, T2a, Tol);
2639 }
2640 else if (Pos1a == IntRes2d_Head) {
2641 Einf = DE.FirstParameter();
2642 P1a = DE.FirstPoint();
2643 Linf = ElCLib::Parameter(L, P1a);
2644
2645 ElCLib::EllipseD2(Einf, EllipseAxis, E.MajorRadius(),
2646 E.MinorRadius(), P1a, Tan1, Norm1);
2647 ElCLib::LineD1(Linf, LineAxis, P2a, Tan2);
2648 IntImpParGen::DeterminePosition(Pos1a, DE, P1a, Einf);
2649 IntImpParGen::DeterminePosition(Pos2a, DL, P2a, Linf);
2650 Determine_Transition_LC(Pos1a, Tan1, Norm1, T1a, Pos2a, Tan2, Norm2, T2a, Tol);
2651 }
2652 else {
2653 Einf = NormalizeOnCircleDomain(SolutionEllipse[i].Binf, DE);
2654 }
2655
2656 IntRes2d_IntersectionPoint NewPoint1(P1a, Linf, Einf, T2a, T1a, ReversedParameters());
2657
2658 if ((SolutionLine[i].Length() + SolutionEllipse[i].Length()) >0.0) {
2659
2660 ElCLib::EllipseD2(SolutionEllipse[i].Binf, EllipseAxis, E.MajorRadius(),
2661 E.MinorRadius(), P1b, Tan1, Norm1);
2662 ElCLib::LineD1(Lsup, LineAxis, P2b, Tan2);
2663
2664 IntImpParGen::DeterminePosition(Pos1b, DE, P1b, SolutionEllipse[i].Bsup);
2665 IntImpParGen::DeterminePosition(Pos2b, DL, P2b, Lsup);
2666 Determine_Transition_LC(Pos1b, Tan1, Norm1, T1b, Pos2b, Tan2, Norm2, T2b, Tol);
2667 Standard_Real Esup;
2668 if (Pos1b == IntRes2d_End) {
2669 Esup = DL.LastParameter();
2670 P1b = DE.LastPoint();
2671 Lsup = ElCLib::Parameter(L, P1b);
2672 ElCLib::EllipseD2(Esup, EllipseAxis, E.MajorRadius(),
2673 E.MinorRadius(), P1b, Tan1, Norm1);
2674 ElCLib::LineD1(Lsup, LineAxis, P2b, Tan2);
2675
2676 IntImpParGen::DeterminePosition(Pos1b, DE, P1b, Esup);
2677 IntImpParGen::DeterminePosition(Pos2b, DL, P2b, Lsup);
2678 Determine_Transition_LC(Pos1b, Tan1, Norm1, T1b, Pos2b, Tan2, Norm2, T2b, Tol);
2679 }
2680 else if (Pos1b == IntRes2d_Head) {
2681 Esup = DE.FirstParameter();
2682 P1b = DE.FirstPoint();
2683 Lsup = ElCLib::Parameter(L, P1b);
2684 ElCLib::EllipseD2(Esup, EllipseAxis, E.MajorRadius(),
2685 E.MinorRadius(), P1b, Tan1, Norm1);
2686 ElCLib::LineD1(Lsup, LineAxis, P2b, Tan2);
2687
2688 IntImpParGen::DeterminePosition(Pos1b, DE, P1b, Esup);
2689 IntImpParGen::DeterminePosition(Pos2b, DL, P2b, Lsup);
2690 Determine_Transition_LC(Pos1b, Tan1, Norm1, T1b, Pos2b, Tan2, Norm2, T2b, Tol);
2691 }
2692 else {
2693 Esup = NormalizeOnCircleDomain(SolutionEllipse[i].Bsup, DE);
2694 }
2695
2696 IntRes2d_IntersectionPoint NewPoint2(P1b, Lsup, Esup, T2b, T1b, ReversedParameters());
2697
2698 if (((Abs(Esup - Einf)*R > MaxTol) && (Abs(Lsup - Linf) > MaxTol))
2699 || (T1a.TransitionType() != T2a.TransitionType())) {
2700 IntRes2d_IntersectionSegment NewSeg(NewPoint1, NewPoint2, isOpposite, ReversedParameters());
2701 Append(NewSeg);
2702 }
2703 else {
2704 if (Pos1a != IntRes2d_Middle || Pos2a != IntRes2d_Middle) {
2705 Insert(NewPoint1);
2706 }
2707 if (Pos1b != IntRes2d_Middle || Pos2b != IntRes2d_Middle) {
2708 Insert(NewPoint2);
2709 }
2710
2711 }
2712 }
2713 else
2714 {
2715 Insert(NewPoint1);
2716 }
2717 }
2718 }
2719}
2720