0027961: Visualization - remove unused and no more working OpenGl_AVIWriter
[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())) {
81 GccEnt_BadQualifier::Raise();
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());
297 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k1)*dc.XY());
298 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
299 pnttg1sol(NbrSol));
300 pararg1(NbrSol)=ElCLib::Parameter(C1,
301 pnttg1sol(NbrSol));
302 }
303 if (Center.Distance(center2) <= Tolerance &&
304 Abs(Radius(k1)-R2) <= Tolerance) {
305 TheSame2(NbrSol) = 1;
306 }
307 else {
308 TheSame2(NbrSol) = 0;
309 gp_Dir2d dc(center2.XY()-Center.XY());
0d969553
Y
310 // case of concentric circles :
311 // 2nd tangency point is at the other side of the circle solution
7fd59977 312 Standard_Real alpha = 1.;
313 if (center1.Distance(center2)<=Tolerance) alpha = -1;
314 pnttg2sol(NbrSol)=gp_Pnt2d(Center.XY()+alpha*Radius(k1)*dc.XY());
315 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
316 pnttg2sol(NbrSol));
317 pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
318 }
319 TheSame3(NbrSol) = 0;
320 pnttg3sol(NbrSol) = Point3;
321 par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
322 pnttg3sol(NbrSol));
323 pararg3(NbrSol) = 0.;
324 WellDone = Standard_True;
325 if (NbrSol==MaxSol) break;
326 }
327 }
328 }
329 }
330 WellDone = Standard_True;
331 if (NbrSol==MaxSol) break;
332 }
333 if (NbrSol==MaxSol) break;
334 }
335 if (NbrSol==MaxSol) break;
336 }
337 }
338
0d969553 339 // Debug to create the point on the solution circles.
7fd59977 340
341 Standard_Integer kk ;
342 for ( kk = 1; kk <= NbrSol; kk++) {
343 gp_Circ2d CC = cirsol(kk);
344 Standard_Real NR = CC.Location().Distance(Point3);
345 if (Abs(NR - CC.Radius()) > Tol) {
346 cirsol(kk).SetRadius(NR);
347 }
348 }
349
0d969553
Y
350 // Debug to eliminate multiple solution.
351 // this happens in case of intersection line hyperbola.
7fd59977 352 Standard_Real Tol2 = Tol*Tol;
353 for (kk = 1; kk <NbrSol; kk++) {
354 gp_Pnt2d PK = cirsol(kk).Location();
355 for (Standard_Integer ll = kk+1 ; ll <= NbrSol; ll++) {
356 gp_Pnt2d PL = cirsol(ll).Location();
357 if (PK.SquareDistance(PL) < Tol2) {
358 for (Standard_Integer mm = ll+1 ; mm <= NbrSol; mm++) {
359 cirsol(mm - 1) = cirsol (mm);
360 pnttg1sol(mm-1) = pnttg1sol(mm);
361 pnttg2sol(mm-1) = pnttg2sol(mm);
362 pnttg3sol(mm-1) = pnttg3sol(mm);
363 par1sol(mm-1) = par1sol(mm);
364 par2sol(mm-1) = par2sol(mm);
365 par3sol(mm-1) = par3sol(mm);
366 pararg1(mm-1) = pararg1(mm);
367 pararg2(mm-1) = pararg2(mm);
368 pararg3(mm-1) = pararg3(mm);
369 qualifier1(mm-1) = qualifier1(mm);
370 qualifier2(mm-1) = qualifier2(mm);
371 qualifier3(mm-1) = qualifier3(mm);
372 }
373 NbrSol--;
374 }
375 }
376 }
377 }
378