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