1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //========================================================================
16 // circulaire tangent a un element de type : - Cercle. +
17 // - Ligne. +
18 // - Point. +
19 // centre sur un deuxieme element de type : - Cercle. +
20 // - Ligne. +
21 // de rayon donne : Radius. +
22 //========================================================================
23
24 #include <Adaptor2d_OffsetCurve.hxx>
25 #include <ElCLib.hxx>
26 #include <GccEnt_BadQualifier.hxx>
27 #include <GccEnt_QualifiedCirc.hxx>
28 #include <GccEnt_QualifiedLin.hxx>
29 #include <Geom2dAdaptor_Curve.hxx>
30 #include <Geom2dAdaptor_Curve.hxx>
31 #include <Geom2dGcc_Circ2dTanOnRadGeo.hxx>
32 #include <Geom2dGcc_CurveTool.hxx>
33 #include <Geom2dGcc_QCurve.hxx>
34 #include <Geom2dInt_GInter.hxx>
35 #include <gp_Circ2d.hxx>
36 #include <gp_Dir2d.hxx>
37 #include <gp_Lin2d.hxx>
38 #include <gp_Pnt2d.hxx>
39 #include <IntRes2d_Domain.hxx>
40 #include <IntRes2d_IntersectionPoint.hxx>
41 #include <math_DirectPolynomialRoots.hxx>
42 #include <Standard_NegativeValue.hxx>
43 #include <Standard_OutOfRange.hxx>
44 #include <StdFail_NotDone.hxx>
45 #include <TColStd_Array1OfReal.hxx>
46
47 static const Standard_Integer aNbSolMAX = 8;
48
49 //=========================================================================
50 // Cercle tangent : a un cercle Qualified1 (C1). +
51 // centre : sur une droite OnLine. +
52 // de rayon : Radius. +
53 // +
54 // On initialise le tableau de solutions cirsol ainsi que tous les +
55 // champs. +
56 // On elimine en fonction du qualifieur les cas ne presentant pas de +
57 // solutions. +
58 // On resoud l equation du second degre indiquant que le point de centre +
59 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
60 // sur la droite OnLine. +
61 // Les solutions sont representees par les cercles : +
62 // - de centre Pntcen(xc,yc) +
63 // - de rayon Radius. +
64 //=========================================================================
65 Geom2dGcc_Circ2dTanOnRadGeo::
Geom2dGcc_Circ2dTanOnRadGeo(const Geom2dGcc_QCurve & Qualified1,const gp_Lin2d & OnLine,const Standard_Real Radius,const Standard_Real Tolerance)66 Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1,
67 const gp_Lin2d& OnLine ,
68 const Standard_Real Radius ,
69 const Standard_Real Tolerance ):
70
71 //=========================================================================
72 // Initialisation des champs. +
73 //=========================================================================
74
75 cirsol(1,aNbSolMAX) ,
76 qualifier1(1,aNbSolMAX) ,
77 TheSame1(1,aNbSolMAX) ,
78 pnttg1sol(1,aNbSolMAX) ,
79 pntcen3(1,aNbSolMAX) ,
80 par1sol(1,aNbSolMAX) ,
81 pararg1(1,aNbSolMAX) ,
82 parcen3(1,aNbSolMAX)
83 {
84
85 //=========================================================================
86 // Traitement. +
87 //=========================================================================
88
89 gp_Dir2d dirx(1.0,0.0);
90 Standard_Real Tol = Abs(Tolerance);
91 Standard_Real thefirst = -100000.;
92 Standard_Real thelast = 100000.;
93 Standard_Real firstparam;
94 Standard_Real lastparam;
95 WellDone = Standard_False;
96 NbrSol = 0;
97 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
98 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
99 throw GccEnt_BadQualifier();
100 return;
101 }
102 Standard_Integer nbrcote1 = 0;
103 TColStd_Array1OfReal Coef(1,2);
104 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
105
106 if (Radius < 0.0) { throw Standard_NegativeValue(); }
107 else {
108 if (Qualified1.IsEnclosed()) {
109 // ===========================
110 nbrcote1 = 1;
111 Coef(1) = Radius;
112 }
113 else if(Qualified1.IsOutside()) {
114 // ===============================
115 nbrcote1 = 1;
116 Coef(1) = -Radius;
117 }
118 else if(Qualified1.IsUnqualified()) {
119 // ===================================
120 nbrcote1 = 2;
121 Coef(1) = Radius;
122 Coef(2) = -Radius;
123 }
124 IntRes2d_Domain D1;
125 Geom2dInt_TheIntConicCurveOfGInter Intp;
126 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
127 Handle(Geom2dAdaptor_Curve) HCu1 = new Geom2dAdaptor_Curve(Cu1);
128 //Adaptor2d_OffsetCurve C2(HCu1,Coef(jcote1));
129 Adaptor2d_OffsetCurve C2(HCu1, -Coef(jcote1));
130 firstparam = Max(C2.FirstParameter(),thefirst);
131 lastparam = Min(C2.LastParameter(),thelast);
132 IntRes2d_Domain D2(C2.Value(firstparam), firstparam, Tol,
133 C2.Value(lastparam), lastparam, Tol);
134 Intp.Perform(OnLine,D1,C2,D2,Tol,Tol);
135 if (Intp.IsDone()) {
136 if (!Intp.IsEmpty()) {
137 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
138 NbrSol++;
139 gp_Pnt2d Center(Intp.Point(i).Value());
140 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
141 // =======================================================
142 qualifier1(NbrSol) = Qualified1.Qualifier();
143 TheSame1(NbrSol) = 0;
144 pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
145 parcen3(NbrSol) = Intp.Point(i).ParamOnFirst();
146 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
147 pnttg1sol(NbrSol));
148 pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol)));
149 pntcen3(NbrSol) = Center;
150 }
151 }
152 WellDone = Standard_True;
153 }
154 }
155 }
156 }
157
158 //=========================================================================
159 // Cercle tangent : a un cercle Qualified1 (C1). +
160 // centre : sur une droite OnLine. +
161 // de rayon : Radius. +
162 // +
163 // On initialise le tableau de solutions cirsol ainsi que tous les +
164 // champs. +
165 // On elimine en fonction du qualifieur les cas ne presentant pas de +
166 // solutions. +
167 // On resoud l equation du second degre indiquant que le point de centre +
168 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
169 // sur la droite OnLine. +
170 // Les solutions sont representees par les cercles : +
171 // - de centre Pntcen(xc,yc) +
172 // - de rayon Radius. +
173 //=========================================================================
174
175 Geom2dGcc_Circ2dTanOnRadGeo::
Geom2dGcc_Circ2dTanOnRadGeo(const Geom2dGcc_QCurve & Qualified1,const gp_Circ2d & OnCirc,const Standard_Real Radius,const Standard_Real Tolerance)176 Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1,
177 const gp_Circ2d& OnCirc ,
178 const Standard_Real Radius ,
179 const Standard_Real Tolerance ):
180
181 //=========================================================================
182 // Initialisation des champs. +
183 //=========================================================================
184
185 cirsol(1,aNbSolMAX) ,
186 qualifier1(1,aNbSolMAX) ,
187 TheSame1(1,aNbSolMAX) ,
188 pnttg1sol(1,aNbSolMAX) ,
189 pntcen3(1,aNbSolMAX) ,
190 par1sol(1,aNbSolMAX) ,
191 pararg1(1,aNbSolMAX) ,
192 parcen3(1,aNbSolMAX)
193 {
194
195 //=========================================================================
196 // Traitement. +
197 //=========================================================================
198
199 gp_Dir2d dirx(1.0,0.0);
200 Standard_Real thefirst = -100000.;
201 Standard_Real thelast = 100000.;
202 Standard_Real firstparam;
203 Standard_Real lastparam;
204 Standard_Real Tol = Abs(Tolerance);
205 Standard_Integer nbrcote1=0;
206 WellDone = Standard_False;
207 NbrSol = 0;
208 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
209 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
210 throw GccEnt_BadQualifier();
211 return;
212 }
213 TColStd_Array1OfReal cote1(1,2);
214 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
215
216 if (Radius < 0.0) {
217 throw Standard_NegativeValue();
218 }
219 else {
220 if (Qualified1.IsEnclosed()) {
221 // ===========================
222 nbrcote1 = 1;
223 cote1(1) = Radius;
224 }
225 else if(Qualified1.IsOutside()) {
226 // ===============================
227 nbrcote1 = 1;
228 cote1(1) = -Radius;
229 }
230 else if(Qualified1.IsUnqualified()) {
231 // ===================================
232 nbrcote1 = 2;
233 cote1(1) = Radius;
234 cote1(2) = -Radius;
235 }
236 IntRes2d_Domain D1(ElCLib::Value(0.,OnCirc), 0.,Tol,
237 ElCLib::Value(2.*M_PI,OnCirc),2.*M_PI,Tol);
238 D1.SetEquivalentParameters(0.,2.*M_PI);
239 Geom2dInt_TheIntConicCurveOfGInter Intp;
240 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
241 Handle(Geom2dAdaptor_Curve) HCu1 = new Geom2dAdaptor_Curve(Cu1);
242 //Adaptor2d_OffsetCurve C2(HCu1,cote1(jcote1));
243 Adaptor2d_OffsetCurve C2(HCu1, -cote1(jcote1));
244 firstparam = Max(C2.FirstParameter(),thefirst);
245 lastparam = Min(C2.LastParameter(),thelast);
246 IntRes2d_Domain D2(C2.Value(firstparam),firstparam,Tol,
247 C2.Value(lastparam),lastparam,Tol);
248 Intp.Perform(OnCirc,D1,C2,D2,Tol,Tol);
249 if (Intp.IsDone()) {
250 if (!Intp.IsEmpty()) {
251 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
252 NbrSol++;
253 gp_Pnt2d Center(Intp.Point(i).Value());
254 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
255 // =======================================================
256 qualifier1(NbrSol) = Qualified1.Qualifier();
257 TheSame1(NbrSol) = 0;
258 pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
259 parcen3(NbrSol) = Intp.Point(i).ParamOnFirst();
260 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
261 pnttg1sol(NbrSol));
262 pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol)));
263 pntcen3(NbrSol) = Center;
264 }
265 }
266 WellDone = Standard_True;
267 }
268 }
269 }
270 }
271
272 //=========================================================================
273 // Cercle tangent : a un cercle Qualified1 (C1). +
274 // centre : sur une droite OnLine. +
275 // de rayon : Radius. +
276 // +
277 // On initialise le tableau de solutions cirsol ainsi que tous les +
278 // champs. +
279 // On elimine en fonction du qualifieur les cas ne presentant pas de +
280 // solutions. +
281 // On resoud l equation du second degre indiquant que le point de centre +
282 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
283 // sur la droite OnLine. +
284 // Les solutions sont representees par les cercles : +
285 // - de centre Pntcen(xc,yc) +
286 // - de rayon Radius. +
287 //=========================================================================
288
289 Geom2dGcc_Circ2dTanOnRadGeo::
Geom2dGcc_Circ2dTanOnRadGeo(const GccEnt_QualifiedCirc & Qualified1,const Geom2dAdaptor_Curve & OnCurv,const Standard_Real Radius,const Standard_Real Tolerance)290 Geom2dGcc_Circ2dTanOnRadGeo (const GccEnt_QualifiedCirc& Qualified1,
291 const Geom2dAdaptor_Curve& OnCurv ,
292 const Standard_Real Radius ,
293 const Standard_Real Tolerance ):
294
295 //=========================================================================
296 // Initialisation des champs. +
297 //=========================================================================
298
299 cirsol(1,aNbSolMAX) ,
300 qualifier1(1,aNbSolMAX) ,
301 TheSame1(1,aNbSolMAX) ,
302 pnttg1sol(1,aNbSolMAX) ,
303 pntcen3(1,aNbSolMAX) ,
304 par1sol(1,aNbSolMAX) ,
305 pararg1(1,aNbSolMAX) ,
306 parcen3(1,aNbSolMAX)
307 {
308
309 //=========================================================================
310 // Traitement. +
311 //=========================================================================
312
313 gp_Dir2d dirx(1.0,0.0);
314 Standard_Real thefirst = -100000.;
315 Standard_Real thelast = 100000.;
316 Standard_Real firstparam;
317 Standard_Real lastparam;
318 Standard_Real Tol = Abs(Tolerance);
319 Standard_Integer nbrcote1=0;
320 WellDone = Standard_False;
321 NbrSol = 0;
322 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
323 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
324 throw GccEnt_BadQualifier();
325 return;
326 }
327 TColStd_Array1OfReal cote1(1,2);
328 gp_Circ2d C1 = Qualified1.Qualified();
329 gp_Pnt2d center1(C1.Location());
330 Standard_Real R1 = C1.Radius();
331
332 if (Radius < 0.0) {
333 throw Standard_NegativeValue();
334 }
335 else {
336 if (Qualified1.IsEnclosed()) {
337 // ===========================
338 nbrcote1 = 1;
339 cote1(1) = Radius;
340 }
341 else if(Qualified1.IsOutside()) {
342 // ===============================
343 nbrcote1 = 1;
344 cote1(1) = -Radius;
345 }
346 else if(Qualified1.IsUnqualified()) {
347 // ===================================
348 nbrcote1 = 2;
349 cote1(1) = Radius;
350 cote1(2) = -Radius;
351 }
352 Geom2dInt_TheIntConicCurveOfGInter Intp;
353 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
354 gp_Circ2d Circ(C1.XAxis(),R1 + cote1(jcote1));
355 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
356 ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol);
357 D1.SetEquivalentParameters(0.,2.*M_PI);
358 firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst);
359 lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast);
360 IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol,
361 Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol);
362 Intp.Perform(Circ,D1,OnCurv,D2,Tol,Tol);
363 if (Intp.IsDone()) {
364 if (!Intp.IsEmpty()) {
365 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
366 NbrSol++;
367 gp_Pnt2d Center(Intp.Point(i).Value());
368 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
369 // =======================================================
370 Standard_Real distcc1 = Center.Distance(center1);
371 if (!Qualified1.IsUnqualified()) {
372 qualifier1(NbrSol) = Qualified1.Qualifier();
373 }
374 else if (Abs(distcc1+Radius-R1) < Tol) {
375 qualifier1(NbrSol) = GccEnt_enclosed;
376 }
377 else if (Abs(distcc1-R1-Radius) < Tol) {
378 qualifier1(NbrSol) = GccEnt_outside;
379 }
380 else { qualifier1(NbrSol) = GccEnt_enclosing; }
381 TheSame1(NbrSol) = 0;
382 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
383 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
384 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
385 pnttg1sol(NbrSol));
386 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),C1);
387 pntcen3(NbrSol) = Center;
388 }
389 }
390 WellDone = Standard_True;
391 }
392 }
393 }
394 }
395
396 //=========================================================================
397 // Cercle tangent : a un cercle Qualified1 (C1). +
398 // centre : sur une droite OnLine. +
399 // de rayon : Radius. +
400 // +
401 // On initialise le tableau de solutions cirsol ainsi que tous les +
402 // champs. +
403 // On elimine en fonction du qualifieur les cas ne presentant pas de +
404 // solutions. +
405 // On resoud l equation du second degre indiquant que le point de centre +
406 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
407 // sur la droite OnLine. +
408 // Les solutions sont representees par les cercles : +
409 // - de centre Pntcen(xc,yc) +
410 // - de rayon Radius. +
411 //=========================================================================
412
413 Geom2dGcc_Circ2dTanOnRadGeo::
Geom2dGcc_Circ2dTanOnRadGeo(const GccEnt_QualifiedLin & Qualified1,const Geom2dAdaptor_Curve & OnCurv,const Standard_Real Radius,const Standard_Real Tolerance)414 Geom2dGcc_Circ2dTanOnRadGeo (const GccEnt_QualifiedLin& Qualified1,
415 const Geom2dAdaptor_Curve& OnCurv ,
416 const Standard_Real Radius ,
417 const Standard_Real Tolerance ):
418
419 //=========================================================================
420 // Initialisation des champs. +
421 //=========================================================================
422
423 cirsol(1,aNbSolMAX) ,
424 qualifier1(1,aNbSolMAX) ,
425 TheSame1(1,aNbSolMAX) ,
426 pnttg1sol(1,aNbSolMAX) ,
427 pntcen3(1,aNbSolMAX) ,
428 par1sol(1,aNbSolMAX) ,
429 pararg1(1,aNbSolMAX) ,
430 parcen3(1,aNbSolMAX)
431 {
432
433 //=========================================================================
434 // Traitement. +
435 //=========================================================================
436
437 gp_Dir2d dirx(1.0,0.0);
438 Standard_Real thefirst = -100000.;
439 Standard_Real thelast = 100000.;
440 Standard_Real firstparam;
441 Standard_Real lastparam;
442 Standard_Real Tol = Abs(Tolerance);
443 WellDone = Standard_False;
444 NbrSol = 0;
445 if (!(Qualified1.IsEnclosed() ||
446 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
447 throw GccEnt_BadQualifier();
448 return;
449 }
450 Standard_Integer nbrcote1=0;
451 TColStd_Array1OfReal cote1(1,2);
452 gp_Lin2d L1 = Qualified1.Qualified();
453 gp_Pnt2d origin1(L1.Location());
454 gp_Dir2d dir1(L1.Direction());
455 gp_Dir2d norm1(-dir1.Y(),dir1.X());
456
457 if (Radius < 0.0) {
458 throw Standard_NegativeValue();
459 }
460 else {
461 if (Qualified1.IsEnclosed()) {
462 // ===========================
463 nbrcote1 = 1;
464 cote1(1) = Radius;
465 }
466 else if(Qualified1.IsOutside()) {
467 // ===============================
468 nbrcote1 = 1;
469 cote1(1) = -Radius;
470 }
471 else if(Qualified1.IsUnqualified()) {
472 // ===================================
473 nbrcote1 = 2;
474 cote1(1) = Radius;
475 cote1(2) = -Radius;
476 }
477 Geom2dInt_TheIntConicCurveOfGInter Intp;
478 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
479 gp_Pnt2d Point(dir1.XY()+cote1(jcote1)*norm1.XY());
480 gp_Lin2d Line(Point,dir1); // ligne avec deport.
481 IntRes2d_Domain D1;
482 firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst);
483 lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast);
484 IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol,
485 Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol);
486 Intp.Perform(Line,D1,OnCurv,D2,Tol,Tol);
487 if (Intp.IsDone()) {
488 if (!Intp.IsEmpty()) {
489 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
490 NbrSol++;
491 gp_Pnt2d Center(Intp.Point(i).Value());
492 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
493 // =======================================================
494 gp_Dir2d dc1(origin1.XY()-Center.XY());
495 if (!Qualified1.IsUnqualified()) {
496 qualifier1(NbrSol) = Qualified1.Qualifier();
497 }
498 else if (dc1.Dot(norm1) > 0.0) {
499 qualifier1(NbrSol) = GccEnt_outside;
500 }
501 else { qualifier1(NbrSol) = GccEnt_enclosed; }
502 TheSame1(NbrSol) = 0;
503 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
504 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
505 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
506 pnttg1sol(NbrSol));
507 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),L1);
508 pntcen3(NbrSol) = Center;
509 }
510 }
511 WellDone = Standard_True;
512 }
513 }
514 }
515 }
516
517 //=========================================================================
518 // Cercle tangent : a un cercle Qualified1 (C1). +
519 // centre : sur une droite OnLine. +
520 // de rayon : Radius. +
521 // +
522 // On initialise le tableau de solutions cirsol ainsi que tous les +
523 // champs. +
524 // On elimine en fonction du qualifieur les cas ne presentant pas de +
525 // solutions. +
526 // On resoud l equation du second degre indiquant que le point de centre +
527 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
528 // sur la droite OnLine. +
529 // Les solutions sont representees par les cercles : +
530 // - de centre Pntcen(xc,yc) +
531 // - de rayon Radius. +
532 //=========================================================================
533
534 Geom2dGcc_Circ2dTanOnRadGeo::
Geom2dGcc_Circ2dTanOnRadGeo(const Geom2dGcc_QCurve & Qualified1,const Geom2dAdaptor_Curve & OnCurv,const Standard_Real Radius,const Standard_Real Tolerance)535 Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1,
536 const Geom2dAdaptor_Curve& OnCurv ,
537 const Standard_Real Radius ,
538 const Standard_Real Tolerance ):
539
540 //=========================================================================
541 // Initialisation des champs. +
542 //=========================================================================
543
544 cirsol(1,aNbSolMAX) ,
545 qualifier1(1,aNbSolMAX) ,
546 TheSame1(1,aNbSolMAX) ,
547 pnttg1sol(1,aNbSolMAX) ,
548 pntcen3(1,aNbSolMAX) ,
549 par1sol(1,aNbSolMAX) ,
550 pararg1(1,aNbSolMAX) ,
551 parcen3(1,aNbSolMAX)
552 {
553
554 //=========================================================================
555 // Traitement. +
556 //=========================================================================
557
558 gp_Dir2d dirx(1.0,0.0);
559 Standard_Real thefirst = -100000.;
560 Standard_Real thelast = 100000.;
561 Standard_Real firstparam;
562 Standard_Real lastparam;
563 Standard_Real Tol = Abs(Tolerance);
564 Standard_Integer nbrcote1=0;
565 WellDone = Standard_False;
566 NbrSol = 0;
567 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
568 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
569 throw GccEnt_BadQualifier();
570 return;
571 }
572 TColStd_Array1OfReal cote1(1,2);
573 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
574
575 if (Radius < 0.0) {
576 throw Standard_NegativeValue();
577 }
578 else {
579 if (Qualified1.IsEnclosed()) {
580 // ===========================
581 nbrcote1 = 1;
582 cote1(1) = Radius;
583 }
584 else if(Qualified1.IsOutside()) {
585 // ===============================
586 nbrcote1 = 1;
587 cote1(1) = -Radius;
588 }
589 else if(Qualified1.IsUnqualified()) {
590 // ===================================
591 nbrcote1 = 2;
592 cote1(1) = Radius;
593 cote1(2) = -Radius;
594 }
595 Geom2dInt_GInter Intp;
596 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
597 Handle(Geom2dAdaptor_Curve) HCu1 = new Geom2dAdaptor_Curve(Cu1);
598 //Adaptor2d_OffsetCurve C1(HCu1,cote1(jcote1));
599 Adaptor2d_OffsetCurve C1(HCu1, -cote1(jcote1));
600 firstparam = Max(C1.FirstParameter(),thefirst);
601 lastparam = Min(C1.LastParameter(),thelast);
602 IntRes2d_Domain D1(C1.Value(firstparam), firstparam, Tol,
603 C1.Value(lastparam), lastparam, Tol);
604 Handle(Geom2dAdaptor_Curve) HOnCurv = new Geom2dAdaptor_Curve(OnCurv);
605 Adaptor2d_OffsetCurve C2(HOnCurv);
606 firstparam = Max(C2.FirstParameter(),thefirst);
607 lastparam = Min(C2.LastParameter(),thelast);
608 IntRes2d_Domain D2(C2.Value(firstparam), firstparam, Tol,
609 C2.Value(lastparam), lastparam, Tol);
610 Intp.Perform(C1,D1,C2,D2,Tol,Tol);
611 if (Intp.IsDone()) {
612 if (!Intp.IsEmpty()) {
613 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
614 NbrSol++;
615 gp_Pnt2d Center(Intp.Point(i).Value());
616 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
617 // =======================================================
618 qualifier1(NbrSol) = Qualified1.Qualifier();
619 TheSame1(NbrSol) = 0;
620 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
621 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
622 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
623 pnttg1sol(NbrSol));
624 pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol)));
625 pntcen3(NbrSol) = Center;
626 }
627 }
628 WellDone = Standard_True;
629 }
630 }
631 }
632 }
633
634 //=========================================================================
635 // Cercle tangent : a un cercle Qualified1 (C1). +
636 // centre : sur une droite OnLine. +
637 // de rayon : Radius. +
638 // +
639 // On initialise le tableau de solutions cirsol ainsi que tous les +
640 // champs. +
641 // On elimine en fonction du qualifieur les cas ne presentant pas de +
642 // solutions. +
643 // On resoud l equation du second degre indiquant que le point de centre +
644 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
645 // sur la droite OnLine. +
646 // Les solutions sont representees par les cercles : +
647 // - de centre Pntcen(xc,yc) +
648 // - de rayon Radius. +
649 //=========================================================================
650
651 Geom2dGcc_Circ2dTanOnRadGeo::
Geom2dGcc_Circ2dTanOnRadGeo(const gp_Pnt2d & Point1,const Geom2dAdaptor_Curve & OnCurv,const Standard_Real Radius,const Standard_Real Tolerance)652 Geom2dGcc_Circ2dTanOnRadGeo (const gp_Pnt2d& Point1 ,
653 const Geom2dAdaptor_Curve& OnCurv ,
654 const Standard_Real Radius ,
655 const Standard_Real Tolerance ):
656
657 //=========================================================================
658 // Initialisation des champs. +
659 //=========================================================================
660
661 cirsol(1,aNbSolMAX) ,
662 qualifier1(1,aNbSolMAX) ,
663 TheSame1(1,aNbSolMAX) ,
664 pnttg1sol(1,aNbSolMAX) ,
665 pntcen3(1,aNbSolMAX) ,
666 par1sol(1,aNbSolMAX) ,
667 pararg1(1,aNbSolMAX) ,
668 parcen3(1,aNbSolMAX)
669 {
670
671 //=========================================================================
672 // Traitement. +
673 //=========================================================================
674
675 gp_Dir2d dirx(1.0,0.0);
676 Standard_Real thefirst = -100000.;
677 Standard_Real thelast = 100000.;
678 Standard_Real firstparam;
679 Standard_Real lastparam;
680 Standard_Real Tol = Abs(Tolerance);
681 WellDone = Standard_False;
682 NbrSol = 0;
683
684 if (Radius < 0.0) {
685 throw Standard_NegativeValue();
686 }
687 else {
688 // gp_Dir2d Dir(-y1dir,x1dir);
689 gp_Circ2d Circ(gp_Ax2d(Point1,gp_Dir2d(1.,0.)),Radius);
690 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
691 ElCLib::Value(2.*M_PI,Circ),2*M_PI,Tol);
692 D1.SetEquivalentParameters(0.,2.*M_PI);
693 firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst);
694 lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast);
695 IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol,
696 Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol);
697 Geom2dInt_TheIntConicCurveOfGInter Intp(Circ,D1,OnCurv,D2,Tol,Tol);
698 if (Intp.IsDone()) {
699 if (!Intp.IsEmpty()) {
700 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
701 NbrSol++;
702 gp_Pnt2d Center(Intp.Point(i).Value());
703 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
704 // =======================================================
705 qualifier1(NbrSol) = GccEnt_noqualifier;
706 TheSame1(NbrSol) = 0;
707 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
708 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
709 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
710 pnttg1sol(NbrSol));
711 pnttg1sol(NbrSol) = Point1;
712 pntcen3(NbrSol) = Center;
713 }
714 WellDone = Standard_True;
715 }
716 }
717 }
718 }
719
720 //=========================================================================
721
722 Standard_Boolean Geom2dGcc_Circ2dTanOnRadGeo::
IsDone() const723 IsDone () const { return WellDone; }
724
725 Standard_Integer Geom2dGcc_Circ2dTanOnRadGeo::
NbSolutions() const726 NbSolutions () const { return NbrSol; }
727
728 gp_Circ2d Geom2dGcc_Circ2dTanOnRadGeo::
ThisSolution(const Standard_Integer Index) const729 ThisSolution (const Standard_Integer Index) const
730 {
731
732 if (Index > NbrSol || Index <= 0)
733 throw Standard_OutOfRange();
734
735 return cirsol(Index);
736 }
737
738 void Geom2dGcc_Circ2dTanOnRadGeo::
WhichQualifier(const Standard_Integer Index,GccEnt_Position & Qualif1) const739 WhichQualifier(const Standard_Integer Index ,
740 GccEnt_Position& Qualif1 ) const
741 {
742 if (!WellDone) { throw StdFail_NotDone(); }
743 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
744 else {
745 Qualif1 = qualifier1(Index);
746 }
747 }
748
749 void Geom2dGcc_Circ2dTanOnRadGeo::
Tangency1(const Standard_Integer Index,Standard_Real & ParSol,Standard_Real & ParArg,gp_Pnt2d & PntSol) const750 Tangency1 (const Standard_Integer Index,
751 Standard_Real& ParSol,
752 Standard_Real& ParArg,
753 gp_Pnt2d& PntSol) const{
754 if (!WellDone) {
755 throw StdFail_NotDone();
756 }
757 else if (Index <= 0 ||Index > NbrSol) {
758 throw Standard_OutOfRange();
759 }
760 else {
761 ParSol = par1sol(Index);
762 ParArg = pararg1(Index);
763 PntSol = gp_Pnt2d(pnttg1sol(Index));
764 }
765 }
766
767 void Geom2dGcc_Circ2dTanOnRadGeo::
CenterOn3(const Standard_Integer Index,Standard_Real & ParArg,gp_Pnt2d & PntSol) const768 CenterOn3 (const Standard_Integer Index,
769 Standard_Real& ParArg,
770 gp_Pnt2d& PntSol) const {
771 if (!WellDone) {
772 throw StdFail_NotDone();
773 }
774 else if (Index <= 0 ||Index > NbrSol) {
775 throw Standard_OutOfRange();
776 }
777 else {
778 ParArg = parcen3(Index);
779 PntSol = pnttg1sol(Index);
780 }
781 }
782
783 Standard_Boolean Geom2dGcc_Circ2dTanOnRadGeo::
IsTheSame1(const Standard_Integer Index) const784 IsTheSame1 (const Standard_Integer Index) const
785 {
786 if (!WellDone) throw StdFail_NotDone();
787 if (Index <= 0 ||Index > NbrSol) throw Standard_OutOfRange();
788
789 if (TheSame1(Index) == 0)
790 return Standard_False;
791
792 return Standard_True;
793 }
794