0022312: Translation of french commentaries in OCCT files
[occt.git] / src / GccAna / GccAna_Circ2d2TanRad.cxx
CommitLineData
7fd59977 1// File GccAna_Circ2d2TanRad.cxx, REG 08/07/91
0d969553
Y
2
3
7fd59977 4
5#include <GccAna_Circ2d2TanRad.ixx>
6
7#include <ElCLib.hxx>
8#include <gp_Ax2d.hxx>
9#include <gp_Circ2d.hxx>
10#include <gp_Lin2d.hxx>
11#include <IntAna2d_AnaIntersection.hxx>
12#include <IntAna2d_IntPoint.hxx>
13#include <Standard_NegativeValue.hxx>
14#include <Standard_OutOfRange.hxx>
15#include <StdFail_NotDone.hxx>
16#include <GccEnt_BadQualifier.hxx>
17#include <Precision.hxx>
18
0d969553 19// circular tangent to two cercles and given radius
7fd59977 20//====================================================
0d969553
Y
21//==================================================================
22// Initialize WellDone to false. +
23// Return circle C1 and circle C2. +
24// Leave with error if the construction is impossible. +
25// Distinguish boundary cases to process them separately. +
26// Create parallel to C1 in the proper direction. +
27// Create parallel to C2 in the proper direction. +
28// Intersect parallels ==> center point of the solution. +
29// Create the solution to be added to already found solutions. +
30// Fill the fields. +
31//==================================================================
7fd59977 32
33GccAna_Circ2d2TanRad::
34 GccAna_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1 ,
35 const GccEnt_QualifiedCirc& Qualified2 ,
36 const Standard_Real Radius ,
37 const Standard_Real Tolerance ):
38 qualifier1(1,8) ,
39 qualifier2(1,8),
40 TheSame1(1,8) ,
41 TheSame2(1,8) ,
42 cirsol(1,8) ,
43 pnttg1sol(1,8) ,
44 pnttg2sol(1,8) ,
45 par1sol(1,8) ,
46 par2sol(1,8) ,
47 pararg1(1,8) ,
48 pararg2(1,8)
49{
50
51 Standard_Real Tol = Abs(Tolerance);
52 gp_Dir2d dirx(1.,0.);
53 WellDone = Standard_False;
54 NbrSol = 0;
55 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
56 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
57 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
58 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
59 GccEnt_BadQualifier::Raise();
60 return;
61 }
62 Standard_Boolean invers = Standard_False;
63 gp_Circ2d C1 = Qualified1.Qualified();
64 gp_Circ2d C2 = Qualified2.Qualified();
65 Standard_Real R1 = C1.Radius();
66 Standard_Real R2 = C2.Radius();
67 Standard_Real rbid = 0.;
68 Standard_Integer signe=0;
69 Standard_Real R3;
70 Standard_Real dist;
71 TColgp_Array1OfCirc2d C(1,8);
72 C(1) = gp_Circ2d(C1);
73 C(2) = gp_Circ2d(C2);
74 Standard_Integer nbsol = 0;
75 gp_Pnt2d center1(C1.Location());
76 gp_Pnt2d center2(C2.Location());
77 gp_Pnt2d center3;
78 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
79 else if ( C(2).Location().IsEqual(C(1).Location(),Precision::Confusion())){
80 WellDone = Standard_True;
81 }
82 else {
83 gp_Dir2d dir1(C(2).Location().XY()-C(1).Location().XY());
84 dist = (center2).Distance(center1);
85 if ((Qualified1.IsEnclosed()) && Qualified2.IsEnclosed()) {
86// =========================================================
87 if (Radius*2.0-Abs(R1+R2-dist) > Tol) { WellDone = Standard_True; }
88 else {
89 if ((dist-R1-R2>Tol)||(Tol<Max(R1,R2)-dist-Min(R1,R2))) {
90 WellDone = Standard_True;
91 }
92 else if (Abs(dist-R1-R2)<=Tol||Abs(Max(R1,R2)-dist-Min(R1,R2))<=Tol) {
93 if (Abs(dist-R1-R2) <= Tol) {
94 rbid = R2+(dist-R1-R2)/2.0;
95 signe = -1;
96 }
97 else if (Abs(Max(R1,R2)-dist-Min(R1,R2)) <= Tol) {
98 if (R1 > R2) { R3 = R2; }
99 else {
100 C2 = gp_Circ2d(C1);
101 R3 = R1;
102 }
103 rbid = -R3+(Min(R1,R2)+dist-Max(R1,R2))/2.;
104 signe = 1;
105 }
106 gp_Ax2d axe(gp_Pnt2d(center2.XY()-rbid*dir1.XY()),dirx);
107 cirsol(1) = gp_Circ2d(axe,Radius);
108// =================================
109 qualifier1(1) = Qualified1.Qualifier();
110 qualifier2(1) = Qualified2.Qualifier();
111 pnttg1sol(1)=gp_Pnt2d(center2.XY()+signe*R2*dir1.XY());
112 pnttg2sol(1)=gp_Pnt2d(center1.XY()+R1*dir1.XY());
113 TheSame1(1) = 0;
114 TheSame2(1) = 0;
115 WellDone = Standard_True;
116 NbrSol = 1;
117 }
118 else {
119 C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
120 C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Abs(Radius-R2));
121 nbsol = 1;
122 }
123 }
124 }
125 else if (((Qualified1.IsEnclosed()) && Qualified2.IsEnclosing()) ||
126// ===================================================================
127 ((Qualified1.IsEnclosing()) && Qualified2.IsEnclosed())) {
128// ========================================================
129 if (Qualified1.IsEnclosing()) {
130 R3 = R1;
131 C(1) = gp_Circ2d(C2);
132 R1 = R2;
133 C(2) = gp_Circ2d(C1);
134 R2 = R3;
135 center3 = center1;
136 center1 = center2;
137 center2 = center3;
138 dir1.Reverse();
0d969553 139 // it is necessary to swap the resulting tangency points
7fd59977 140 invers = Standard_True;
141 }
142 if ((R2-Radius>Tol) || (Tol<Radius-R1) || (Tol>R1-dist-R2) ||
143 ((Tol<Radius*2-R1-dist-R2)||(Tol<R1+R2-dist-Radius*2.0))) {
144 WellDone = Standard_True;
145 }
146 else if ((Abs(R2-Radius)<=Tol) || (Abs(R1-Radius)<=Tol)) {
147 if (Abs(R2-Radius) <= Tol) {
148 C(2) = gp_Circ2d(C2);
149 R3 = R2;
150 TheSame2(1) = 1;
151 TheSame1(1) = 0;
152 pnttg1sol(1) = gp_Pnt2d(C(2).Location().XY()+R3*dir1.XY());
153 }
154 else if (Abs(Radius-R1) <= Tol) {
155 C(2) = gp_Circ2d(C1);
156 R3 = R1;
157 TheSame1(1) = 1;
158 TheSame2(1) = 0;
159 pnttg2sol(1) = gp_Pnt2d(C(2).Location().XY()+R3*dir1.XY());
160 }
161 WellDone = Standard_True;
162 NbrSol = 1;
163 gp_Ax2d axe(C(2).Location(),dirx);
164 cirsol(1) = gp_Circ2d(axe,Radius);
165// =================================
166 qualifier1(1) = Qualified1.Qualifier();
167 qualifier2(1) = Qualified2.Qualifier();
168 }
169 else {
170 if ((Abs(R2+dist-R1) <= Tol) || (Abs(Radius*2.0-R1-dist-R2) < Tol)) {
171 if (Abs(R2+dist-R1) <= Tol) { signe = 1; }
172 else if (Abs(Radius*2.0-R1-dist-R2) < Tol) {signe = -1; }
173 WellDone = Standard_True;
174 NbrSol = 1;
175 gp_Ax2d axe(gp_Pnt2d(center1.XY()+
176 signe*(R1-Radius)*dir1.XY()),dirx);
177 cirsol(1) = gp_Circ2d(axe,Radius);
178// =================================
179 qualifier1(1) = Qualified1.Qualifier();
180 qualifier2(1) = Qualified2.Qualifier();
181 pnttg1sol(1) = gp_Pnt2d(center1.XY()+signe*R1*dir1.XY());
182 pnttg2sol(1)=gp_Pnt2d(center2.XY()+R2*dir1.XY());
183 TheSame1(1) = 0;
184 TheSame2(1) = 0;
185 }
186 else {
187 C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
188 C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Abs(Radius-R2));
189 nbsol = 1;
190 }
191 }
192 }
193 else if (((Qualified1.IsEnclosed()) && (Qualified2.IsOutside())) ||
194// ===================================================================
195 ((Qualified1.IsOutside()) && (Qualified2.IsEnclosed()))) {
196// ========================================================
197 if (Qualified1.IsOutside()) {
198 C(2) = gp_Circ2d(C1);
199 C(1) = gp_Circ2d(C2);
200 R3 = R1;
201 R1 = R2;
202 R2 = R3;
203 center3 = center1;
204 center1 = center2;
205 center2 = center3;
206 dir1.Reverse();
0d969553 207 // it is necessary to swap the resulting tangency points
7fd59977 208 invers = Standard_True;
209 }
210 if ((Radius-R1>Tol)||(dist-R2-R1>Tol)||
211 ((R2-dist-R1+Radius*2>Tol)||(R1-R2-dist-Radius*2>Tol))){
212 WellDone = Standard_True;
213 }
214 else {
215 if (((Radius-R1 > 0.0) && (Abs(dist-R1-R2) <= Tol)) ||
216 (Abs(R1-R2+dist-Radius*2.0) <= Tol) ||
217 (Abs(R1-R2-dist-Radius*2.0) <= Tol) || (Abs(dist-R1-R2) <= Tol)) {
218 if (Abs(R1-R2+dist-Radius*2.0) <= Tol) {
219 signe = -1;
220 }
221 else {
222 signe = 1;
223 if ((Radius-R1 > 0.0) && (Abs(dist-R1-R2) <= Tol)) {
224 R2 = R1;
225 }
226 else if (Abs(dist-R1-R2) <= Tol) {
227 R2 = R1;
228 if (Abs(R1-Radius) <= Tol) {
229 TheSame1(1) = 1;
230 }
231 }
232 }
233 WellDone = Standard_True;
234 NbrSol = 1;
235 gp_Ax2d axe(gp_Pnt2d(center1.XY()+
236 signe*(R1-Radius)*dir1.XY()),dirx);
237 cirsol(1) = gp_Circ2d(axe,Radius);
238// =================================
239 qualifier1(1) = Qualified1.Qualifier();
240 qualifier2(1) = Qualified2.Qualifier();
241 pnttg1sol(1) = gp_Pnt2d(center1.XY()+signe*R1*dir1.XY());
242 pnttg2sol(1) = gp_Pnt2d(center2.XY()+signe*R2*dir1.XY());
243 TheSame1(1) = 0;
244 TheSame2(1) = 0;
245 }
246 else {
247 C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
248 C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
249 nbsol = 1;
250 }
251 }
252 }
253 else if (((Qualified1.IsEnclosed()) && (Qualified2.IsUnqualified())) ||
254// =======================================================================
255 ((Qualified1.IsUnqualified()) && (Qualified2.IsEnclosed()))) {
256// ============================================================
257 if (Qualified1.IsUnqualified()) {
258 C(1) = gp_Circ2d(C2);
259 C(2) = gp_Circ2d(C1);
260 R3 = R1;
261 R1 = R2;
262 R2 = R3;
263 center3 = center1;
264 center1 = center2;
265 center2 = center3;
266 dir1.Reverse();
0d969553 267 // it is necessary to swap the resulting tangency points
7fd59977 268 invers = Standard_True;
269 }
270 if ((Radius-R1 > Tol) || (dist-R2-R1 > Tol)) { WellDone = Standard_True; }
271 else {
272 if ((Abs(dist-R2-R1) <= Tol) || (Abs(Radius-R1) <= Tol)) {
273 WellDone = Standard_True;
274 NbrSol = 1;
275 gp_Ax2d ax(gp_Pnt2d(center1.XY()+(R1-Radius)*dir1.XY()),dirx);
276 cirsol(1) = gp_Circ2d(ax,Radius);
277// ================================
278 qualifier1(1) = Qualified1.Qualifier();
279 qualifier2(1) = Qualified2.Qualifier();
280 pnttg2sol(1) = gp_Pnt2d(center1.XY()+(dist-R2)*dir1.XY());
281 TheSame2(1) = 0;
282 if (Abs(Radius-R1) > 0.0) {
283 TheSame1(1) = 1;
284 }
285 else {
286 TheSame1(1) = 0;
287 pnttg1sol(1) = gp_Pnt2d(center1.XY()+R1*dir1.XY());
288 }
289 }
290 else {
291 C(3) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
292 C(4) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
293 C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
294 C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Abs(Radius-R2));
295 nbsol = 2;
296 }
297 }
298 }
299 else if ((Qualified1.IsEnclosing()) && (Qualified2.IsEnclosing())) {
300// ==================================================================
301 if ((Tol < Max(R1,R2)-Radius) || (Tol < Max(R1,R2)-dist-Min(R1,R2)) ||
302 (dist+R1+R2-Radius*2.0 > Tol)) { WellDone = Standard_True; }
303 else {
304 if ((Abs(dist+Min(R1,R2)-Max(R1,R2)) <= Tol) ||
305 (Abs(R1+R2+dist-2.0*Radius) <= Tol)) {
306 if (Abs(dist+Min(R1,R2)-Max(R1,R2)) <= Tol) {
307 signe = 1;
308 }
309 else {
310 signe = -1;
311 }
312 WellDone = Standard_True;
313 NbrSol = 1;
314 gp_Ax2d axe(gp_Pnt2d(center1.XY()+
315 signe*(R1-Radius)*dir1.XY()),dirx);
316 cirsol(1) = gp_Circ2d(axe,Radius);
317// =================================
318 qualifier1(1) = Qualified1.Qualifier();
319 qualifier2(1) = Qualified2.Qualifier();
320 pnttg1sol(1) = gp_Pnt2d(center1.XY()+R1*dir1.XY());
321 pnttg2sol(1) = gp_Pnt2d(center2.XY()+signe*R2*dir1.XY());
322 TheSame1(1) = 0;
323 TheSame2(1) = 0;
324 }
325 else if (Abs(Radius-Max(R1,R2)) <= Tol) {
326 WellDone = Standard_True;
327 NbrSol = 1;
328 if (R1 > R2) {
329 C(1) = gp_Circ2d(C1);
330 C(2) = gp_Circ2d(C2);
331 TheSame1(1) = 1;
332 TheSame2(1) = 0;
333 pnttg2sol(1) = gp_Pnt2d(center1.XY()+(dist+R2)*dir1.XY());
334 }
335 else {
336 C(1) = gp_Circ2d(C2);
337 C(2) = gp_Circ2d(C1);
338 TheSame1(1) = 0;
339 TheSame2(1) = 1;
340 pnttg1sol(1) = gp_Pnt2d(center1.XY()-R1*dir1.XY());
341 }
342 gp_Ax2d axe(C(1).Location(),dirx);
343 cirsol(1) = gp_Circ2d(axe,Radius);
344// =================================
345 qualifier1(1) = Qualified1.Qualifier();
346 qualifier2(1) = Qualified2.Qualifier();
347 }
348 else {
349 C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
350 C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Abs(Radius-R2));
351 nbsol = 1;
352 }
353 }
354 }
355 else if (((Qualified1.IsEnclosing()) && (Qualified2.IsOutside())) ||
356// ====================================================================
357 ((Qualified1.IsOutside()) && (Qualified2.IsEnclosing()))) {
358// =========================================================
359 if (Qualified1.IsOutside()) {
360 C(1) = gp_Circ2d(C2);
361 C(2) = gp_Circ2d(C1);
362 R3 = R1;
363 R1 = R2;
364 R2 = R3;
365 center3 = center1;
366 center1 = center2;
367 center2 = center3;
368 dir1.Reverse();
0d969553 369 // it is necessary to swap the resulting tangency points
7fd59977 370 invers = Standard_True;
371 }
372 if ((R1-Radius > Tol) || (Tol < R1+R2-dist) ||
373 (dist-R2+R1-Radius*2.0>Tol)) {
374 WellDone = Standard_True;
375 }
376 else if (((Abs(R1-Radius)<=Tol) || (Abs(R1+R2-dist)<=Tol))||
377 (Abs(dist-R2+R1-Radius*2.0) <= Tol)) {
378 WellDone = Standard_True;
379 NbrSol = 1;
380 if((Abs(R1-Radius) <= Tol) || (Abs(R1+R2-dist) <= Tol)){
381 TheSame1(1) = 1;
382 }
383 else {
384 TheSame1(1) = 0;
385 }
386 TheSame2(1) = 0;
387 gp_Ax2d axe(gp_Pnt2d(center1.XY()+(R1-Radius)*dir1.XY()),dirx);
388 cirsol(1) = gp_Circ2d(axe,Radius);
389// =================================
390 qualifier1(1) = Qualified1.Qualifier();
391 qualifier2(1) = Qualified2.Qualifier();
392 pnttg1sol(1) = gp_Pnt2d(center1.XY()-R1*dir1.XY());
393 pnttg2sol(1) = gp_Pnt2d(center1.XY()+(dist-R2)*dir1.XY());
394 }
395 else {
396 C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
397 C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
398 nbsol = 1;
399 }
400 }
401 else if (((Qualified1.IsEnclosing()) && (Qualified2.IsUnqualified())) ||
402// ========================================================================
403 ((Qualified1.IsUnqualified()) && (Qualified2.IsEnclosing()))) {
404// =============================================================
405 if (Qualified1.IsUnqualified()) {
406 C(1) = gp_Circ2d(C2);
407 C(2) = gp_Circ2d(C1);
408 R3 = R1;
409 R1 = R2;
410 R2 = R3;
411 center3 = center1;
412 center1 = center2;
413 center2 = center3;
414 invers = Standard_True;
415 dir1.Reverse();
416 }
417 if ((Tol < R1-dist-R2) || (R1-Radius > Tol)) { WellDone = Standard_True; }
418 else if ((Abs(R1-Radius) <= Tol) || (Abs(R1-dist-R2) > 0.0)) {
419 if (Abs(R1-Radius) <= Tol) {
420 TheSame1(1) = 1;
421 if((Abs(Radius-R2) <= Tol) &&
422 (center1.Distance(center2) <= Tol)) {
423 TheSame2(1) = 1;
424 }
425 }
426 else if (Abs(R1-dist-R2) > 0.0) {
427 TheSame1(1) = 0;
428 TheSame2(1) = 0;
429 }
430 WellDone = Standard_True;
431 NbrSol = 1;
432 gp_Ax2d axe(gp_Pnt2d(center1.XY()+(Radius-R1)*dir1.XY()),dirx);
433 cirsol(1) = gp_Circ2d(axe,Radius);
434// =================================
435 qualifier1(1) = Qualified1.Qualifier();
436 qualifier2(1) = Qualified2.Qualifier();
437 pnttg1sol(1) = gp_Pnt2d(center1.XY()+R1*dir1.XY());
438 pnttg2sol(1) = gp_Pnt2d(center1.XY()+(dist+R2)*dir1.XY());
439 }
440 else {
441 C(3) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
442 C(4) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
443 C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
444 C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Abs(Radius-R2));
445 nbsol = 2;
446 }
447 }
448 else if ((Qualified1.IsOutside()) && (Qualified2.IsOutside())) {
449// ==============================================================
450 if (Tol < Max(R1,R2)-dist-Min(R1,R2)) { WellDone = Standard_True; }
451 else if (dist-R1-R2-Radius*2.0 > Tol) { WellDone = Standard_True; }
452 else {
453 if (Abs(dist+Min(R1,R2)-Max(R1,R2)) <= Tol) {
454 WellDone = Standard_True;
455 NbrSol = 1;
456 if (R1 < R2) { signe = -1; }
457 else { signe = -1; }
458 gp_Ax2d axe(gp_Pnt2d(center1.XY()-(Radius+R1)*dir1.XY()),
459 dirx);
460 cirsol(1) = gp_Circ2d(axe,Radius);
461// =================================
462 qualifier1(1) = Qualified1.Qualifier();
463 qualifier2(1) = Qualified2.Qualifier();
464 pnttg1sol(1) = gp_Pnt2d(center1.XY()+signe*R1*dir1.XY());
465 pnttg2sol(1) = gp_Pnt2d(pnttg1sol(1));
466 TheSame1(1) = 0;
467 TheSame2(1) = 0;
468 }
469 else if (Abs(dist-R1-R2-Radius*2.0) <= Tol) {
470 WellDone = Standard_True;
471 NbrSol = 1;
472 gp_Ax2d ax(gp_Pnt2d(center1.XY()+(R1+Radius)*dir1.XY()),dirx);
473 cirsol(1) = gp_Circ2d(ax,Radius);
474// ================================
475 qualifier1(1) = Qualified1.Qualifier();
476 qualifier2(1) = Qualified2.Qualifier();
477 pnttg1sol(1) = gp_Pnt2d(center1.XY()+R1*dir1.XY());
478 pnttg2sol(1) = gp_Pnt2d(center2.XY()-R2*dir1.XY());
479 TheSame1(1) = 0;
480 TheSame2(1) = 0;
481 }
482 else {
483 C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Radius+R1);
484 C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
485 nbsol = 1;
486 }
487 }
488 }
489 else if (((Qualified1.IsOutside()) && (Qualified2.IsUnqualified())) ||
490// ======================================================================
491 ((Qualified1.IsUnqualified()) && (Qualified2.IsOutside()))) {
492// ===========================================================
493 if (Qualified1.IsUnqualified()) {
494 C(1) = gp_Circ2d(C2);
495 R3 = R1;
496 R1 = R2;
497 C(2) = gp_Circ2d(C1);
498 R2 = R3;
499 center3 = center1;
500 center1 = center2;
501 center2 = center3;
502 dir1.Reverse();
0d969553 503 // it is necessary to swap the resulting tangency points
7fd59977 504 invers = Standard_True;
505 }
506 if (Tol < R1-dist-R2) { WellDone = Standard_True; }
507 else if ((Tol < R2-dist-R1) && (Tol < Radius*2.0-R2-dist+R1)) {
508 WellDone = Standard_True;
509 }
510 else if ((dist-R1-R2 > Tol) && (Tol < dist-R1-R2-Radius*2.0)) {
511 WellDone = Standard_True;
512 }
513 else {
514 if ((Abs(R1-R2-dist)<=Tol) ||
515 ((Abs(dist-R1-R2)<=Tol) && (Abs(Radius*2.0-dist+R1+R2) <= Tol)) ||
516 ((Abs(dist+R1-R2)<=Tol) && (Abs(R2+dist-R1-Radius*2.0)<=Tol))) {
517 WellDone = Standard_True;
518 NbrSol = 1;
519 gp_Ax2d axe(gp_Pnt2d(center1.XY()+(Radius+R1)*dir1.XY()),
520 dirx);
521 cirsol(1) = gp_Circ2d(axe,Radius);
522// =================================
523 qualifier1(1) = Qualified1.Qualifier();
524 qualifier2(1) = Qualified2.Qualifier();
525 pnttg1sol(1) = gp_Pnt2d(center1.XY()+R1*dir1.XY());
526 pnttg2sol(1) = gp_Pnt2d(center1.XY()+(dist+R2)*dir1.XY());
527 TheSame1(1) = 0;
528 TheSame2(1) = 0;
529 }
530 else {
531 C(3) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Radius+R1);
532 C(4) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
533 C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Radius+R1);
534 C(2) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R2));
535 nbsol = 2;
536 }
537 }
538 }
539 else if ((Qualified1.IsUnqualified()) && (Qualified2.IsUnqualified())) {
540// ======================================================================
541 if ((dist-R1-R2>Tol)&&(Tol<(dist-R1-R2-Radius*2))) {
542 WellDone = Standard_True;
543 }
544 else if ((Max(R1,R2)-dist-Min(R1,R2)>Tol) &&
545 (((Max(R1,R2)-dist-Min(R1,R2))-Radius*2.0 > Tol))) {
546 WellDone = Standard_True;
547 }
548 else {
549 Standard_Real p3 = Max(R1,R2)-Min(R1,R2)-dist-Radius*2.0;
550 Standard_Real p4 = dist-R1-R2;
551 Standard_Real p5 = Radius*2.0-dist+R1+R2;
552 if (p3 > 0.0) {
553 dist = Max(R1,R2)-Min(R1,R2)-Radius*2.0;
554 }
555 else if (p4 > 0.0 && p5 < 0.0) {
556 R1 = dist-R2-Radius*2.0;
557 }
558 C(1) = gp_Circ2d(gp_Ax2d(center1,dirx),Abs(Radius-R1));
559 C(2) = gp_Circ2d(gp_Ax2d(center2,dirx),Abs(Radius-R2));
560 C(3) = gp_Circ2d(gp_Ax2d(center1,dirx),Abs(Radius-R1));
561 C(4) = gp_Circ2d(gp_Ax2d(center2,dirx),Radius+R2);
562 C(5) = gp_Circ2d(gp_Ax2d(center1,dirx),Radius+R1);
563 C(6) = gp_Circ2d(gp_Ax2d(center2,dirx),Abs(Radius-R2));
564 C(7) = gp_Circ2d(gp_Ax2d(center1,dirx),Radius+R1);
565 C(8) = gp_Circ2d(gp_Ax2d(center2,dirx),Radius+R2);
566 nbsol = 4;
567 }
568 }
569 if (nbsol > 0) {
570 for (Standard_Integer j = 1 ; j <= nbsol ; j++) {
571 IntAna2d_AnaIntersection Intp(C(2*j-1),C(2*j));
572 if (Intp.IsDone()) {
573 if (!Intp.IsEmpty()) {
574 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
575 NbrSol++;
576 gp_Pnt2d Center(Intp.Point(i).Value());
577 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
578// =======================================================
579 dir1 = gp_Dir2d(Center.XY()-center1.XY());
580 gp_Dir2d dir2(Center.XY()-center2.XY());
581 Standard_Real distcc1 = Center.Distance(center1);
582 Standard_Real distcc2 = Center.Distance(center2);
583 if (!Qualified1.IsUnqualified()) {
584 qualifier1(NbrSol) = Qualified1.Qualifier();
585 }
586 else if (Abs(distcc1+Radius-R1) < Tol) {
587 qualifier1(NbrSol) = GccEnt_enclosed;
588 }
589 else if (Abs(distcc1-R1-Radius) < Tol) {
590 qualifier1(NbrSol) = GccEnt_outside;
591 }
592 else { qualifier1(NbrSol) = GccEnt_enclosing; }
593 if (!Qualified2.IsUnqualified()) {
594 qualifier2(NbrSol) = Qualified2.Qualifier();
595 }
596 else if (Abs(distcc2+Radius-R2) < Tol) {
597 qualifier2(NbrSol) = GccEnt_enclosed;
598 }
599 else if (Abs(distcc2-R2-Radius) < Tol) {
600 qualifier2(NbrSol) = GccEnt_outside;
601 }
602 else { qualifier2(NbrSol) = GccEnt_enclosing; }
603 if ((Center.Distance(center1) > R1) &&
604 (Radius < Center.Distance(center1)+R1)) {
605 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1.XY());
606 }
607 else if ((Center.Distance(center1) < R1) &&
608 (Radius < R1)) {
609 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dir1.XY());
610 }
611 else {
612 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1.XY());
613 }
614 if ((Center.Distance(center2) > R2) &&
615 (Radius < Center.Distance(center2)+R2)) {
616 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir2.XY());
617 }
618 else if ((Center.Distance(center2) < R2) &&
619 (Radius < R2)) {
620 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dir2.XY());
621 }
622 else {
623 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir2.XY());
624 }
625 TheSame1(NbrSol) = 0;
626 TheSame2(NbrSol) = 0;
627 }
628 }
629 WellDone = Standard_True;
630 }
631 }
632 }
633 }
0d969553 634 // swapping of resulting tangency points if necessary
7fd59977 635 if (invers) {
636 gp_Pnt2d Psav;
637 for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
638 Psav = pnttg1sol(i);
639 pnttg1sol(i) = pnttg2sol(i);
640 pnttg2sol(i) = Psav;
641 }
642 }
0d969553 643 // calculation of parameters of tangency points
7fd59977 644 for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
645 par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
646 if (TheSame1(i) == 0) {
647 pararg1(i)=ElCLib::Parameter(C1,pnttg1sol(i));
648 }
649 par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
650 if (TheSame2(i) == 0) {
651 pararg2(i)=ElCLib::Parameter(C2,pnttg2sol(i));
652 }
653 }
654 }
655
656Standard_Boolean GccAna_Circ2d2TanRad::
657 IsDone () const { return WellDone; }
658
659Standard_Integer GccAna_Circ2d2TanRad::
660 NbSolutions () const { return NbrSol; }
661
662gp_Circ2d GccAna_Circ2d2TanRad::
663 ThisSolution (const Standard_Integer Index) const
664{
665 if (!WellDone) { StdFail_NotDone::Raise(); }
666 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
667 return cirsol(Index);
668}
669
670void GccAna_Circ2d2TanRad::
671 WhichQualifier(const Standard_Integer Index ,
672 GccEnt_Position& Qualif1 ,
673 GccEnt_Position& Qualif2 ) const
674{
675 if (!WellDone) { StdFail_NotDone::Raise(); }
676 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
677
678 Qualif1 = qualifier1(Index);
679 Qualif2 = qualifier2(Index);
680}
681
682void GccAna_Circ2d2TanRad::
683 Tangency1 (const Standard_Integer Index,
684 Standard_Real& ParSol,
685 Standard_Real& ParArg,
686 gp_Pnt2d& PntSol) const{
687 if (!WellDone) { StdFail_NotDone::Raise(); }
688 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
689 else {
690 if (TheSame1(Index) == 0) {
691 ParSol = par1sol(Index);
692 ParArg = pararg1(Index);
693 PntSol = gp_Pnt2d(pnttg1sol(Index));
694 }
695 else { StdFail_NotDone::Raise(); }
696 }
697 }
698
699void GccAna_Circ2d2TanRad::
700 Tangency2 (const Standard_Integer Index,
701 Standard_Real& ParSol,
702 Standard_Real& ParArg,
703 gp_Pnt2d& PntSol) const{
704 if (!WellDone) { StdFail_NotDone::Raise(); }
705 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
706 else {
707 if (TheSame2(Index) == 0) {
708 ParSol = par2sol(Index);
709 ParArg = pararg2(Index);
710 PntSol = gp_Pnt2d(pnttg2sol(Index));
711 }
712 else { StdFail_NotDone::Raise(); }
713 }
714 }
715
716Standard_Boolean GccAna_Circ2d2TanRad::
717 IsTheSame1 (const Standard_Integer Index) const
718{
719 if (!WellDone) { StdFail_NotDone::Raise(); }
720 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
721
722 if (TheSame1(Index) == 0) { return Standard_False; }
723
724 return Standard_True;
725}
726
727Standard_Boolean GccAna_Circ2d2TanRad::
728 IsTheSame2 (const Standard_Integer Index) const
729{
730 if (!WellDone) { StdFail_NotDone::Raise(); }
731 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
732
733 if (TheSame2(Index) == 0) { return Standard_False; }
734 return Standard_True;
735}