Warnings on vc14 were eliminated
[occt.git] / src / Geom2dGcc / Geom2dGcc_Circ2d2TanRadGeo.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
7fd59977 14
578ce4be 15
5201d3e6 16#include <Adaptor2d_OffsetCurve.hxx>
7fd59977 17#include <ElCLib.hxx>
42cf5bc1 18#include <GccEnt_BadQualifier.hxx>
19#include <GccEnt_QualifiedCirc.hxx>
20#include <GccEnt_QualifiedLin.hxx>
21#include <Geom2dAdaptor_HCurve.hxx>
22#include <Geom2dGcc_Circ2d2TanRadGeo.hxx>
23#include <Geom2dGcc_CurveTool.hxx>
42cf5bc1 24#include <Geom2dGcc_QCurve.hxx>
25#include <Geom2dInt_GInter.hxx>
7fd59977 26#include <gp_Ax2d.hxx>
27#include <gp_Circ2d.hxx>
28#include <gp_Lin2d.hxx>
42cf5bc1 29#include <gp_Pnt2d.hxx>
30#include <IntRes2d_Domain.hxx>
31#include <IntRes2d_IntersectionPoint.hxx>
7fd59977 32#include <Standard_NegativeValue.hxx>
33#include <Standard_OutOfRange.hxx>
34#include <StdFail_NotDone.hxx>
35#include <TColStd_Array1OfReal.hxx>
578ce4be 36
1d19db8d 37static const Standard_Integer aNbSolMAX = 16;
38
7fd59977 39// circulaire tant a une courbe et une droite ,de rayon donne
40//==============================================================
41
42//========================================================================
43// On initialise WellDone a false. +
44// On recupere la courbe Cu2 et la droite L1. +
45// On sort en erreur dans les cas ou la construction est impossible. +
46// On fait la parallele a Cu2 dans le bon sens. +
47// On fait la parallele a L1 dans le bon sens. +
48// On intersecte les paralleles ==> point de centre de la solution. +
49// On cree la solution qu on ajoute aux solutions deja trouvees. +
50// On remplit les champs. +
51//========================================================================
52
578ce4be 53Geom2dGcc_Circ2d2TanRadGeo::
54Geom2dGcc_Circ2d2TanRadGeo (const GccEnt_QualifiedLin& Qualified1,
55 const Geom2dGcc_QCurve& Qualified2,
56 const Standard_Real Radius ,
57 const Standard_Real Tolerance ):
7fd59977 58
59//========================================================================
60// initialisation des champs. +
61//========================================================================
62
1d19db8d 63cirsol(1,aNbSolMAX) ,
64qualifier1(1,aNbSolMAX),
65qualifier2(1,aNbSolMAX),
66TheSame1(1,aNbSolMAX) ,
67TheSame2(1,aNbSolMAX) ,
68pnttg1sol(1,aNbSolMAX),
69pnttg2sol(1,aNbSolMAX),
70par1sol(1,aNbSolMAX) ,
71par2sol(1,aNbSolMAX) ,
72pararg1(1,aNbSolMAX) ,
73pararg2(1,aNbSolMAX)
7fd59977 74{
75
74f5f8df 76 //========================================================================
77 // Traitement. +
78 //========================================================================
79
80 Standard_Real Tol = Abs(Tolerance);
81 Standard_Real thefirst = -100000.;
82 Standard_Real thelast = 100000.;
83 Standard_Real firstparam;
84 Standard_Real lastparam;
85 gp_Dir2d dirx(1.,0.);
86 TColStd_Array1OfReal cote1(1,2);
87 TColStd_Array1OfReal cote2(1,2);
88 Standard_Integer nbrcote1=0;
89 Standard_Integer nbrcote2=0;
90 WellDone = Standard_False;
91 NbrSol = 0;
92 if (!(Qualified1.IsEnclosed() ||
93 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
94 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
95 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
96
9775fa61 97 throw GccEnt_BadQualifier();
74f5f8df 98 return;
99 }
100 gp_Lin2d L1 = Qualified1.Qualified();
101 Standard_Real x1dir = (L1.Direction()).X();
102 Standard_Real y1dir = (L1.Direction()).Y();
103 Standard_Real lxloc = (L1.Location()).X();
104 Standard_Real lyloc = (L1.Location()).Y();
105 gp_Pnt2d origin1(lxloc,lyloc);
106 gp_Dir2d normL1(-y1dir,x1dir);
578ce4be 107 Geom2dAdaptor_Curve Cu2= Qualified2.Qualified();
9775fa61 108 if (Radius < 0.0) { throw Standard_NegativeValue(); }
74f5f8df 109 else {
110 if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
111 // =======================================================
112 nbrcote1 = 1;
113 nbrcote2 = 1;
114 cote1(1) = Radius;
115 cote2(1) = Radius;
116 }
117 else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
118 // ==========================================================
119 nbrcote1 = 1;
120 nbrcote2 = 1;
121 cote1(1) = Radius;
122 cote2(1) = -Radius;
123 }
124 else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
125 // ===========================================================
126 nbrcote1 = 1;
127 nbrcote2 = 1;
128 cote1(1) = -Radius;
129 cote2(1) = Radius;
130 }
131 else if(Qualified1.IsOutside() && Qualified2.IsOutside()) {
132 // =========================================================
133 nbrcote1 = 1;
134 nbrcote2 = 1;
135 cote1(1) = -Radius;
136 cote2(1) = -Radius;
137 }
138 if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
139 // =========================================================
140 nbrcote1 = 1;
141 nbrcote2 = 2;
142 cote1(1) = Radius;
143 cote2(1) = Radius;
144 cote2(2) = -Radius;
145 }
146 if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
147 // =========================================================
148 nbrcote1 = 2;
149 nbrcote2 = 1;
150 cote1(1) = Radius;
151 cote1(2) = -Radius;
152 cote2(1) = Radius;
153 }
154 else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
155 // =============================================================
156 nbrcote1 = 1;
157 nbrcote2 = 2;
158 cote1(1) = -Radius;
159 cote2(1) = Radius;
160 cote2(2) = -Radius;
161 }
162 if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
163 // ========================================================
164 nbrcote1 = 2;
165 nbrcote2 = 1;
166 cote1(1) = Radius;
167 cote1(2) = -Radius;
168 cote2(1) = -Radius;
169 }
170 else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
171 // =================================================================
172 nbrcote1 = 2;
173 nbrcote2 = 2;
174 cote1(1) = Radius;
175 cote1(2) = -Radius;
176 cote2(1) = Radius;
177 cote2(2) = -Radius;
178 }
179 gp_Dir2d Dir(-y1dir,x1dir);
180 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
181 gp_Pnt2d Point(L1.Location().XY()+cote1(jcote1)*Dir.XY());
182 gp_Lin2d Line(Point,L1.Direction()); // ligne avec deport.
183 IntRes2d_Domain D1;
184 for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) {
578ce4be 185 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(Cu2);
5201d3e6 186 Adaptor2d_OffsetCurve C2(HCu2,cote2(jcote2));
187 firstparam = Max(C2.FirstParameter(),thefirst);
188 lastparam = Min(C2.LastParameter(),thelast);
189 IntRes2d_Domain D2(C2.Value(firstparam), firstparam, Tol,
190 C2.Value(lastparam), lastparam, Tol);
578ce4be 191 Geom2dInt_TheIntConicCurveOfGInter Intp(Line,D1,C2,D2,Tol,Tol);
74f5f8df 192 if (Intp.IsDone()) {
193 if (!Intp.IsEmpty()) {
194 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
195 NbrSol++;
196 gp_Pnt2d Center(Intp.Point(i).Value());
197 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
198 // =======================================================
199 gp_Dir2d dc1(origin1.XY()-Center.XY());
200 qualifier2(NbrSol) = Qualified2.Qualifier();
201 if (!Qualified1.IsUnqualified()) {
202 qualifier1(NbrSol) = Qualified1.Qualifier();
203 }
204 else if (dc1.Dot(normL1) > 0.0) {
205 qualifier1(NbrSol) = GccEnt_outside;
206 }
207 else { qualifier1(NbrSol) = GccEnt_enclosed; }
208 TheSame1(NbrSol) = 0;
209 TheSame2(NbrSol) = 0;
210 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
211 pararg2(NbrSol) = Intp.Point(i).ParamOnSecond();
212 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),L1);
578ce4be 213 pnttg2sol(NbrSol) = Geom2dGcc_CurveTool::Value(Cu2,pararg2(NbrSol));
74f5f8df 214 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
215 pnttg1sol(NbrSol));
216 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
217 pnttg2sol(NbrSol));
218 }
219 }
220 WellDone = Standard_True;
221 }
222 }
223 }
224 }
225}
7fd59977 226
227// circulaire tant a une courbe et un cercle ,de rayon donne
228//=============================================================
229
230//========================================================================
231// On initialise WellDone a false. +
232// On recupere la courbe Cu2 et le cercle C1. +
233// On sort en erreur dans les cas ou la construction est impossible. +
234// On fait la parallele a Cu2 dans le bon sens. +
235// On fait la parallele a C1 dans le bon sens. +
236// On intersecte les paralleles ==> point de centre de la solution. +
237// On cree la solution qu on ajoute aux solutions deja trouvees. +
238// On remplit les champs. +
239//========================================================================
240
578ce4be 241Geom2dGcc_Circ2d2TanRadGeo::
242Geom2dGcc_Circ2d2TanRadGeo (const GccEnt_QualifiedCirc& Qualified1,
243 const Geom2dGcc_QCurve& Qualified2,
244 const Standard_Real Radius ,
245 const Standard_Real Tolerance ):
7fd59977 246
247//========================================================================
248// initialisation des champs. +
249//========================================================================
250
1d19db8d 251cirsol(1,aNbSolMAX) ,
252qualifier1(1,aNbSolMAX),
253qualifier2(1,aNbSolMAX),
254TheSame1(1,aNbSolMAX) ,
255TheSame2(1,aNbSolMAX) ,
256pnttg1sol(1,aNbSolMAX),
257pnttg2sol(1,aNbSolMAX),
258par1sol(1,aNbSolMAX) ,
259par2sol(1,aNbSolMAX) ,
260pararg1(1,aNbSolMAX) ,
261pararg2(1,aNbSolMAX)
7fd59977 262{
263
74f5f8df 264 //========================================================================
265 // Traitement. +
266 //========================================================================
267
268 Standard_Real Tol = Abs(Tolerance);
269 Standard_Real thefirst = -100000.;
270 Standard_Real thelast = 100000.;
271 Standard_Real firstparam;
272 Standard_Real lastparam;
273 gp_Dir2d dirx(1.,0.);
274 TColStd_Array1OfReal cote1(1,2);
275 TColStd_Array1OfReal cote2(1,2);
276 Standard_Integer nbrcote1=0;
277 Standard_Integer nbrcote2=0;
278 WellDone = Standard_False;
279 NbrSol = 0;
280 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
281 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
282 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
283 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
9775fa61 284 throw GccEnt_BadQualifier();
74f5f8df 285 return;
286 }
287 gp_Circ2d C1 = Qualified1.Qualified();
288 gp_Pnt2d center1(C1.Location());
578ce4be 289 Geom2dAdaptor_Curve Cu2 = Qualified2.Qualified();
9775fa61 290 if (Radius < 0.0) { throw Standard_NegativeValue(); }
74f5f8df 291 else {
292 if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
293 // =======================================================
294 nbrcote1 = 1;
295 nbrcote2 = 1;
296 cote1(1) = Radius;
297 cote2(1) = Radius;
298 }
299 else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
300 // ==========================================================
301 nbrcote1 = 1;
302 nbrcote2 = 1;
303 cote1(1) = Radius;
304 cote2(1) = -Radius;
305 }
306 else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
307 // ===========================================================
308 nbrcote1 = 1;
309 nbrcote2 = 1;
310 cote1(1) = -Radius;
311 cote2(1) = Radius;
312 }
313 else if(Qualified1.IsOutside() && Qualified2.IsOutside()) {
314 // =========================================================
315 nbrcote1 = 1;
316 nbrcote2 = 1;
317 cote1(1) = -Radius;
318 cote2(1) = -Radius;
319 }
320 if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
321 // =========================================================
322 nbrcote1 = 1;
323 nbrcote2 = 2;
324 cote1(1) = Radius;
325 cote2(1) = Radius;
326 cote2(2) = -Radius;
327 }
328 if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
329 // =========================================================
330 nbrcote1 = 2;
331 nbrcote2 = 1;
332 cote1(1) = Radius;
333 cote1(2) = -Radius;
334 cote2(1) = Radius;
335 }
336 else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
337 // =============================================================
338 nbrcote1 = 1;
339 nbrcote2 = 2;
340 cote1(1) = -Radius;
341 cote2(1) = Radius;
342 cote2(2) = -Radius;
343 }
344 if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
345 // ========================================================
346 nbrcote1 = 2;
347 nbrcote2 = 1;
348 cote1(1) = Radius;
349 cote1(2) = -Radius;
350 cote2(1) = -Radius;
351 }
352 else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
353 // =================================================================
354 nbrcote1 = 2;
355 nbrcote2 = 2;
356 cote1(1) = Radius;
357 cote1(2) = -Radius;
358 cote2(1) = Radius;
359 cote2(2) = -Radius;
360 }
361 Standard_Real R1 = C1.Radius();
578ce4be 362 Geom2dInt_TheIntConicCurveOfGInter Intp;
74f5f8df 363 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
364 gp_Circ2d Circ(C1.XAxis(),R1+cote1(jcote1));
365 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
366 ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol);
367 D1.SetEquivalentParameters(0.,2.*M_PI);
368 for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) {
578ce4be 369 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(Cu2);
5201d3e6 370 Adaptor2d_OffsetCurve C2(HCu2,cote2(jcote2));
371 firstparam = Max(C2.FirstParameter(),thefirst);
372 lastparam = Min(C2.LastParameter(),thelast);
373 IntRes2d_Domain D2(C2.Value(firstparam), firstparam, Tol,
374 C2.Value(lastparam), lastparam, Tol);
74f5f8df 375 Intp.Perform(Circ,D1,C2,D2,Tol,Tol);
376 if (Intp.IsDone()) {
377 if (!Intp.IsEmpty()) {
378 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
379 NbrSol++;
380 gp_Pnt2d Center(Intp.Point(i).Value());
381 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
382 // =======================================================
0797d9d3 383#ifdef OCCT_DEBUG
74f5f8df 384 gp_Dir2d dir1(Center.XY()-center1.XY());
7fd59977 385#else
74f5f8df 386 Center.XY() ;
387 center1.XY() ;
7fd59977 388#endif
74f5f8df 389 Standard_Real distcc1 = Center.Distance(center1);
390 if (!Qualified1.IsUnqualified()) {
391 qualifier1(NbrSol) = Qualified1.Qualifier();
392 }
393 else if (Abs(distcc1+Radius-R1) < Tol) {
394 qualifier1(NbrSol) = GccEnt_enclosed;
395 }
396 else if (Abs(distcc1-R1-Radius) < Tol) {
397 qualifier1(NbrSol) = GccEnt_outside;
398 }
399 else { qualifier1(NbrSol) = GccEnt_enclosing; }
400 qualifier2(NbrSol) = Qualified2.Qualifier();
401 TheSame1(NbrSol) = 0;
402 TheSame2(NbrSol) = 0;
403 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
404 pararg2(NbrSol) = Intp.Point(i).ParamOnSecond();
405 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),C1);
578ce4be 406 pnttg2sol(NbrSol) = Geom2dGcc_CurveTool::Value(Cu2,pararg2(NbrSol));
74f5f8df 407 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
408 pnttg1sol(NbrSol));
409 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
410 pnttg2sol(NbrSol));
411 }
412 }
413 WellDone = Standard_True;
414 }
415 }
416 }
417 }
418}
7fd59977 419
420// circulaire tant a une courbe et un point ,de rayon donne
421//============================================================
422
423//========================================================================
424// On initialise WellDone a false. +
425// On recupere la courbe Cu1 et le point P2. +
426// On sort en erreur dans les cas ou la construction est impossible. +
427// On fait la parallele a Cu1 dans le bon sens. +
428// On fait la parallele a P2 dans le bon sens. +
429// On intersecte les paralleles ==> point de centre de la solution. +
430// On cree la solution qu on ajoute aux solutions deja trouvees. +
431// On remplit les champs. +
432//========================================================================
433
578ce4be 434Geom2dGcc_Circ2d2TanRadGeo::
435Geom2dGcc_Circ2d2TanRadGeo (const Geom2dGcc_QCurve& Qualified1,
436 const gp_Pnt2d& Point2 ,
437 const Standard_Real Radius ,
438 const Standard_Real Tolerance ):
7fd59977 439
440//========================================================================
441// initialisation des champs. +
442//========================================================================
443
1d19db8d 444cirsol(1,aNbSolMAX) ,
445qualifier1(1,aNbSolMAX),
446qualifier2(1,aNbSolMAX),
447TheSame1(1,aNbSolMAX) ,
448TheSame2(1,aNbSolMAX) ,
449pnttg1sol(1,aNbSolMAX),
450pnttg2sol(1,aNbSolMAX),
451par1sol(1,aNbSolMAX) ,
452par2sol(1,aNbSolMAX) ,
453pararg1(1,aNbSolMAX) ,
454pararg2(1,aNbSolMAX)
7fd59977 455{
456
74f5f8df 457 //========================================================================
458 // Traitement. +
459 //========================================================================
460
461 Standard_Real Tol = Abs(Tolerance);
462 Standard_Real thefirst = -100000.;
463 Standard_Real thelast = 100000.;
464 Standard_Real firstparam;
465 Standard_Real lastparam;
466 gp_Dir2d dirx(1.,0.);
467 TColStd_Array1OfReal cote1(1,2);
468 Standard_Integer nbrcote1=0;
469 WellDone = Standard_False;
470 NbrSol = 0;
471 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
472 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
9775fa61 473 throw GccEnt_BadQualifier();
74f5f8df 474 return;
475 }
578ce4be 476 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
9775fa61 477 if (Radius < 0.0) { throw Standard_NegativeValue(); }
74f5f8df 478 else {
479 if (Qualified1.IsEnclosed()) {
480 // ===========================
481 nbrcote1 = 1;
482 cote1(1) = Radius;
483 }
484 else if(Qualified1.IsOutside()) {
485 // ===============================
486 nbrcote1 = 1;
487 cote1(1) = -Radius;
488 }
489 else if(Qualified1.IsUnqualified()) {
490 // ===================================
491 nbrcote1 = 2;
492 cote1(1) = Radius;
493 cote1(2) = -Radius;
494 }
495 gp_Circ2d Circ(gp_Ax2d(Point2,gp_Dir2d(1.,0.)),Radius);
496 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
497 ElCLib::Value(M_PI+M_PI,Circ),M_PI+M_PI,Tol);
498 D1.SetEquivalentParameters(0.,M_PI+M_PI);
578ce4be 499 Geom2dInt_TheIntConicCurveOfGInter Intp;
74f5f8df 500 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
578ce4be 501 Handle(Geom2dAdaptor_HCurve) HCu1 = new Geom2dAdaptor_HCurve(Cu1);
5201d3e6 502 Adaptor2d_OffsetCurve Cu2(HCu1,cote1(jcote1));
503 firstparam = Max(Cu2.FirstParameter(),thefirst);
504 lastparam = Min(Cu2.LastParameter(),thelast);
505 IntRes2d_Domain D2(Cu2.Value(firstparam), firstparam, Tol,
506 Cu2.Value(lastparam), lastparam, Tol);
74f5f8df 507 Intp.Perform(Circ,D1,Cu2,D2,Tol,Tol);
508 if (Intp.IsDone()) {
509 if (!Intp.IsEmpty()) {
510 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
511 NbrSol++;
512 gp_Pnt2d Center(Intp.Point(i).Value());
513 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
514 // =======================================================
515 qualifier1(NbrSol) = Qualified1.Qualifier();
516 qualifier2(NbrSol) = GccEnt_noqualifier;
517 TheSame1(NbrSol) = 0;
518 TheSame2(NbrSol) = 0;
519 pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
520 pararg2(NbrSol) = 0.;
578ce4be 521 pnttg1sol(NbrSol) = Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol));
74f5f8df 522 pnttg2sol(NbrSol) = Point2;
523 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
524 pnttg1sol(NbrSol));
525 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
526 pnttg2sol(NbrSol));
527 }
528 }
529 WellDone = Standard_True;
530 }
531 }
532 }
533}
534
1d19db8d 535//=======================================================================
536//function : PrecRoot
537//purpose : In case, when curves has tangent zones, intersection point
538// found may be precised. This function uses precision algorithm
539// of Extrema Curve-Curve method (dot product between every
540// tangent vector and vector between points in two curves must
541// be equal to zero).
542//=======================================================================
5201d3e6 543static void PrecRoot(const Adaptor2d_OffsetCurve& theC1,
544 const Adaptor2d_OffsetCurve& theC2,
578ce4be 545 const Standard_Real theU0,
546 const Standard_Real theV0,
578ce4be 547 Standard_Real& theUfinal,
548 Standard_Real& theVfinal)
74f5f8df 549{
1d19db8d 550/*
551It is necessary for precision to solve the system
552
553 \left\{\begin{matrix}
554 (x_{1}(u)-x_{2}(v))*{x_{1}(u)}'+(y_{1}(u)-y_{2}(v))*{y_{1}(u)}'=0\\
555 (x_{1}(u)-x_{2}(v))*{x_{2}(v)}'+(y_{1}(u)-y_{2}(v))*{y_{2}(v)}'=0
556 \end{matrix}\right.
557
558Precision of any 2*2-system (two equation and two variables)
559
560 \left\{\begin{matrix}
561 S_{1}(u,v)=0\\
562 S_{2}(u,v)=0
563 \end{matrix}\right.
564
565by Newton method can be made as follows:
566
567 u=u_{0}-\left (\frac{\frac{\partial S_{2}}{\partial v}*S_{1}-
568 \frac{\partial S_{1}}{\partial v}*S_{2}}
569 {\frac{\partial S_{1}}{\partial u}*
570 \frac{\partial S_{2}}{\partial v}-
571 \frac{\partial S_{1}}{\partial v}*
572 \frac{\partial S_{2}}{\partial u}} \right )_{u_{0},v_{0}}\\
573 v=v_{0}-\left (\frac{\frac{\partial S_{1}}{\partial u}*S_{2}-
574 \frac{\partial S_{2}}{\partial u}*S_{1}}
575 {\frac{\partial S_{1}}{\partial u}*
576 \frac{\partial S_{2}}{\partial v}-
577 \frac{\partial S_{1}}{\partial v}*
578 \frac{\partial S_{2}}{\partial u}} \right )_{u_{0},v_{0}}
579 \end{matrix}\right.
580
581where u_{0} and v_{0} are initial values or values computed on previous iteration.
582*/
74f5f8df 583
1d19db8d 584 theUfinal = theU0;
585 theVfinal = theV0;
74f5f8df 586
74f5f8df 587 const Standard_Integer aNbIterMax = 100;
588
1d19db8d 589 Standard_Real aU = theU0, aV = theV0;
590 gp_Pnt2d aPu, aPv;
591 gp_Vec2d aD1u, aD1v, aD2u, aD2v;
74f5f8df 592
1d19db8d 593 Standard_Integer aNbIter = 0;
74f5f8df 594
1d19db8d 595 Standard_Real aStepU = 0.0, aStepV = 0.0;
74f5f8df 596
1d19db8d 597 Standard_Real aSQDistPrev = RealFirst();
74f5f8df 598
5201d3e6 599 theC1.D2(aU, aPu, aD1u, aD2u);
600 theC2.D2(aV, aPv, aD1v, aD2v);
578ce4be 601
1d19db8d 602 const Standard_Real aCrProd = Abs(aD1u.Crossed(aD1v));
603 if(aCrProd*aCrProd > 1.0e-6*
604 aD1u.SquareMagnitude()*aD1v.SquareMagnitude())
605 {
606 //Curves are not tangent. Therefore, we consider that
607 //2D-intersection algorithm have found good point which
608 //did not need in more precision.
609 return;
610 }
74f5f8df 611
612 do
613 {
1d19db8d 614 aNbIter++;
74f5f8df 615
1d19db8d 616 gp_Vec2d aVuv(aPv, aPu);
74f5f8df 617
1d19db8d 618 Standard_Real aSQDist = aVuv.SquareMagnitude();
619 if(IsEqual(aSQDist, 0.0))
620 break;
74f5f8df 621
1d19db8d 622 if((aNbIter == 1) || (aSQDist < aSQDistPrev))
74f5f8df 623 {
624 aSQDistPrev = aSQDist;
74f5f8df 625 theUfinal = aU;
626 theVfinal = aV;
627 }
74f5f8df 628
74f5f8df 629
1d19db8d 630 Standard_Real aG1 = aD1u.Magnitude();
631 Standard_Real aG2 = aD1v.Magnitude();
74f5f8df 632
1d19db8d 633 if(IsEqual(aG1, 0.0) || IsEqual(aG2, 0.0))
634 {//Here we do not processing singular cases.
635 break;
636 }
74f5f8df 637
1d19db8d 638 Standard_Real aF1 = aVuv.Dot(aD1u);
639 Standard_Real aF2 = aVuv.Dot(aD1v);
74f5f8df 640
1d19db8d 641 Standard_Real aFIu = aVuv.Dot(aD2u);
642 Standard_Real aFIv = aVuv.Dot(aD2v);
643 Standard_Real aPSIu = aD1u.Dot(aD2u);
644 Standard_Real aPSIv = aD1v.Dot(aD2v);
7fd59977 645
1d19db8d 646 Standard_Real aTheta = aD1u*aD1v;
74f5f8df 647
1d19db8d 648 Standard_Real aS1 = aF1/aG1;
649 Standard_Real aS2 = aF2/aG2;
74f5f8df 650
1d19db8d 651 Standard_Real aDS1u = (aG1*aG1+aFIu)/aG1 - (aS1*aPSIu/(aG1*aG1));
652 Standard_Real aDS1v = -aTheta/aG1;
653 Standard_Real aDS2u = aTheta/aG2;
654 Standard_Real aDS2v = (aFIv-aG2*aG2)/aG2 - (aS2*aPSIv/(aG2*aG2));
74f5f8df 655
1d19db8d 656 Standard_Real aDet = aDS1u*aDS2v-aDS1v*aDS2u;
74f5f8df 657
1d19db8d 658 if(IsEqual(aDet, 0.0))
659 {
660 if(!IsEqual(aStepV, 0.0) && !IsEqual(aDS1u, 0.0))
661 {
662 aV += aStepV;
663 aU = aU - (aDS1v*aStepV - aS1)/aDS1u;
664 }
665 else if(!IsEqual(aStepU, 0.0) && !IsEqual(aDS1v, 0.0))
666 {
667 aU += aStepU;
668 aV = aV - (aDS1u*aStepU - aS1)/aDS1v;
669 }
670 else
671 {
672 break;
673 }
674 }
74f5f8df 675 else
1d19db8d 676 {
677 aStepU = -(aS1*aDS2v-aS2*aDS1v)/aDet;
678 aStepV = -(aS2*aDS1u-aS1*aDS2u)/aDet;
679
680 if(Abs(aStepU) < Epsilon(Abs(aU)))
681 {
682 if(Abs(aStepV) < Epsilon(Abs(aV)))
683 {
684 break;
685 }
686 }
74f5f8df 687
1d19db8d 688 aU += aStepU;
689 aV += aStepV;
690 }
74f5f8df 691
5201d3e6 692 theC1.D2(aU, aPu, aD1u, aD2u);
693 theC2.D2(aV, aPv, aD1v, aD2v);
74f5f8df 694 }
1d19db8d 695 while(aNbIter <= aNbIterMax);
696}
74f5f8df 697
74f5f8df 698
7fd59977 699
700// circulaire tant a deux courbes ,de rayon donne
701//==================================================
702
703//========================================================================
704// On initialise WellDone a false. +
705// On recupere les courbes Cu1 et Cu2. +
706// On sort en erreur dans les cas ou la construction est impossible. +
707// On fait la parallele a Cu1 dans le bon sens. +
708// On fait la parallele a Cu2 dans le bon sens. +
709// On intersecte les paralleles ==> point de centre de la solution. +
710// On cree la solution qu on ajoute aux solutions deja trouvees. +
711// On remplit les champs. +
712//========================================================================
578ce4be 713Geom2dGcc_Circ2d2TanRadGeo::
714Geom2dGcc_Circ2d2TanRadGeo (const Geom2dGcc_QCurve& Qualified1,
715 const Geom2dGcc_QCurve& Qualified2,
716 const Standard_Real Radius ,
717 const Standard_Real Tolerance ):
7fd59977 718
719//========================================================================
720// initialisation des champs. +
721//========================================================================
722
1d19db8d 723cirsol(1,aNbSolMAX) ,
724qualifier1(1,aNbSolMAX),
725qualifier2(1,aNbSolMAX),
726TheSame1(1,aNbSolMAX) ,
727TheSame2(1,aNbSolMAX) ,
728pnttg1sol(1,aNbSolMAX),
729pnttg2sol(1,aNbSolMAX),
730par1sol(1,aNbSolMAX) ,
731par2sol(1,aNbSolMAX) ,
732pararg1(1,aNbSolMAX) ,
733pararg2(1,aNbSolMAX)
7fd59977 734{
735
74f5f8df 736 //========================================================================
737 // Traitement. +
738 //========================================================================
739
740 Standard_Real Tol = Abs(Tolerance);
5201d3e6 741#ifdef OCCT_DEBUG
742 const Standard_Real thefirst = -100000.;
743 const Standard_Real thelast = 100000.;
744#endif
74f5f8df 745 gp_Dir2d dirx(1.,0.);
746 TColStd_Array1OfReal cote1(1,2);
747 TColStd_Array1OfReal cote2(1,2);
748 Standard_Integer nbrcote1=0;
749 Standard_Integer nbrcote2=0;
750 WellDone = Standard_False;
751 NbrSol = 0;
752 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
753 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
754 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
755 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
9775fa61 756 throw GccEnt_BadQualifier();
74f5f8df 757 return;
758 }
578ce4be 759 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
760 Geom2dAdaptor_Curve Cu2 = Qualified2.Qualified();
9775fa61 761 if (Radius < 0.0) { throw Standard_NegativeValue(); }
74f5f8df 762 else {
763 if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
764 // =======================================================
765 nbrcote1 = 1;
766 nbrcote2 = 1;
767 cote1(1) = Radius;
768 cote2(1) = Radius;
769 }
770 else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
771 // ==========================================================
772 nbrcote1 = 1;
773 nbrcote2 = 1;
774 cote1(1) = Radius;
775 cote2(1) = -Radius;
776 }
777 else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
778 // ===========================================================
779 nbrcote1 = 1;
780 nbrcote2 = 1;
781 cote1(1) = -Radius;
782 cote2(1) = Radius;
783 }
784 else if(Qualified1.IsOutside() && Qualified2.IsOutside()) {
785 // =========================================================
786 nbrcote1 = 1;
787 nbrcote2 = 1;
788 cote1(1) = -Radius;
789 cote2(1) = -Radius;
790 }
791 if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
792 // =========================================================
793 nbrcote1 = 1;
794 nbrcote2 = 2;
795 cote1(1) = Radius;
796 cote2(1) = Radius;
797 cote2(2) = -Radius;
798 }
799 if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
800 // =========================================================
801 nbrcote1 = 2;
802 nbrcote2 = 1;
803 cote1(1) = Radius;
804 cote1(2) = -Radius;
805 cote2(1) = Radius;
806 }
807 else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
808 // =============================================================
809 nbrcote1 = 1;
810 nbrcote2 = 2;
811 cote1(1) = -Radius;
812 cote2(1) = Radius;
813 cote2(2) = -Radius;
814 }
815 if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
816 // ========================================================
817 nbrcote1 = 2;
818 nbrcote2 = 1;
819 cote1(1) = Radius;
820 cote1(2) = -Radius;
821 cote2(1) = -Radius;
822 }
823 else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
824 // =================================================================
825 nbrcote1 = 2;
826 nbrcote2 = 2;
827 cote1(1) = Radius;
828 cote1(2) = -Radius;
829 cote2(1) = Radius;
830 cote2(2) = -Radius;
831 }
578ce4be 832 Geom2dInt_GInter Intp;
74f5f8df 833 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
578ce4be 834 Handle(Geom2dAdaptor_HCurve) HCu1 = new Geom2dAdaptor_HCurve(Cu1);
5201d3e6 835 Adaptor2d_OffsetCurve C1(HCu1,cote1(jcote1));
0797d9d3 836#ifdef OCCT_DEBUG
5201d3e6 837 Standard_Real firstparam = Max(C1.FirstParameter(), thefirst);
838 Standard_Real lastparam = Min(C1.LastParameter(), thelast);
ec7ed71c 839 IntRes2d_Domain D2C1(C1.Value(firstparam),firstparam,Tol,
840 C1.Value(lastparam),lastparam,Tol);
7fd59977 841#endif
74f5f8df 842 for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) {
578ce4be 843 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(Cu2);
5201d3e6 844 Adaptor2d_OffsetCurve C2(HCu2,cote2(jcote2));
0797d9d3 845#ifdef OCCT_DEBUG
5201d3e6 846 firstparam = Max(C2.FirstParameter(), thefirst);
847 lastparam = Min(C2.LastParameter(),thelast);
ec7ed71c 848 IntRes2d_Domain D2C2(C2.Value(firstparam),firstparam,Tol,
849 C2.Value(lastparam),lastparam,Tol);
7fd59977 850#endif
74f5f8df 851 Intp.Perform(C1,C2,Tol,Tol);
852 if (Intp.IsDone()) {
853 if (!Intp.IsEmpty()) {
1d19db8d 854 const Standard_Real aSQApproxTol = Precision::Approximation() *
855 Precision::Approximation();
74f5f8df 856 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++)
857 {
858 Standard_Real aU0 = Intp.Point(i).ParamOnFirst();
859 Standard_Real aV0 = Intp.Point(i).ParamOnSecond();
860
861 Standard_Real aU1 = aU0-Precision::PApproximation();
862 Standard_Real aV1 = aV0-Precision::PApproximation();
863
864 Standard_Real aU2 = aU0+Precision::PApproximation();
865 Standard_Real aV2 = aV0+Precision::PApproximation();
866
5201d3e6 867 gp_Pnt2d P11 = C1.Value(aU1);
868 gp_Pnt2d P12 = C2.Value(aV1);
869 gp_Pnt2d P21 = C1.Value(aU2);
870 gp_Pnt2d P22 = C2.Value(aV2);
74f5f8df 871
1d19db8d 872 Standard_Real aDist1112 = P11.SquareDistance(P12);
873 Standard_Real aDist1122 = P11.SquareDistance(P22);
74f5f8df 874
1d19db8d 875 Standard_Real aDist1221 = P12.SquareDistance(P21);
876 Standard_Real aDist2122 = P21.SquareDistance(P22);
74f5f8df 877
1d19db8d 878 if( (Min(aDist1112, aDist1122) <= aSQApproxTol) &&
879 (Min(aDist1221, aDist2122) <= aSQApproxTol))
74f5f8df 880 {
1d19db8d 881 PrecRoot(C1, C2, aU0, aV0, aU0, aV0);
74f5f8df 882 }
883
884 NbrSol++;
5201d3e6 885 gp_Pnt2d Center(C1.Value(aU0));
74f5f8df 886 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
887 // =======================================================
888 qualifier1(NbrSol) = Qualified1.Qualifier();
889 qualifier1(NbrSol) = Qualified1.Qualifier();
890 TheSame1(NbrSol) = 0;
891 TheSame2(NbrSol) = 0;
892 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
893 pararg2(NbrSol) = Intp.Point(i).ParamOnSecond();
578ce4be 894 pnttg1sol(NbrSol) = Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol));
895 pnttg2sol(NbrSol) = Geom2dGcc_CurveTool::Value(Cu2,pararg2(NbrSol));
74f5f8df 896 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
897 pnttg1sol(NbrSol));
898 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
899 pnttg2sol(NbrSol));
900 }
901 }
902
903 WellDone = Standard_True;
904 }
905 }
906 }
907 }
908}
7fd59977 909
910//=========================================================================
911
578ce4be 912Standard_Boolean Geom2dGcc_Circ2d2TanRadGeo::
74f5f8df 913IsDone () const { return WellDone; }
7fd59977 914
578ce4be 915Standard_Integer Geom2dGcc_Circ2d2TanRadGeo::
74f5f8df 916NbSolutions () const { return NbrSol; }
7fd59977 917
578ce4be 918gp_Circ2d Geom2dGcc_Circ2d2TanRadGeo::
74f5f8df 919ThisSolution (const Standard_Integer Index) const
7fd59977 920{
9775fa61 921 if (!WellDone) { throw StdFail_NotDone(); }
922 if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
7fd59977 923 return cirsol(Index);
924}
925
578ce4be 926void Geom2dGcc_Circ2d2TanRadGeo::
74f5f8df 927WhichQualifier(const Standard_Integer Index ,
928 GccEnt_Position& Qualif1 ,
929 GccEnt_Position& Qualif2 ) const
7fd59977 930{
9775fa61 931 if (!WellDone) { throw StdFail_NotDone(); }
932 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
7fd59977 933 else {
934 Qualif1 = qualifier1(Index);
935 Qualif2 = qualifier2(Index);
936 }
937}
938
578ce4be 939void Geom2dGcc_Circ2d2TanRadGeo::
74f5f8df 940Tangency1 (const Standard_Integer Index,
941 Standard_Real& ParSol,
942 Standard_Real& ParArg,
943 gp_Pnt2d& PntSol) const{
9775fa61 944 if (!WellDone) { throw StdFail_NotDone(); }
945 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
74f5f8df 946 else {
947 if (TheSame1(Index) == 0) {
948 ParSol = par1sol(Index);
949 ParArg = pararg1(Index);
950 PntSol = gp_Pnt2d(pnttg1sol(Index));
951 }
9775fa61 952 else { throw StdFail_NotDone(); }
74f5f8df 953 }
954}
7fd59977 955
578ce4be 956void Geom2dGcc_Circ2d2TanRadGeo::
74f5f8df 957Tangency2 (const Standard_Integer Index,
958 Standard_Real& ParSol,
959 Standard_Real& ParArg,
960 gp_Pnt2d& PntSol) const{
9775fa61 961 if (!WellDone) { throw StdFail_NotDone(); }
962 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
74f5f8df 963 else {
964 if (TheSame2(Index) == 0) {
965 ParSol = par2sol(Index);
966 ParArg = pararg2(Index);
967 PntSol = gp_Pnt2d(pnttg2sol(Index));
968 }
9775fa61 969 else { throw StdFail_NotDone(); }
74f5f8df 970 }
971}
7fd59977 972
578ce4be 973Standard_Boolean Geom2dGcc_Circ2d2TanRadGeo::
74f5f8df 974IsTheSame1 (const Standard_Integer Index) const
7fd59977 975{
9775fa61 976 if (!WellDone) { throw StdFail_NotDone(); }
977 if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
7fd59977 978
979 if (TheSame1(Index) == 0) { return Standard_False; }
980 return Standard_True;
981}
982
578ce4be 983Standard_Boolean Geom2dGcc_Circ2d2TanRadGeo::
74f5f8df 984IsTheSame2 (const Standard_Integer Index) const
7fd59977 985{
9775fa61 986 if (!WellDone) { throw StdFail_NotDone(); }
987 if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
7fd59977 988
989 if (TheSame2(Index) == 0) { return Standard_False; }
990 return Standard_True;
991}
992