0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / GccAna / GccAna_Circ2d2TanOn.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.
7fd59977 14
7fd59977 15
7fd59977 16#include <ElCLib.hxx>
42cf5bc1 17#include <GccAna_Circ2d2TanOn.hxx>
18#include <GccAna_Circ2dBisec.hxx>
19#include <GccEnt_BadQualifier.hxx>
20#include <GccEnt_QualifiedCirc.hxx>
21#include <GccEnt_QualifiedLin.hxx>
7fd59977 22#include <GccInt_BCirc.hxx>
23#include <GccInt_BLine.hxx>
42cf5bc1 24#include <GccInt_IType.hxx>
25#include <gp_Ax2d.hxx>
26#include <gp_Circ2d.hxx>
27#include <gp_Dir2d.hxx>
28#include <gp_Lin2d.hxx>
29#include <gp_Pnt2d.hxx>
30#include <IntAna2d_AnaIntersection.hxx>
7fd59977 31#include <IntAna2d_Conic.hxx>
42cf5bc1 32#include <IntAna2d_IntPoint.hxx>
33#include <Standard_OutOfRange.hxx>
7fd59977 34#include <StdFail_NotDone.hxx>
42cf5bc1 35#include <TColStd_Array1OfReal.hxx>
36#include <TColStd_SequenceOfReal.hxx>
7fd59977 37
38//=========================================================================
0d969553
Y
39// Circles tangent to two circles C1 and C2 and centered on a straight line. +
40// We start by distinguishing various boundary cases that will be processed separately. +
41// In the general case: +
7fd59977 42// ==================== +
0d969553
Y
43// We calculate bissectrices to two circles that give us +
44// all possible locations of centers of all circles tangent to C1 and C2. +
45// We intersect these bissectrices with straight line which gives us +
46// points among which we are going to find solutions. +
47// The choices are made basing on Qualifiers of C1 and C2. +
7fd59977 48//=========================================================================
7fd59977 49GccAna_Circ2d2TanOn::
50 GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 ,
51 const GccEnt_QualifiedCirc& Qualified2 ,
52 const gp_Lin2d& OnLine ,
53 const Standard_Real Tolerance ):
54 cirsol(1,4) ,
55 qualifier1(1,4),
56 qualifier2(1,4) ,
57 TheSame1(1,4) ,
58 TheSame2(1,4) ,
59 pnttg1sol(1,4),
60 pnttg2sol(1,4),
61 pntcen(1,4) ,
62 par1sol(1,4) ,
63 par2sol(1,4) ,
64 pararg1(1,4) ,
65 pararg2(1,4) ,
66 parcen3(1,4)
67{
68
69 TheSame1.Init(0);
70 TheSame2.Init(0);
71 WellDone = Standard_False;
72 NbrSol = 0;
73 Standard_Integer nbsol = 0;
74 Standard_Real Tol = Abs(Tolerance);
75 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
76 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
77 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
78 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
9775fa61 79 throw GccEnt_BadQualifier();
7fd59977 80 return;
81 }
82 gp_Circ2d C1 = Qualified1.Qualified();
83 gp_Circ2d C2 = Qualified2.Qualified();
84 Standard_Real R1 = C1.Radius();
85 Standard_Real R2 = C2.Radius();
86 gp_Dir2d dirx(1.,0.);
87 gp_Pnt2d center1(C1.Location());
88 gp_Pnt2d center2(C2.Location());
89 TColStd_Array1OfReal Radius(1,2);
6e6cd5d9 90
7fd59977 91 Standard_Real dist1 = OnLine.Distance(center1);
92 Standard_Real dist2 = OnLine.Distance(center2);
93 Standard_Real d1 = dist1+R1;
94 Standard_Real d2 = dist2+R2;
95 Standard_Real d3 = dist1-R1;
96 Standard_Real d4 = dist2-R2;
97
98//=========================================================================
0d969553 99// Processing of boundary cases. +
7fd59977 100//=========================================================================
101
102 if (Abs(d3-d4)<Tol &&
103 (Qualified1.IsEnclosed() || Qualified1.IsOutside() ||
104 Qualified1.IsUnqualified()) &&
105 (Qualified2.IsEnclosed() || Qualified2.IsOutside() ||
106 Qualified2.IsUnqualified())) {
107 nbsol++;
108 Radius(nbsol) = Abs(d3);
109 WellDone = Standard_True;
110 }
111 if (Abs(d1-d2)<Tol &&
112 (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) &&
113 (Qualified2.IsEnclosing() || Qualified2.IsUnqualified())){
114 nbsol++;
115 Radius(nbsol) = Abs(d1);
116 WellDone = Standard_True;
117 }
118 if (Abs(d1-d4)<Tol &&
119 (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) &&
120 (Qualified2.IsEnclosed() || Qualified2.IsOutside() ||
121 Qualified2.IsUnqualified())){
122 nbsol++;
123 Radius(nbsol) = Abs(d1);
124 WellDone = Standard_True;
125 }
126 if (Abs(d3-d2)<Tol &&
127 (Qualified2.IsEnclosing() || Qualified2.IsUnqualified()) &&
128 (Qualified1.IsEnclosed() || Qualified1.IsOutside() ||
129 Qualified1.IsUnqualified())){
130 nbsol++;
131 Radius(nbsol) = Abs(d3);
132 WellDone = Standard_True;
133 }
134 gp_Lin2d L(center1,gp_Dir2d(center2.XY()-center1.XY()));
135 IntAna2d_AnaIntersection Intp(OnLine,L);
136 if (Intp.IsDone()) {
137 if (!Intp.IsEmpty()){
138 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
139 gp_Pnt2d Center(Intp.Point(j).Value());
140 for (Standard_Integer i = 1 ; i <= nbsol ; i++) {
141 NbrSol++;
142 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(i));
143// ==========================================================
144 WellDone = Standard_True;
145 Standard_Real distcc1 = Center.Distance(center1);
146 Standard_Real distcc2 = Center.Distance(center2);
147 if (!Qualified1.IsUnqualified()) {
148 qualifier1(NbrSol) = Qualified1.Qualifier();
149 }
150 else if (Abs(distcc1+Radius(i)-R1) < Tol) {
151 qualifier1(NbrSol) = GccEnt_enclosed;
152 }
153 else if (Abs(distcc1-R1-Radius(i)) < Tol) {
154 qualifier1(NbrSol) = GccEnt_outside;
155 }
156 else { qualifier1(NbrSol) = GccEnt_enclosing; }
157 if (!Qualified2.IsUnqualified()) {
158 qualifier2(NbrSol) = Qualified2.Qualifier();
159 }
160 else if (Abs(distcc2+Radius(i)-R2) < Tol) {
161 qualifier2(NbrSol) = GccEnt_enclosed;
162 }
163 else if (Abs(distcc2-R2-Radius(i)) < Tol) {
164 qualifier2(NbrSol) = GccEnt_outside;
165 }
166 else { qualifier2(NbrSol) = GccEnt_enclosing; }
167 gp_Dir2d dc1(center1.XY()-Center.XY());
168 gp_Dir2d dc2(center2.XY()-Center.XY());
169 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(i)*dc1.XY());
170 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(i)*dc2.XY());
171 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
172 pnttg1sol(NbrSol));
173 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
174 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
175 pnttg2sol(NbrSol));
176 pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
177 pntcen(NbrSol) = cirsol(NbrSol).Location();
178 parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
179 }
180 }
181 }
182 }
183
184//=========================================================================
0d969553 185// General case. +
7fd59977 186//=========================================================================
187
188 if (!WellDone) {
189 GccAna_Circ2dBisec Bis(C1,C2);
190 if (Bis.IsDone()) {
191 TColStd_Array1OfReal Rbid(1,2);
192 TColStd_Array1OfReal RBid(1,2);
193 Standard_Integer nbsolution = Bis.NbSolutions();
194 for (Standard_Integer i = 1 ; i <= nbsolution ; i++) {
195 Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
196 GccInt_IType typ = Sol->ArcType();
197
198 if (typ == GccInt_Cir) {
199 Intp.Perform(OnLine,Sol->Circle());
200 }
201 else if (typ == GccInt_Lin) {
202 Intp.Perform(OnLine,Sol->Line());
203 }
204 else if (typ == GccInt_Hpr) {
205 Intp.Perform(OnLine,IntAna2d_Conic(Sol->Hyperbola()));
206 }
207 else if (typ == GccInt_Ell) {
208 Intp.Perform(OnLine,IntAna2d_Conic(Sol->Ellipse()));
209 }
210 if (Intp.IsDone()) {
211 if (!Intp.IsEmpty()){
212 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
213 gp_Pnt2d Center(Intp.Point(j).Value());
214 dist1 = Center.Distance(center1);
215 dist2 = Center.Distance(center2);
216 nbsol = 0;
217 Standard_Integer nsol = 0;
218 Standard_Integer nnsol = 0;
219 R1 = C1.Radius();
220 R2 = C2.Radius();
221 if (Qualified1.IsEnclosed()) {
222 if (dist1-R1 < Tol) {
223 nbsol = 1;
224 Rbid(1) = Abs(R1-dist1);
225 }
226 }
227 else if (Qualified1.IsOutside()) {
228 if (R1-dist1 < Tol) {
229 nbsol = 1;
230 Rbid(1) = Abs(dist1-R1);
231 }
232 }
233 else if (Qualified1.IsEnclosing()) {
234 nbsol = 1;
235 Rbid(1) = dist1+R1;
236 }
237 else if (Qualified1.IsUnqualified()) {
238 nbsol = 2;
239 Rbid(1) = dist1+R1;
240 Rbid(1) = Abs(dist1-R1);
241 }
242 if (Qualified2.IsEnclosed() && nbsol != 0) {
243 if (dist2-R2 < Tol) {
244 nsol = 1;
245 RBid(1) = Abs(R2-dist2);
246 }
247 }
248 else if (Qualified2.IsOutside() && nbsol != 0) {
249 if (R2-dist2 < Tol) {
250 nsol = 1;
251 RBid(1) = Abs(R2-dist2);
252 }
253 }
254 else if (Qualified2.IsEnclosing() && nbsol != 0) {
255 nsol = 1;
256 RBid(1) = dist2+R2;
257 }
258 else if (Qualified2.IsUnqualified() && nbsol != 0) {
259 nsol = 2;
260 RBid(1) = dist2+R2;
261 RBid(2) = Abs(R2-dist2);
262 }
263 for (Standard_Integer isol = 1; isol <= nbsol ; isol++) {
264 for (Standard_Integer jsol = 1; jsol <= nsol ; jsol++) {
265 if (Abs(Rbid(isol)-RBid(jsol)) <= Tol) {
266 nnsol++;
267 Radius(nnsol) = (RBid(jsol)+Rbid(isol))/2.;
268 }
269 }
270 }
271 if (nnsol > 0) {
272 for (Standard_Integer k = 1 ; k <= nnsol ; k++) {
273 NbrSol++;
274 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
275// ==========================================================
276 Standard_Real distcc1 = Center.Distance(center1);
277 Standard_Real distcc2 = Center.Distance(center2);
278 if (!Qualified1.IsUnqualified()) {
279 qualifier1(NbrSol) = Qualified1.Qualifier();
280 }
281 else if (Abs(distcc1+Radius(i)-R1) < Tol) {
282 qualifier1(NbrSol) = GccEnt_enclosed;
283 }
284 else if (Abs(distcc1-R1-Radius(i)) < Tol) {
285 qualifier1(NbrSol) = GccEnt_outside;
286 }
287 else { qualifier1(NbrSol) = GccEnt_enclosing; }
288 if (!Qualified2.IsUnqualified()) {
289 qualifier2(NbrSol) = Qualified2.Qualifier();
290 }
291 else if (Abs(distcc2+Radius(i)-R2) < Tol) {
292 qualifier2(NbrSol) = GccEnt_enclosed;
293 }
294 else if (Abs(distcc2-R2-Radius(i)) < Tol) {
295 qualifier2(NbrSol) = GccEnt_outside;
296 }
297 else { qualifier2(NbrSol) = GccEnt_enclosing; }
298 if (Center.Distance(center1) <= Tol &&
299 Abs(Radius(k)-C1.Radius()) <= Tol) {TheSame1(NbrSol)=1;}
300 else {
301 TheSame1(NbrSol) = 0;
302 gp_Dir2d dc1(center1.XY()-Center.XY());
303 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+
304 Radius(k)*dc1.XY());
305 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
306 pnttg1sol(NbrSol));
307 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg2sol(NbrSol));
308 }
309 if (Center.Distance(center2) <= Tol &&
310 Abs(Radius(k)-C2.Radius()) <= Tol) {TheSame2(NbrSol)=1;}
311 else {
312 TheSame2(NbrSol) = 0;
313 gp_Dir2d dc2(center2.XY()-Center.XY());
314 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+
315 Radius(k)*dc2.XY());
316 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
317 pnttg2sol(NbrSol));
318 pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
319 }
320 pntcen(NbrSol) = Center;
321 parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
322 }
323 }
324 }
325 }
326 WellDone = Standard_True;
327 }
328 }
329 }
330 }
331}
332
333//========================================================================
334
335Standard_Boolean GccAna_Circ2d2TanOn::
336 IsDone () const{ return WellDone; }
337
338Standard_Integer GccAna_Circ2d2TanOn::
339 NbSolutions () const{ return NbrSol; }
340
341gp_Circ2d GccAna_Circ2d2TanOn::
342 ThisSolution (const Standard_Integer Index) const{ return cirsol(Index); }
343
344void GccAna_Circ2d2TanOn::
345 WhichQualifier(const Standard_Integer Index ,
346 GccEnt_Position& Qualif1 ,
347 GccEnt_Position& Qualif2 ) const
348{
9775fa61 349 if (!WellDone) { throw StdFail_NotDone(); }
350 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
7fd59977 351 else {
352 Qualif1 = qualifier1(Index);
353 Qualif2 = qualifier2(Index);
354 }
355}
356
357void GccAna_Circ2d2TanOn::
358 Tangency1 (const Standard_Integer Index ,
359 Standard_Real& ParSol ,
360 Standard_Real& ParArg ,
361 gp_Pnt2d& PntSol ) const{
9775fa61 362 if (!WellDone) { throw StdFail_NotDone(); }
363 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
7fd59977 364 else {
365 if (TheSame1(Index) == 0) {
366 ParSol = par1sol(Index);
367 ParArg = pararg1(Index);
368 PntSol = gp_Pnt2d(pnttg1sol(Index));
369 }
9775fa61 370 else { throw StdFail_NotDone(); }
7fd59977 371 }
372 }
373
374void GccAna_Circ2d2TanOn::
375 Tangency2 (const Standard_Integer Index ,
376 Standard_Real& ParSol ,
377 Standard_Real& ParArg ,
378 gp_Pnt2d& PntSol ) const{
9775fa61 379 if (!WellDone) { throw StdFail_NotDone(); }
380 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
7fd59977 381 else {
382 if (TheSame2(Index) == 0) {
383 ParSol = par2sol(Index);
384 ParArg = pararg2(Index);
385 PntSol = gp_Pnt2d(pnttg2sol(Index));
386 }
9775fa61 387 else { throw StdFail_NotDone(); }
7fd59977 388 }
389 }
390
391void GccAna_Circ2d2TanOn::
392 CenterOn3 (const Standard_Integer Index ,
393 Standard_Real& ParArg ,
394 gp_Pnt2d& PntSol ) const{
9775fa61 395 if (!WellDone) { throw StdFail_NotDone(); }
396 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
7fd59977 397 else {
398 ParArg = parcen3(Index);
399 PntSol = pnttg1sol(Index);
400 }
401 }
402
403Standard_Boolean GccAna_Circ2d2TanOn::
404 IsTheSame1 (const Standard_Integer Index) const
405{
9775fa61 406 if (!WellDone) { throw StdFail_NotDone(); }
407 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
7fd59977 408
409 if (TheSame1(Index) == 0) { return Standard_False; }
410 return Standard_True;
411}
412
413Standard_Boolean GccAna_Circ2d2TanOn::
414 IsTheSame2 (const Standard_Integer Index) const
415{
9775fa61 416 if (!WellDone) { throw StdFail_NotDone(); }
417 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
7fd59977 418
419 if (TheSame2(Index) == 0) { return Standard_False; }
420 return Standard_True;
421}