0025418: Debug output to be limited to OCC development environment
[occt.git] / src / GccAna / GccAna_Circ2d2TanRad_1.cxx
CommitLineData
b311480e 1// Created on: 1991-09-24
2// Created by: Remi GILET
3// Copyright (c) 1991-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <GccAna_Circ2d2TanRad.jxx>
18
19#include <ElCLib.hxx>
20#include <gp_Ax2d.hxx>
21#include <gp_Circ2d.hxx>
22#include <gp_Lin2d.hxx>
23#include <IntAna2d_AnaIntersection.hxx>
24#include <IntAna2d_IntPoint.hxx>
25#include <TColStd_Array1OfReal.hxx>
26#include <Standard_NegativeValue.hxx>
27#include <GccEnt_BadQualifier.hxx>
28
0d969553 29// circular tangent to a circle, a line and a given radius
7fd59977 30//==============================================================
31//========================================================================
0d969553
Y
32// Initialize WellDone to false. +
33// Return circle C1 and straight line L2. +
34// Leave with error if the construction is impossible. +
35// Create parallel to C1 in the proper direction. +
36// Create parallel to L2 in the proper direction. +
37// Intersect parallels ==> center point of the solution. +
38// Create the solution and add it to already found ones. +
39// Fill the fields. +
7fd59977 40//========================================================================
41
42GccAna_Circ2d2TanRad::
43 GccAna_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1 ,
44 const GccEnt_QualifiedLin& Qualified2 ,
45 const Standard_Real Radius ,
46 const Standard_Real Tolerance ):
47 qualifier1(1,8) ,
48 qualifier2(1,8),
49 TheSame1(1,8) ,
50 TheSame2(1,8) ,
51 cirsol(1,8) ,
52 pnttg1sol(1,8) ,
53 pnttg2sol(1,8) ,
54 par1sol(1,8) ,
55 par2sol(1,8) ,
56 pararg1(1,8) ,
57 pararg2(1,8)
58{
59
60 Standard_Real Tol = Abs(Tolerance);
61 gp_Dir2d dirx(1.,0.);
62 NbrSol = 0;
63 WellDone = Standard_False;
64 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
65 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
66 !(Qualified2.IsEnclosed() || Qualified2.IsOutside() ||
67 Qualified2.IsUnqualified())) {
68 GccEnt_BadQualifier::Raise();
69 return;
70 }
71 Standard_Integer i ;
72 for ( i = 1 ; i <= 8 ; i++) { TheSame2(i) = 0; }
73 Standard_Integer ncote1=0;
74 Standard_Integer ncote2=0;
75 Standard_Integer nbsol = 0;
76 Standard_Real cote = 0.0;
77 Standard_Real ccote = 0.0;
78 TColStd_Array1OfReal cote1(1,3);
79 TColStd_Array1OfReal cote2(1,2);
80 gp_Circ2d C1 = Qualified1.Qualified();
81 gp_Lin2d L2 = Qualified2.Qualified();
82 Standard_Real xdir = (L2.Direction()).X();
83 Standard_Real ydir = (L2.Direction()).Y();
84 gp_Dir2d normL2(-ydir,xdir);
85 Standard_Real lxloc = (L2.Location()).X();
86 Standard_Real lyloc = (L2.Location()).Y();
87 Standard_Real cxloc = (C1.Location()).X();
88 Standard_Real cyloc = (C1.Location()).Y();
89 Standard_Real R1 = C1.Radius();
90 gp_Pnt2d center1(cxloc,cyloc);
91 gp_Pnt2d origin2(lxloc,lyloc);
92 Standard_Real dist = Radius*2.0 + R1;
93 Standard_Real distance = L2.Distance(center1);
94
95 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
96 else {
97 if ( distance-dist >Tol) { WellDone = Standard_True; }
98 else if (Qualified1.IsEnclosed()) {
99// =================================
100 if (Qualified2.IsEnclosed()) {
101// ============================
102 if (distance-R1 > Tol) { WellDone = Standard_True; }
103 else if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
104 (Radius*2.0-R1+distance > Tol)) ||
105 ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
106 (Radius*2.0-R1-distance > Tol))||
107 (Radius-R1 > Tol)) { WellDone = Standard_True; }
108 else {
109 if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
110 (Radius*2.0>R1-distance)) || (Abs(distance-R1)<Tol) ||
111 ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
112 (Radius*2.0 > (R1+distance+Tol)))) {
113 cote = 1.0;
114 nbsol = 3;
115 ccote = 1.0;
116 }
117 else {
118 ncote1 = 1;
119 ncote2 = 1;
120 cote1(1) = R1-Radius;
121 cote2(1) = 1.0;
122 nbsol = 1;
123 }
124 }
125 }
126 else if (Qualified2.IsOutside()) {
127// ================================
128 if (distance > R1+Tol) { WellDone = Standard_True; }
129 else if ((((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)) > 0.0) &&
130 (Radius*2.0-R1+distance > Tol)) ||
131 (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)) < 0.0) &&
132 (Radius*2.0-R1-distance > Tol)) ||
133 (Radius-R1 >Tol)) { WellDone = Standard_True; }
134 else {
135 if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) > 0.0) &&
136 (Radius*2.0 > R1-distance)) || (Abs(R1-Radius) < Tol) ||
137 ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) < 0.0) &&
138 (Radius*2.0>(R1+distance))) || (Abs(distance-R1)<Tol)) {
139 cote = -1.0;
140 nbsol = 3;
141 ccote = 1.0;
142 }
143 else {
144 ncote1 = 1;
145 ncote2 = 1;
146 cote1(1) = R1-Radius;
147 cote2(1) = -1.0;
148 nbsol = 1;
149 }
150 }
151 }
152 else if (Qualified2.IsUnqualified()) {
153// ====================================
154 if ((distance-R1>Tol) || (Radius*2.0-R1-distance>Tol) ||
155 (Radius-R1 > Tol)) { WellDone = Standard_True; }
156 else if (distance > R1) {
157 if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) > 0.0)) {
158 cote = 1.0;
159 }
160 else {
161 cote = -1.0;
162 nbsol = 3;
163 }
164 nbsol = 3;
165 ccote = 1;
166 }
167 else {
168 ncote1 = 1;
169 ncote2 = 2;
170 cote1(1) = R1-Radius;
171 cote2(1) = 1.0;
172 cote2(2) = -1.0;
173 nbsol = 1;
174 }
175 }
176 if (nbsol == 3) {
177 }
178 }
179 else if (Qualified1.IsEnclosing()) {
180// ==================================
181 if (Qualified2.IsEnclosed()) {
182// =================================
183 if ((distance<R1-Tol)||(Radius<R1-Tol)||(Radius*2<distance+R1-Tol) ||
184 (Tol<R1-Radius)||(-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0)){
185 WellDone = Standard_True;
186 }
187 else if ((distance<R1) || (Radius<R1) || (Radius*2.0<distance+R1)) {
188 cote = 1.0;
189 ccote =1.0;
190 nbsol = 3;
191 }
192 else {
193 ncote1 = 1;
194 ncote2 = 1;
195 cote1(1) = Radius-R1;
196 cote2(1) = 1.0;
197 nbsol = 1;
198 }
199 }
200 else if (Qualified2.IsOutside()) {
201// ================================
202 if ((Tol<R1-distance) || (Tol<distance+R1-Radius*2.0) ||
203 (Tol<R1-Radius)||(-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0)){
204 WellDone = Standard_True;
205 }
206 else if ((distance<R1) || (Radius*2.0<distance+R1) || (Radius<R1)) {
207 cote = -1.0;
208 ccote = -1.0;
209 nbsol = 3;
210 }
211 else {
212 ncote1 = 1;
213 ncote2 = 1;
214 cote1(1) = Radius-R1;
215 cote2(1) = -1.0;
216 nbsol = 1;
217 }
218 }
219 else if (Qualified2.IsUnqualified()) {
220// ====================================
221 if ((distance<R1-Tol) || (Radius*2.0<distance+R1-Tol) ||
222 (Radius < R1-Tol)) { WellDone = Standard_True; }
223 else if ((distance < R1) || (Radius*2.0 < distance+R1)) {
224 if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) > 0.0)) {
225 cote = 1.0;
226 ccote = 1.0;
227 nbsol = 3;
228 }
229 else {
230 ccote = -1.0;
231 cote = -1.0;
232 nbsol = 3;
233 }
234 }
235 else {
236 ncote1 = 1;
237 ncote2 = 2;
238 cote1(1) = Radius-R1;
239 cote2(1) = 1.0;
240 cote2(2) = -1.0;
241 nbsol = 1;
242 }
243 }
244 }
245 else if ((Qualified1.IsOutside()) && (Qualified2.IsEnclosed())) {
246// ===============================================================
247 if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
248 (distance>R1+Tol)) || (distance > R1+Radius*2.0+Tol)) {
249 WellDone = Standard_True;
250 }
251 else {
252 if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
253 (distance>R1)) {
254 cote = 1.0;
255 nbsol = 2;
256 }
257 else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
258 (distance>R1+2.0*Radius)) {
259 cote = -1.0;
260 nbsol = 2;
261 }
262 else {
263 ncote1 = 1;
264 ncote2 = 1;
265 cote1(1) = Radius+R1;
266 cote2(1) = 1.0;
267 nbsol = 1;
268 }
269 }
270 }
271 else if ((Qualified1.IsOutside()) && (Qualified2.IsOutside())) {
272// ==============================================================
273 if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
274 (distance>R1+Tol)) || (distance > R1+Radius*2.0+Tol)) {
275 WellDone = Standard_True;
276 }
277 else {
278 if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) && (distance>R1)) {
279 cote = -1.0;
280 nbsol = 2;
281 }
282 else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
283 (distance>R1+2.0*Radius)) {
284 cote = 1.0;
285 nbsol = 2;
286 }
287 else {
288 ncote1 = 1;
289 ncote2 = 1;
290 cote1(1) = Radius+R1;
291 cote2(1) = -1.0;
292 nbsol = 1;
293 }
294 }
295 }
296 else if ((Qualified1.IsOutside()) && (Qualified2.IsUnqualified())) {
297// ==================================================================
298 if (distance > Radius*2.0+R1+Tol) { WellDone = Standard_True; }
299 else if (distance > Radius*2.0+R1) {
300 if (-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) { cote = 1.0; }
301 else { cote = -1.0; }
302 nbsol = 4;
303 }
304 else {
305 ncote1 = 1;
306 ncote2 = 2;
307 cote1(1) = Radius+R1;
308 cote2(1) = 1.0;
309 cote2(2) = -1.0;
310 nbsol = 1;
311 }
312 }
313 else if ((Qualified1.IsUnqualified()) && (Qualified2.IsEnclosed())) {
314// ===================================================================
315 if ((distance>R1+Radius*2.0+Tol) ||
316 ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
317 (distance > R1+Tol))){ WellDone = Standard_True; }
318 else {
319 if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) && (distance > R1)){
320 cote = 1.0;
321 nbsol = 2;
322 }
323 else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
324 (distance>R1+2.0*Radius)) {
325 cote = -1.0;
326 nbsol = 2;
327 }
328 else {
329 ncote1 = 2;
330 ncote2 = 1;
331 cote1(1) = Abs(Radius-R1);
332 cote1(2) = Radius+R1;
333 cote2(1) = 1.0;
334 nbsol = 1;
335 }
336 }
337 }
338 else if ((Qualified1.IsUnqualified()) && (Qualified2.IsOutside())) {
339// ==================================================================
340 if ((distance>R1+Radius*2.0+Tol) ||
341 ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
342 (distance > R1+Tol))){ WellDone = Standard_True; }
343 else {
344 if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) && (distance > R1)){
345 cote = -1.0;
346 nbsol = 2;
347 }
348 else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
349 (distance>R1+2.0*Radius)) {
350 cote = 1.0;
351 nbsol = 2;
352 }
353 else {
354 ncote1 = 2;
355 ncote2 = 1;
356 cote1(1) = Abs(Radius-R1);
357 cote1(2) = Radius+R1;
358 cote2(1) = -1.0;
359 nbsol = 1;
360 }
361 }
362 }
363 else if ((Qualified1.IsUnqualified()) && (Qualified2.IsUnqualified())) {
364// ======================================================================
365 if (distance>R1+Radius*2.0+Tol) { WellDone = Standard_True; }
366 else if (distance>R1+Radius*2.0) {
367 if (-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) { cote = -1.0; }
368 else { cote = 1.0; }
369 nbsol = 4;
370 }
371 else {
372 ncote1 = 2;
373 ncote2 = 2;
374 cote1(1) = Abs(Radius-R1);
375 cote1(2) = Radius+R1;
376 cote2(1) = 1.0;
377 cote2(2) = -1.0;
378 nbsol = 1;
379 }
380 }
381 if (nbsol == 1) {
382 for (Standard_Integer jcote1 = 1 ; jcote1 <= ncote1 ; jcote1++) {
383 for (Standard_Integer jcote2 = 1 ; jcote2 <= ncote2 ; jcote2++) {
384 if (cote1(jcote1)<Tol) continue;
385 gp_Circ2d cirint(gp_Ax2d(center1,dirx),cote1(jcote1));
386 gp_Lin2d linint(gp_Pnt2d(lxloc-cote2(jcote2)*ydir*Radius,
387 lyloc+cote2(jcote2)*xdir*Radius),L2.Direction());
388 IntAna2d_AnaIntersection Intp(linint,cirint);
389 if (Intp.IsDone()) {
390 if (!Intp.IsEmpty()) {
391 for (i = 1 ; i <= Intp.NbPoints() ; i++) {
392 NbrSol++;
393 gp_Pnt2d Center(Intp.Point(i).Value());
394 gp_Ax2d axe(Center,dirx);
395 cirsol(NbrSol) = gp_Circ2d(axe,Radius);
396// ======================================
0797d9d3 397#ifdef OCCT_DEBUG
7fd59977 398 gp_Dir2d dc1(center1.XY()-Center.XY());
399#endif
400 gp_Dir2d dc2(origin2.XY()-Center.XY());
401 Standard_Real distcc1 = Center.Distance(center1);
402 if (!Qualified1.IsUnqualified()) {
403 qualifier1(NbrSol) = Qualified1.Qualifier();
404 }
405 else if (Abs(distcc1+Radius-R1) < Tol) {
406 qualifier1(NbrSol) = GccEnt_enclosed;
407 }
408 else if (Abs(distcc1-R1-Radius) < Tol) {
409 qualifier1(NbrSol) = GccEnt_outside;
410 }
411 else { qualifier1(NbrSol) = GccEnt_enclosing; }
412 if (!Qualified2.IsUnqualified()) {
413 qualifier2(NbrSol) = Qualified2.Qualifier();
414 }
415 else if (dc2.Dot(normL2) > 0.0) {
416 qualifier2(NbrSol) = GccEnt_outside;
417 }
418 else { qualifier2(NbrSol) = GccEnt_enclosed; }
419 TheSame1(NbrSol) = 0;
420 if ((Radius < R1) && Center.Distance(center1) <= R1) {
421 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*(gp_Dir2d(
422 Center.XY()-center1.XY()).XY()));
423 }
424 else {
425 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*(gp_Dir2d(
426 Center.XY()-center1.XY()).XY()));
427 }
428 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+
429 cote2(jcote2)*Radius*gp_XY(ydir,-xdir));
430 }
431 }
432 WellDone = Standard_True;
433 }
434 }
435 }
436 }
437 else if (nbsol == 2) {
438 gp_Pnt2d Cen(center1.XY()+cote*(R1+Radius)*gp_XY(-ydir,xdir));
439 gp_Ax2d axe(Cen,dirx);
440 cirsol(1) = gp_Circ2d(axe,Radius);
441// =================================
442 WellDone = Standard_True;
443 NbrSol = 1;
444 TheSame1(1) = 0;
445 qualifier1(1) = Qualified1.Qualifier();;
446 qualifier2(1) = Qualified2.Qualifier();
447 pnttg1sol(1)=gp_Pnt2d(Cen.XY()+cote*Radius*gp_XY(ydir,-xdir));
448 pnttg2sol(1)=gp_Pnt2d(Cen.XY()+Radius*gp_XY(ydir,-xdir));
449 }
450 else if (nbsol == 3) {
451 WellDone = Standard_True;
452 NbrSol = 1;
453 gp_Pnt2d Cen(center1.XY()+cote*(R1-Radius)*gp_XY(ydir,-xdir));
454 gp_Ax2d axe(Cen,dirx);
455 cirsol(1) = gp_Circ2d(axe,Radius);
456// =================================
457 qualifier1(1) = Qualified1.Qualifier();
458 qualifier2(1) = Qualified2.Qualifier();
459 pnttg2sol(1) = gp_Pnt2d(Cen.XY()+cote*Radius*gp_XY(ydir,-xdir));
460 if (Abs(R1-Radius) > 0.0) {
461 pnttg1sol(1) = gp_Pnt2d(Cen.XY()+ccote*Radius*gp_XY(ydir,-xdir));
462 }
463 else { TheSame1(1) = 1; }
464 }
465 else if (nbsol == 4) {
466 gp_Pnt2d Cent(center1.XY()+cote*(R1+Radius)*gp_XY(-ydir,xdir));
467 gp_Ax2d axe(Cent,dirx);
468 cirsol(1) = gp_Circ2d(axe,Radius);
469// =================================
470 qualifier1(1) = Qualified1.Qualifier();
471 qualifier2(1) = Qualified2.Qualifier();
472 WellDone = Standard_True;
473 NbrSol = 1;
474 TheSame1(1) = 0;
475 pnttg1sol(1)=gp_Pnt2d(Cent.XY()+cote*Radius*gp_XY(ydir,-xdir));
476 pnttg2sol(1)=gp_Pnt2d(Cent.XY()+cote*Radius*gp_XY(-ydir,xdir));
477 }
478 }
479 for (i = 1 ; i <= NbrSol ; i++) {
480 par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
481 if (TheSame1(i) == 0) {
482 pararg1(i)=ElCLib::Parameter(C1,pnttg1sol(i));
483 }
484 par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
485 pararg2(i)=ElCLib::Parameter(L2,pnttg2sol(i));
486 }
487}
488
489