0030675: Visualization - remove redundant proxy classes in hierarchy of PrsMgr_Presen...
[occt.git] / src / GccAna / GccAna_Circ2d3Tan_4.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15// cas de 2 cercles concentriques JCT 28/11/97
16
17#include <ElCLib.hxx>
42cf5bc1 18#include <GccAna_Circ2d3Tan.hxx>
7fd59977 19#include <GccAna_Circ2dBisec.hxx>
20#include <GccAna_CircPnt2dBisec.hxx>
42cf5bc1 21#include <GccEnt_BadQualifier.hxx>
22#include <GccEnt_QualifiedCirc.hxx>
23#include <GccEnt_QualifiedLin.hxx>
7fd59977 24#include <GccInt_BCirc.hxx>
7fd59977 25#include <GccInt_BElips.hxx>
26#include <GccInt_BHyper.hxx>
42cf5bc1 27#include <GccInt_BLine.hxx>
28#include <GccInt_IType.hxx>
29#include <gp_Circ2d.hxx>
30#include <gp_Dir2d.hxx>
31#include <gp_Lin2d.hxx>
32#include <gp_Pnt2d.hxx>
33#include <IntAna2d_AnaIntersection.hxx>
7fd59977 34#include <IntAna2d_Conic.hxx>
42cf5bc1 35#include <IntAna2d_IntPoint.hxx>
36#include <Standard_OutOfRange.hxx>
37#include <StdFail_NotDone.hxx>
38#include <TColStd_Array1OfReal.hxx>
7fd59977 39
40static Standard_Integer MaxSol = 20;
41//=========================================================================
0d969553 42// Creation of a circle tangent to two circles and a point. +
7fd59977 43//=========================================================================
44
45GccAna_Circ2d3Tan::
46 GccAna_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 ,
47 const GccEnt_QualifiedCirc& Qualified2 ,
48 const gp_Pnt2d& Point3 ,
49 const Standard_Real Tolerance ):
50
51//=========================================================================
0d969553 52// Initialization of fields. +
7fd59977 53//=========================================================================
54
55 cirsol(1,MaxSol) ,
56 qualifier1(1,MaxSol) ,
57 qualifier2(1,MaxSol) ,
58 qualifier3(1,MaxSol) ,
59 TheSame1(1,MaxSol) ,
60 TheSame2(1,MaxSol) ,
61 TheSame3(1,MaxSol) ,
62 pnttg1sol(1,MaxSol) ,
63 pnttg2sol(1,MaxSol) ,
64 pnttg3sol(1,MaxSol) ,
65 par1sol(1,MaxSol) ,
66 par2sol(1,MaxSol) ,
67 par3sol(1,MaxSol) ,
68 pararg1(1,MaxSol) ,
69 pararg2(1,MaxSol) ,
70 pararg3(1,MaxSol)
71{
72
73 gp_Dir2d dirx(1.0,0.0);
74 Standard_Real Tol = Abs(Tolerance);
75 WellDone = Standard_False;
76 NbrSol = 0;
77 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
78 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
79 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
80 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
9775fa61 81 throw GccEnt_BadQualifier();
7fd59977 82 return;
83 }
84
85//=========================================================================
0d969553 86// Processing. +
7fd59977 87//=========================================================================
88
89 gp_Circ2d C1(Qualified1.Qualified());
90 gp_Circ2d C2(Qualified2.Qualified());
91 Standard_Real R1 = C1.Radius();
92 Standard_Real R2 = C2.Radius();
93 gp_Pnt2d center1(C1.Location());
94 gp_Pnt2d center2(C2.Location());
95
96 TColStd_Array1OfReal Radius(1,2);
97 GccAna_Circ2dBisec Bis1(C1,C2);
98 GccAna_CircPnt2dBisec Bis2(C1,Point3);
99 if (Bis1.IsDone() && Bis2.IsDone()) {
100 Standard_Integer nbsolution1 = Bis1.NbSolutions();
101 Standard_Integer nbsolution2 = Bis2.NbSolutions();
102 for (Standard_Integer i = 1 ; i <= nbsolution1; i++) {
103 Handle(GccInt_Bisec) Sol1 = Bis1.ThisSolution(i);
104 GccInt_IType typ1 = Sol1->ArcType();
105 IntAna2d_AnaIntersection Intp;
106 for (Standard_Integer k = 1 ; k <= nbsolution2; k++) {
107 Handle(GccInt_Bisec) Sol2 = Bis2.ThisSolution(k);
108 GccInt_IType typ2 = Sol2->ArcType();
109 if (typ1 == GccInt_Cir) {
110 if (typ2 == GccInt_Cir) {
111 Intp.Perform(Sol1->Circle(),Sol2->Circle());
112 }
113 else if (typ2 == GccInt_Lin) {
114 Intp.Perform(Sol2->Line(),Sol1->Circle());
115 }
116 else if (typ2 == GccInt_Hpr) {
117 Intp.Perform(Sol1->Circle(),IntAna2d_Conic(Sol2->Hyperbola()));
118 }
119 else if (typ2 == GccInt_Ell) {
120 Intp.Perform(Sol1->Circle(),IntAna2d_Conic(Sol2->Ellipse()));
121 }
122 }
123 else if (typ1 == GccInt_Ell) {
124 if (typ2 == GccInt_Cir) {
125 Intp.Perform(Sol2->Circle(),IntAna2d_Conic(Sol1->Ellipse()));
126 }
127 else if (typ2 == GccInt_Lin) {
128 Intp.Perform(Sol2->Line(),IntAna2d_Conic(Sol1->Ellipse()));
129 }
130 else if (typ2 == GccInt_Hpr) {
131 Intp.Perform(Sol1->Ellipse(),IntAna2d_Conic(Sol2->Hyperbola()));
132 }
133 else if (typ2 == GccInt_Ell) {
134 Intp.Perform(Sol1->Ellipse(),IntAna2d_Conic(Sol2->Ellipse()));
135 }
136 }
137 else if (typ1 == GccInt_Lin) {
138 if (typ2 == GccInt_Cir) {
139 Intp.Perform(Sol1->Line(),Sol2->Circle());
140 }
141 else if (typ2 == GccInt_Lin) {
142 Intp.Perform(Sol1->Line(),Sol2->Line());
143 }
144 else if (typ2 == GccInt_Hpr) {
145 Intp.Perform(Sol1->Line(),IntAna2d_Conic(Sol2->Hyperbola()));
146 }
147 else if (typ2 == GccInt_Ell) {
148 Intp.Perform(Sol1->Line(),IntAna2d_Conic(Sol2->Ellipse()));
149 }
150 }
151 else if (typ1 == GccInt_Hpr) {
152 if (typ2 == GccInt_Cir) {
153 Intp.Perform(Sol2->Circle(),IntAna2d_Conic(Sol1->Hyperbola()));
154 }
155 else if (typ2 == GccInt_Lin) {
156 Intp.Perform(Sol2->Line(),IntAna2d_Conic(Sol1->Hyperbola()));
157 }
158 else if (typ2 == GccInt_Hpr) {
159 Intp.Perform(Sol2->Hyperbola(),IntAna2d_Conic(Sol1->Hyperbola()));
160 }
161 else if (typ2 == GccInt_Ell) {
162 Intp.Perform(Sol2->Ellipse(),IntAna2d_Conic(Sol1->Hyperbola()));
163 }
164 }
165 if (Intp.IsDone()) {
166 if (!Intp.IsEmpty()) {
167 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
168 Standard_Real Rradius=0;
169 gp_Pnt2d Center(Intp.Point(j).Value());
170 Standard_Real dist1 = Center.Distance(center1);
171 Standard_Real dist2 = Center.Distance(center2);
172 Standard_Real dist3 = Center.Distance(Point3);
173 Standard_Integer nbsol1 = 0;
174 Standard_Integer nbsol2 = 0;
175 Standard_Integer nbsol3 = 0;
176 Standard_Boolean ok = Standard_False;
177 if (Qualified1.IsEnclosed()) {
178 if (dist1-R1 < Tolerance) {
179 Radius(1) = Abs(R1-dist1);
180 nbsol1 = 1;
181 ok = Standard_True;
182 }
183 }
184 else if (Qualified1.IsOutside()) {
185 if (R1-dist1 < Tolerance) {
186 Radius(1) = Abs(R1-dist1);
187 nbsol1 = 1;
188 ok = Standard_True;
189 }
190 }
191 else if (Qualified1.IsEnclosing()) {
192 ok = Standard_True;
193 nbsol1 = 1;
194 Radius(1) = R1+dist1;
195 }
196 else if (Qualified1.IsUnqualified()) {
197 ok = Standard_True;
198 nbsol1 = 2;
199 Radius(1) = Abs(R1-dist1);
200 Radius(2) = R1+dist1;
201 }
202 if (Qualified2.IsEnclosed() && ok) {
203 if (dist2-R2 < Tolerance) {
204 for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
205 if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
206 Radius(1) = Abs(R2-dist2);
207 ok = Standard_True;
208 nbsol2 = 1;
209 }
210 }
211 }
212 }
213 else if (Qualified2.IsOutside() && ok) {
214 if (R2-dist2 < Tolerance) {
215 for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
216 if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
217 Radius(1) = Abs(R2-dist2);
218 ok = Standard_True;
219 nbsol2 = 1;
220 }
221 }
222 }
223 }
224 else if (Qualified2.IsEnclosing() && ok) {
225 for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
226 if (Abs(Radius(ii)-R2-dist2) < Tol) {
227 Radius(1) = R2+dist2;
228 ok = Standard_True;
229 nbsol2 = 1;
230 }
231 }
232 }
233 else if (Qualified2.IsUnqualified() && ok) {
234 for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
235 if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
236 Rradius = Abs(R2-dist2);
237 ok = Standard_True;
238 nbsol2++;
239 }
240 else if (Abs(Radius(ii)-R2-dist2) < Tol) {
241 Rradius = R2+dist2;
242 ok = Standard_True;
243 nbsol2++;
244 }
245 }
246 if (nbsol2 == 1) {
247 Radius(1) = Rradius;
248 }
249 else if (nbsol2 == 2) {
250 Radius(1) = Abs(R2-dist2);
251 Radius(2) = R2+dist2;
252 }
253 }
254 for (Standard_Integer ii = 1 ; ii <= nbsol2 ; ii++) {
255 if (Abs(dist3-Radius(ii)) <= Tol) {
256 nbsol3++;
257 ok = Standard_True;
258 }
259 }
260 if (ok) {
261 for (Standard_Integer k1 = 1 ; k1 <= nbsol3 ; k1++) {
262 NbrSol++;
263 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k1));
264// ==========================================================
265 Standard_Real distcc1 = Center.Distance(center1);
266 if (!Qualified1.IsUnqualified()) {
267 qualifier1(NbrSol) = Qualified1.Qualifier();
268 }
269 else if (Abs(distcc1+Radius(k1)-R1) < Tol) {
270 qualifier1(NbrSol) = GccEnt_enclosed;
271 }
272 else if (Abs(distcc1-R1-Radius(k1)) < Tol) {
273 qualifier1(NbrSol) = GccEnt_outside;
274 }
275 else { qualifier1(NbrSol) = GccEnt_enclosing; }
276
277// Standard_Real distcc2 = Center.Distance(center1);
278 Standard_Real distcc2 = Center.Distance(center2);
279 if (!Qualified2.IsUnqualified()) {
280 qualifier2(NbrSol) = Qualified2.Qualifier();
281 }
282 else if (Abs(distcc2+Radius(k1)-R2) < Tol) {
283 qualifier2(NbrSol) = GccEnt_enclosed;
284 }
285 else if (Abs(distcc2-R2-Radius(k1)) < Tol) {
286 qualifier2(NbrSol) = GccEnt_outside;
287 }
288 else { qualifier2(NbrSol) = GccEnt_enclosing; }
289 qualifier3(NbrSol) = GccEnt_noqualifier;
290 if (Center.Distance(center1) <= Tolerance &&
291 Abs(Radius(k1)-R1) <= Tolerance) {
292 TheSame1(NbrSol) = 1;
293 }
294 else {
295 TheSame1(NbrSol) = 0;
296 gp_Dir2d dc(center1.XY()-Center.XY());
9294c8f7 297 if (qualifier1(NbrSol) == GccEnt_enclosed)
298 dc.Reverse(); // if tangent circle is inside the source circle, moving to edge of source circle
7fd59977 299 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k1)*dc.XY());
300 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
301 pnttg1sol(NbrSol));
302 pararg1(NbrSol)=ElCLib::Parameter(C1,
303 pnttg1sol(NbrSol));
304 }
305 if (Center.Distance(center2) <= Tolerance &&
306 Abs(Radius(k1)-R2) <= Tolerance) {
307 TheSame2(NbrSol) = 1;
308 }
309 else {
310 TheSame2(NbrSol) = 0;
311 gp_Dir2d dc(center2.XY()-Center.XY());
0d969553
Y
312 // case of concentric circles :
313 // 2nd tangency point is at the other side of the circle solution
7fd59977 314 Standard_Real alpha = 1.;
315 if (center1.Distance(center2)<=Tolerance) alpha = -1;
316 pnttg2sol(NbrSol)=gp_Pnt2d(Center.XY()+alpha*Radius(k1)*dc.XY());
317 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
318 pnttg2sol(NbrSol));
319 pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
320 }
321 TheSame3(NbrSol) = 0;
322 pnttg3sol(NbrSol) = Point3;
323 par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
324 pnttg3sol(NbrSol));
325 pararg3(NbrSol) = 0.;
326 WellDone = Standard_True;
327 if (NbrSol==MaxSol) break;
328 }
329 }
330 }
331 }
332 WellDone = Standard_True;
333 if (NbrSol==MaxSol) break;
334 }
335 if (NbrSol==MaxSol) break;
336 }
337 if (NbrSol==MaxSol) break;
338 }
339 }
340
0d969553 341 // Debug to create the point on the solution circles.
7fd59977 342
343 Standard_Integer kk ;
344 for ( kk = 1; kk <= NbrSol; kk++) {
345 gp_Circ2d CC = cirsol(kk);
346 Standard_Real NR = CC.Location().Distance(Point3);
347 if (Abs(NR - CC.Radius()) > Tol) {
348 cirsol(kk).SetRadius(NR);
349 }
350 }
351
0d969553
Y
352 // Debug to eliminate multiple solution.
353 // this happens in case of intersection line hyperbola.
7fd59977 354 Standard_Real Tol2 = Tol*Tol;
355 for (kk = 1; kk <NbrSol; kk++) {
356 gp_Pnt2d PK = cirsol(kk).Location();
357 for (Standard_Integer ll = kk+1 ; ll <= NbrSol; ll++) {
358 gp_Pnt2d PL = cirsol(ll).Location();
359 if (PK.SquareDistance(PL) < Tol2) {
360 for (Standard_Integer mm = ll+1 ; mm <= NbrSol; mm++) {
361 cirsol(mm - 1) = cirsol (mm);
362 pnttg1sol(mm-1) = pnttg1sol(mm);
363 pnttg2sol(mm-1) = pnttg2sol(mm);
364 pnttg3sol(mm-1) = pnttg3sol(mm);
365 par1sol(mm-1) = par1sol(mm);
366 par2sol(mm-1) = par2sol(mm);
367 par3sol(mm-1) = par3sol(mm);
368 pararg1(mm-1) = pararg1(mm);
369 pararg2(mm-1) = pararg2(mm);
370 pararg3(mm-1) = pararg3(mm);
371 qualifier1(mm-1) = qualifier1(mm);
372 qualifier2(mm-1) = qualifier2(mm);
373 qualifier3(mm-1) = qualifier3(mm);
374 }
375 NbrSol--;
376 }
377 }
378 }
379 }
380