Commit | Line | Data |
---|---|---|
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 | |
41 | Standard_Boolean Affichage=Standard_False; | |
42 | Standard_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 | 49 | const Standard_Real PIsur2 = 0.5*M_PI; |
7fd59977 | 50 | |
51 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
52 | IntRes2d_Position FindPositionLL(Standard_Real&,const IntRes2d_Domain&); | |
53 | const 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 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
60 | void 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 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
140 | void 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 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
296 | void 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 | //======================================================================= |
387 | void 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 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
545 | void 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 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
617 | void 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 | ||
665 | IntCurve_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 | ||
676 | IntCurve_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 | //---------------------------------------------------------------------- | |
686 | void 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 | //---------------------------------------------------------------------- | |
1056 | IntRes2d_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 | |
1085 | static 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 | 1102 | static 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 | //======================================================================= | |
1199 | static 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 | //---------------------------------------------------------------------- |
1219 | void 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 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
1853 | void 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 | ||
2216 | const 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 | //======================================================================= | |
2253 | void 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 | //======================================================================= | |
2379 | void 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 | |
2447 | //purpose : Line - Elipse | |
2448 | //======================================================================= | |
2449 | void 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 |