578ce4be |
1 | // Copyright (c) 1995-1999 Matra Datavision |
2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
3 | // |
4 | // This file is part of Open CASCADE Technology software library. |
5 | // |
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 |
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. |
11 | // |
12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. |
14 | |
15 | //======================================================================== |
16 | // circulaire tangent a un element de type : - Cercle. + |
17 | // - Ligne. + |
18 | // - Point. + |
19 | // centre sur un deuxieme element de type : - Cercle. + |
20 | // - Ligne. + |
21 | // de rayon donne : Radius. + |
22 | //======================================================================== |
23 | |
5201d3e6 |
24 | #include <Adaptor2d_OffsetCurve.hxx> |
578ce4be |
25 | #include <ElCLib.hxx> |
578ce4be |
26 | #include <GccEnt_BadQualifier.hxx> |
42cf5bc1 |
27 | #include <GccEnt_QualifiedCirc.hxx> |
28 | #include <GccEnt_QualifiedLin.hxx> |
29 | #include <Geom2dAdaptor_Curve.hxx> |
578ce4be |
30 | #include <Geom2dAdaptor_HCurve.hxx> |
42cf5bc1 |
31 | #include <Geom2dGcc_Circ2dTanOnRadGeo.hxx> |
32 | #include <Geom2dGcc_CurveTool.hxx> |
42cf5bc1 |
33 | #include <Geom2dGcc_QCurve.hxx> |
578ce4be |
34 | #include <Geom2dInt_GInter.hxx> |
42cf5bc1 |
35 | #include <gp_Circ2d.hxx> |
36 | #include <gp_Dir2d.hxx> |
37 | #include <gp_Lin2d.hxx> |
38 | #include <gp_Pnt2d.hxx> |
39 | #include <IntRes2d_Domain.hxx> |
40 | #include <IntRes2d_IntersectionPoint.hxx> |
41 | #include <math_DirectPolynomialRoots.hxx> |
42 | #include <Standard_NegativeValue.hxx> |
43 | #include <Standard_OutOfRange.hxx> |
44 | #include <StdFail_NotDone.hxx> |
45 | #include <TColStd_Array1OfReal.hxx> |
578ce4be |
46 | |
47 | //========================================================================= |
48 | // Cercle tangent : a un cercle Qualified1 (C1). + |
49 | // centre : sur une droite OnLine. + |
50 | // de rayon : Radius. + |
51 | // + |
52 | // On initialise le tableau de solutions cirsol ainsi que tous les + |
53 | // champs. + |
54 | // On elimine en fonction du qualifieur les cas ne presentant pas de + |
55 | // solutions. + |
56 | // On resoud l equation du second degre indiquant que le point de centre + |
57 | // recherche (xc,yc) est a une distance Radius du cercle C1 et + |
58 | // sur la droite OnLine. + |
59 | // Les solutions sont representees par les cercles : + |
60 | // - de centre Pntcen(xc,yc) + |
61 | // - de rayon Radius. + |
62 | //========================================================================= |
578ce4be |
63 | Geom2dGcc_Circ2dTanOnRadGeo:: |
64 | Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1, |
65 | const gp_Lin2d& OnLine , |
66 | const Standard_Real Radius , |
67 | const Standard_Real Tolerance ): |
68 | |
69 | //========================================================================= |
70 | // Initialisation des champs. + |
71 | //========================================================================= |
72 | |
73 | cirsol(1,8) , |
74 | qualifier1(1,8) , |
75 | TheSame1(1,8) , |
76 | pnttg1sol(1,8) , |
77 | pntcen3(1,8) , |
78 | par1sol(1,8) , |
79 | pararg1(1,8) , |
80 | parcen3(1,8) |
81 | { |
82 | |
83 | //========================================================================= |
84 | // Traitement. + |
85 | //========================================================================= |
86 | |
87 | gp_Dir2d dirx(1.0,0.0); |
88 | Standard_Real Tol = Abs(Tolerance); |
89 | Standard_Real thefirst = -100000.; |
90 | Standard_Real thelast = 100000.; |
91 | Standard_Real firstparam; |
92 | Standard_Real lastparam; |
93 | WellDone = Standard_False; |
94 | NbrSol = 0; |
95 | if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || |
96 | Qualified1.IsOutside() || Qualified1.IsUnqualified())) { |
9775fa61 |
97 | throw GccEnt_BadQualifier(); |
578ce4be |
98 | return; |
99 | } |
100 | Standard_Integer nbrcote1 = 0; |
101 | TColStd_Array1OfReal Coef(1,2); |
102 | Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified(); |
103 | |
9775fa61 |
104 | if (Radius < 0.0) { throw Standard_NegativeValue(); } |
578ce4be |
105 | else { |
106 | if (Qualified1.IsEnclosed()) { |
107 | // =========================== |
108 | nbrcote1 = 1; |
109 | Coef(1) = Radius; |
110 | } |
111 | else if(Qualified1.IsOutside()) { |
112 | // =============================== |
113 | nbrcote1 = 1; |
114 | Coef(1) = -Radius; |
115 | } |
116 | else if(Qualified1.IsUnqualified()) { |
117 | // =================================== |
118 | nbrcote1 = 2; |
119 | Coef(1) = Radius; |
120 | Coef(2) = -Radius; |
121 | } |
122 | IntRes2d_Domain D1; |
123 | Geom2dInt_TheIntConicCurveOfGInter Intp; |
124 | for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { |
125 | Handle(Geom2dAdaptor_HCurve) HCu1 = new Geom2dAdaptor_HCurve(Cu1); |
5201d3e6 |
126 | Adaptor2d_OffsetCurve C2(HCu1,Coef(jcote1)); |
127 | firstparam = Max(C2.FirstParameter(),thefirst); |
128 | lastparam = Min(C2.LastParameter(),thelast); |
129 | IntRes2d_Domain D2(C2.Value(firstparam), firstparam, Tol, |
130 | C2.Value(lastparam), lastparam, Tol); |
578ce4be |
131 | Intp.Perform(OnLine,D1,C2,D2,Tol,Tol); |
132 | if (Intp.IsDone()) { |
133 | if (!Intp.IsEmpty()) { |
134 | for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { |
135 | NbrSol++; |
136 | gp_Pnt2d Center(Intp.Point(i).Value()); |
137 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); |
138 | // ======================================================= |
139 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
140 | TheSame1(NbrSol) = 0; |
141 | pararg1(NbrSol) = Intp.Point(i).ParamOnSecond(); |
142 | parcen3(NbrSol) = Intp.Point(i).ParamOnFirst(); |
143 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
144 | pnttg1sol(NbrSol)); |
145 | pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol))); |
146 | pntcen3(NbrSol) = Center; |
147 | } |
148 | } |
149 | WellDone = Standard_True; |
150 | } |
151 | } |
152 | } |
153 | } |
154 | |
155 | //========================================================================= |
156 | // Cercle tangent : a un cercle Qualified1 (C1). + |
157 | // centre : sur une droite OnLine. + |
158 | // de rayon : Radius. + |
159 | // + |
160 | // On initialise le tableau de solutions cirsol ainsi que tous les + |
161 | // champs. + |
162 | // On elimine en fonction du qualifieur les cas ne presentant pas de + |
163 | // solutions. + |
164 | // On resoud l equation du second degre indiquant que le point de centre + |
165 | // recherche (xc,yc) est a une distance Radius du cercle C1 et + |
166 | // sur la droite OnLine. + |
167 | // Les solutions sont representees par les cercles : + |
168 | // - de centre Pntcen(xc,yc) + |
169 | // - de rayon Radius. + |
170 | //========================================================================= |
171 | |
172 | Geom2dGcc_Circ2dTanOnRadGeo:: |
173 | Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1, |
174 | const gp_Circ2d& OnCirc , |
175 | const Standard_Real Radius , |
176 | const Standard_Real Tolerance ): |
177 | |
178 | //========================================================================= |
179 | // Initialisation des champs. + |
180 | //========================================================================= |
181 | |
182 | cirsol(1,8) , |
183 | qualifier1(1,8) , |
184 | TheSame1(1,8) , |
185 | pnttg1sol(1,8) , |
186 | pntcen3(1,8) , |
187 | par1sol(1,8) , |
188 | pararg1(1,8) , |
189 | parcen3(1,8) |
190 | { |
191 | |
192 | //========================================================================= |
193 | // Traitement. + |
194 | //========================================================================= |
195 | |
196 | gp_Dir2d dirx(1.0,0.0); |
197 | Standard_Real thefirst = -100000.; |
198 | Standard_Real thelast = 100000.; |
199 | Standard_Real firstparam; |
200 | Standard_Real lastparam; |
201 | Standard_Real Tol = Abs(Tolerance); |
202 | Standard_Integer nbrcote1=0; |
203 | WellDone = Standard_False; |
204 | NbrSol = 0; |
205 | if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || |
206 | Qualified1.IsOutside() || Qualified1.IsUnqualified())) { |
9775fa61 |
207 | throw GccEnt_BadQualifier(); |
578ce4be |
208 | return; |
209 | } |
210 | TColStd_Array1OfReal cote1(1,2); |
211 | Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified(); |
212 | |
213 | if (Radius < 0.0) { |
9775fa61 |
214 | throw Standard_NegativeValue(); |
578ce4be |
215 | } |
216 | else { |
217 | if (Qualified1.IsEnclosed()) { |
218 | // =========================== |
219 | nbrcote1 = 1; |
220 | cote1(1) = Radius; |
221 | } |
222 | else if(Qualified1.IsOutside()) { |
223 | // =============================== |
224 | nbrcote1 = 1; |
225 | cote1(1) = -Radius; |
226 | } |
227 | else if(Qualified1.IsUnqualified()) { |
228 | // =================================== |
229 | nbrcote1 = 2; |
230 | cote1(1) = Radius; |
231 | cote1(2) = -Radius; |
232 | } |
233 | IntRes2d_Domain D1(ElCLib::Value(0.,OnCirc), 0.,Tol, |
234 | ElCLib::Value(2.*M_PI,OnCirc),2.*M_PI,Tol); |
235 | D1.SetEquivalentParameters(0.,2.*M_PI); |
236 | Geom2dInt_TheIntConicCurveOfGInter Intp; |
237 | for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { |
238 | Handle(Geom2dAdaptor_HCurve) HCu1 = new Geom2dAdaptor_HCurve(Cu1); |
5201d3e6 |
239 | Adaptor2d_OffsetCurve C2(HCu1,cote1(jcote1)); |
240 | firstparam = Max(C2.FirstParameter(),thefirst); |
241 | lastparam = Min(C2.LastParameter(),thelast); |
242 | IntRes2d_Domain D2(C2.Value(firstparam),firstparam,Tol, |
243 | C2.Value(lastparam),lastparam,Tol); |
578ce4be |
244 | Intp.Perform(OnCirc,D1,C2,D2,Tol,Tol); |
245 | if (Intp.IsDone()) { |
246 | if (!Intp.IsEmpty()) { |
247 | for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { |
248 | NbrSol++; |
249 | gp_Pnt2d Center(Intp.Point(i).Value()); |
250 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); |
251 | // ======================================================= |
252 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
253 | TheSame1(NbrSol) = 0; |
254 | pararg1(NbrSol) = Intp.Point(i).ParamOnSecond(); |
255 | parcen3(NbrSol) = Intp.Point(i).ParamOnFirst(); |
256 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
257 | pnttg1sol(NbrSol)); |
258 | pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol))); |
259 | pntcen3(NbrSol) = Center; |
260 | } |
261 | } |
262 | WellDone = Standard_True; |
263 | } |
264 | } |
265 | } |
266 | } |
267 | |
268 | //========================================================================= |
269 | // Cercle tangent : a un cercle Qualified1 (C1). + |
270 | // centre : sur une droite OnLine. + |
271 | // de rayon : Radius. + |
272 | // + |
273 | // On initialise le tableau de solutions cirsol ainsi que tous les + |
274 | // champs. + |
275 | // On elimine en fonction du qualifieur les cas ne presentant pas de + |
276 | // solutions. + |
277 | // On resoud l equation du second degre indiquant que le point de centre + |
278 | // recherche (xc,yc) est a une distance Radius du cercle C1 et + |
279 | // sur la droite OnLine. + |
280 | // Les solutions sont representees par les cercles : + |
281 | // - de centre Pntcen(xc,yc) + |
282 | // - de rayon Radius. + |
283 | //========================================================================= |
284 | |
285 | Geom2dGcc_Circ2dTanOnRadGeo:: |
286 | Geom2dGcc_Circ2dTanOnRadGeo (const GccEnt_QualifiedCirc& Qualified1, |
287 | const Geom2dAdaptor_Curve& OnCurv , |
288 | const Standard_Real Radius , |
289 | const Standard_Real Tolerance ): |
290 | |
291 | //========================================================================= |
292 | // Initialisation des champs. + |
293 | //========================================================================= |
294 | |
295 | cirsol(1,8) , |
296 | qualifier1(1,8) , |
297 | TheSame1(1,8) , |
298 | pnttg1sol(1,8) , |
299 | pntcen3(1,8) , |
300 | par1sol(1,8) , |
301 | pararg1(1,8) , |
302 | parcen3(1,8) |
303 | { |
304 | |
305 | //========================================================================= |
306 | // Traitement. + |
307 | //========================================================================= |
308 | |
309 | gp_Dir2d dirx(1.0,0.0); |
310 | Standard_Real thefirst = -100000.; |
311 | Standard_Real thelast = 100000.; |
312 | Standard_Real firstparam; |
313 | Standard_Real lastparam; |
314 | Standard_Real Tol = Abs(Tolerance); |
315 | Standard_Integer nbrcote1=0; |
316 | WellDone = Standard_False; |
317 | NbrSol = 0; |
318 | if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || |
319 | Qualified1.IsOutside() || Qualified1.IsUnqualified())) { |
9775fa61 |
320 | throw GccEnt_BadQualifier(); |
578ce4be |
321 | return; |
322 | } |
323 | TColStd_Array1OfReal cote1(1,2); |
324 | gp_Circ2d C1 = Qualified1.Qualified(); |
325 | gp_Pnt2d center1(C1.Location()); |
326 | Standard_Real R1 = C1.Radius(); |
327 | |
328 | if (Radius < 0.0) { |
9775fa61 |
329 | throw Standard_NegativeValue(); |
578ce4be |
330 | } |
331 | else { |
332 | if (Qualified1.IsEnclosed()) { |
333 | // =========================== |
334 | nbrcote1 = 1; |
335 | cote1(1) = Radius; |
336 | } |
337 | else if(Qualified1.IsOutside()) { |
338 | // =============================== |
339 | nbrcote1 = 1; |
340 | cote1(1) = -Radius; |
341 | } |
342 | else if(Qualified1.IsUnqualified()) { |
343 | // =================================== |
344 | nbrcote1 = 2; |
345 | cote1(1) = Radius; |
346 | cote1(2) = -Radius; |
347 | } |
348 | Geom2dInt_TheIntConicCurveOfGInter Intp; |
349 | for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { |
350 | gp_Circ2d Circ(C1.XAxis(),R1 + cote1(jcote1)); |
351 | IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol, |
352 | ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol); |
353 | D1.SetEquivalentParameters(0.,2.*M_PI); |
354 | firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst); |
355 | lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast); |
356 | IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol, |
357 | Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol); |
358 | Intp.Perform(Circ,D1,OnCurv,D2,Tol,Tol); |
359 | if (Intp.IsDone()) { |
360 | if (!Intp.IsEmpty()) { |
361 | for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { |
362 | NbrSol++; |
363 | gp_Pnt2d Center(Intp.Point(i).Value()); |
364 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); |
365 | // ======================================================= |
366 | Standard_Real distcc1 = Center.Distance(center1); |
367 | if (!Qualified1.IsUnqualified()) { |
368 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
369 | } |
370 | else if (Abs(distcc1+Radius-R1) < Tol) { |
371 | qualifier1(NbrSol) = GccEnt_enclosed; |
372 | } |
373 | else if (Abs(distcc1-R1-Radius) < Tol) { |
374 | qualifier1(NbrSol) = GccEnt_outside; |
375 | } |
376 | else { qualifier1(NbrSol) = GccEnt_enclosing; } |
377 | TheSame1(NbrSol) = 0; |
378 | pararg1(NbrSol) = Intp.Point(i).ParamOnFirst(); |
379 | parcen3(NbrSol) = Intp.Point(i).ParamOnSecond(); |
380 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
381 | pnttg1sol(NbrSol)); |
382 | pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),C1); |
383 | pntcen3(NbrSol) = Center; |
384 | } |
385 | } |
386 | WellDone = Standard_True; |
387 | } |
388 | } |
389 | } |
390 | } |
391 | |
392 | //========================================================================= |
393 | // Cercle tangent : a un cercle Qualified1 (C1). + |
394 | // centre : sur une droite OnLine. + |
395 | // de rayon : Radius. + |
396 | // + |
397 | // On initialise le tableau de solutions cirsol ainsi que tous les + |
398 | // champs. + |
399 | // On elimine en fonction du qualifieur les cas ne presentant pas de + |
400 | // solutions. + |
401 | // On resoud l equation du second degre indiquant que le point de centre + |
402 | // recherche (xc,yc) est a une distance Radius du cercle C1 et + |
403 | // sur la droite OnLine. + |
404 | // Les solutions sont representees par les cercles : + |
405 | // - de centre Pntcen(xc,yc) + |
406 | // - de rayon Radius. + |
407 | //========================================================================= |
408 | |
409 | Geom2dGcc_Circ2dTanOnRadGeo:: |
410 | Geom2dGcc_Circ2dTanOnRadGeo (const GccEnt_QualifiedLin& Qualified1, |
411 | const Geom2dAdaptor_Curve& OnCurv , |
412 | const Standard_Real Radius , |
413 | const Standard_Real Tolerance ): |
414 | |
415 | //========================================================================= |
416 | // Initialisation des champs. + |
417 | //========================================================================= |
418 | |
419 | cirsol(1,8) , |
420 | qualifier1(1,8) , |
421 | TheSame1(1,8) , |
422 | pnttg1sol(1,8) , |
423 | pntcen3(1,8) , |
424 | par1sol(1,8) , |
425 | pararg1(1,8) , |
426 | parcen3(1,8) |
427 | { |
428 | |
429 | //========================================================================= |
430 | // Traitement. + |
431 | //========================================================================= |
432 | |
433 | gp_Dir2d dirx(1.0,0.0); |
434 | Standard_Real thefirst = -100000.; |
435 | Standard_Real thelast = 100000.; |
436 | Standard_Real firstparam; |
437 | Standard_Real lastparam; |
438 | Standard_Real Tol = Abs(Tolerance); |
439 | WellDone = Standard_False; |
440 | NbrSol = 0; |
441 | if (!(Qualified1.IsEnclosed() || |
442 | Qualified1.IsOutside() || Qualified1.IsUnqualified())) { |
9775fa61 |
443 | throw GccEnt_BadQualifier(); |
578ce4be |
444 | return; |
445 | } |
446 | Standard_Integer nbrcote1=0; |
447 | TColStd_Array1OfReal cote1(1,2); |
448 | gp_Lin2d L1 = Qualified1.Qualified(); |
449 | gp_Pnt2d origin1(L1.Location()); |
450 | gp_Dir2d dir1(L1.Direction()); |
451 | gp_Dir2d norm1(-dir1.Y(),dir1.X()); |
452 | |
453 | if (Radius < 0.0) { |
9775fa61 |
454 | throw Standard_NegativeValue(); |
578ce4be |
455 | } |
456 | else { |
457 | if (Qualified1.IsEnclosed()) { |
458 | // =========================== |
459 | nbrcote1 = 1; |
460 | cote1(1) = Radius; |
461 | } |
462 | else if(Qualified1.IsOutside()) { |
463 | // =============================== |
464 | nbrcote1 = 1; |
465 | cote1(1) = -Radius; |
466 | } |
467 | else if(Qualified1.IsUnqualified()) { |
468 | // =================================== |
469 | nbrcote1 = 2; |
470 | cote1(1) = Radius; |
471 | cote1(2) = -Radius; |
472 | } |
473 | Geom2dInt_TheIntConicCurveOfGInter Intp; |
474 | for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { |
475 | gp_Pnt2d Point(dir1.XY()+cote1(jcote1)*norm1.XY()); |
476 | gp_Lin2d Line(Point,dir1); // ligne avec deport. |
477 | IntRes2d_Domain D1; |
478 | firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst); |
479 | lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast); |
480 | IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol, |
481 | Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol); |
482 | Intp.Perform(Line,D1,OnCurv,D2,Tol,Tol); |
483 | if (Intp.IsDone()) { |
484 | if (!Intp.IsEmpty()) { |
485 | for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { |
486 | NbrSol++; |
487 | gp_Pnt2d Center(Intp.Point(i).Value()); |
488 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); |
489 | // ======================================================= |
490 | gp_Dir2d dc1(origin1.XY()-Center.XY()); |
491 | if (!Qualified1.IsUnqualified()) { |
492 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
493 | } |
494 | else if (dc1.Dot(norm1) > 0.0) { |
495 | qualifier1(NbrSol) = GccEnt_outside; |
496 | } |
497 | else { qualifier1(NbrSol) = GccEnt_enclosed; } |
498 | TheSame1(NbrSol) = 0; |
499 | pararg1(NbrSol) = Intp.Point(i).ParamOnFirst(); |
500 | parcen3(NbrSol) = Intp.Point(i).ParamOnSecond(); |
501 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
502 | pnttg1sol(NbrSol)); |
503 | pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),L1); |
504 | pntcen3(NbrSol) = Center; |
505 | } |
506 | } |
507 | WellDone = Standard_True; |
508 | } |
509 | } |
510 | } |
511 | } |
512 | |
513 | //========================================================================= |
514 | // Cercle tangent : a un cercle Qualified1 (C1). + |
515 | // centre : sur une droite OnLine. + |
516 | // de rayon : Radius. + |
517 | // + |
518 | // On initialise le tableau de solutions cirsol ainsi que tous les + |
519 | // champs. + |
520 | // On elimine en fonction du qualifieur les cas ne presentant pas de + |
521 | // solutions. + |
522 | // On resoud l equation du second degre indiquant que le point de centre + |
523 | // recherche (xc,yc) est a une distance Radius du cercle C1 et + |
524 | // sur la droite OnLine. + |
525 | // Les solutions sont representees par les cercles : + |
526 | // - de centre Pntcen(xc,yc) + |
527 | // - de rayon Radius. + |
528 | //========================================================================= |
529 | |
530 | Geom2dGcc_Circ2dTanOnRadGeo:: |
531 | Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1, |
532 | const Geom2dAdaptor_Curve& OnCurv , |
533 | const Standard_Real Radius , |
534 | const Standard_Real Tolerance ): |
535 | |
536 | //========================================================================= |
537 | // Initialisation des champs. + |
538 | //========================================================================= |
539 | |
540 | cirsol(1,8) , |
541 | qualifier1(1,8) , |
542 | TheSame1(1,8) , |
543 | pnttg1sol(1,8) , |
544 | pntcen3(1,8) , |
545 | par1sol(1,8) , |
546 | pararg1(1,8) , |
547 | parcen3(1,8) |
548 | { |
549 | |
550 | //========================================================================= |
551 | // Traitement. + |
552 | //========================================================================= |
553 | |
554 | gp_Dir2d dirx(1.0,0.0); |
555 | Standard_Real thefirst = -100000.; |
556 | Standard_Real thelast = 100000.; |
557 | Standard_Real firstparam; |
558 | Standard_Real lastparam; |
559 | Standard_Real Tol = Abs(Tolerance); |
560 | Standard_Integer nbrcote1=0; |
561 | WellDone = Standard_False; |
562 | NbrSol = 0; |
563 | if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || |
564 | Qualified1.IsOutside() || Qualified1.IsUnqualified())) { |
9775fa61 |
565 | throw GccEnt_BadQualifier(); |
578ce4be |
566 | return; |
567 | } |
568 | TColStd_Array1OfReal cote1(1,2); |
569 | Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified(); |
570 | |
571 | if (Radius < 0.0) { |
9775fa61 |
572 | throw Standard_NegativeValue(); |
578ce4be |
573 | } |
574 | else { |
575 | if (Qualified1.IsEnclosed()) { |
576 | // =========================== |
577 | nbrcote1 = 1; |
578 | cote1(1) = Radius; |
579 | } |
580 | else if(Qualified1.IsOutside()) { |
581 | // =============================== |
582 | nbrcote1 = 1; |
583 | cote1(1) = -Radius; |
584 | } |
585 | else if(Qualified1.IsUnqualified()) { |
586 | // =================================== |
587 | nbrcote1 = 2; |
588 | cote1(1) = Radius; |
589 | cote1(2) = -Radius; |
590 | } |
591 | Geom2dInt_GInter Intp; |
592 | for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { |
593 | Handle(Geom2dAdaptor_HCurve) HCu1 = new Geom2dAdaptor_HCurve(Cu1); |
5201d3e6 |
594 | Adaptor2d_OffsetCurve C1(HCu1,cote1(jcote1)); |
595 | firstparam = Max(C1.FirstParameter(),thefirst); |
596 | lastparam = Min(C1.LastParameter(),thelast); |
597 | IntRes2d_Domain D1(C1.Value(firstparam), firstparam, Tol, |
598 | C1.Value(lastparam), lastparam, Tol); |
578ce4be |
599 | Handle(Geom2dAdaptor_HCurve) HOnCurv = new Geom2dAdaptor_HCurve(OnCurv); |
5201d3e6 |
600 | Adaptor2d_OffsetCurve C2(HOnCurv); |
601 | firstparam = Max(C2.FirstParameter(),thefirst); |
602 | lastparam = Min(C2.LastParameter(),thelast); |
603 | IntRes2d_Domain D2(C2.Value(firstparam), firstparam, Tol, |
604 | C2.Value(lastparam), lastparam, Tol); |
578ce4be |
605 | Intp.Perform(C1,D1,C2,D2,Tol,Tol); |
606 | if (Intp.IsDone()) { |
607 | if (!Intp.IsEmpty()) { |
608 | for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { |
609 | NbrSol++; |
610 | gp_Pnt2d Center(Intp.Point(i).Value()); |
611 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); |
612 | // ======================================================= |
613 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
614 | TheSame1(NbrSol) = 0; |
615 | pararg1(NbrSol) = Intp.Point(i).ParamOnFirst(); |
616 | parcen3(NbrSol) = Intp.Point(i).ParamOnSecond(); |
617 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
618 | pnttg1sol(NbrSol)); |
619 | pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol))); |
620 | pntcen3(NbrSol) = Center; |
621 | } |
622 | } |
623 | WellDone = Standard_True; |
624 | } |
625 | } |
626 | } |
627 | } |
628 | |
629 | //========================================================================= |
630 | // Cercle tangent : a un cercle Qualified1 (C1). + |
631 | // centre : sur une droite OnLine. + |
632 | // de rayon : Radius. + |
633 | // + |
634 | // On initialise le tableau de solutions cirsol ainsi que tous les + |
635 | // champs. + |
636 | // On elimine en fonction du qualifieur les cas ne presentant pas de + |
637 | // solutions. + |
638 | // On resoud l equation du second degre indiquant que le point de centre + |
639 | // recherche (xc,yc) est a une distance Radius du cercle C1 et + |
640 | // sur la droite OnLine. + |
641 | // Les solutions sont representees par les cercles : + |
642 | // - de centre Pntcen(xc,yc) + |
643 | // - de rayon Radius. + |
644 | //========================================================================= |
645 | |
646 | Geom2dGcc_Circ2dTanOnRadGeo:: |
647 | Geom2dGcc_Circ2dTanOnRadGeo (const gp_Pnt2d& Point1 , |
648 | const Geom2dAdaptor_Curve& OnCurv , |
649 | const Standard_Real Radius , |
650 | const Standard_Real Tolerance ): |
651 | |
652 | //========================================================================= |
653 | // Initialisation des champs. + |
654 | //========================================================================= |
655 | |
656 | cirsol(1,8) , |
657 | qualifier1(1,8) , |
658 | TheSame1(1,8) , |
659 | pnttg1sol(1,8) , |
660 | pntcen3(1,8) , |
661 | par1sol(1,8) , |
662 | pararg1(1,8) , |
663 | parcen3(1,8) |
664 | { |
665 | |
666 | //========================================================================= |
667 | // Traitement. + |
668 | //========================================================================= |
669 | |
670 | gp_Dir2d dirx(1.0,0.0); |
671 | Standard_Real thefirst = -100000.; |
672 | Standard_Real thelast = 100000.; |
673 | Standard_Real firstparam; |
674 | Standard_Real lastparam; |
675 | Standard_Real Tol = Abs(Tolerance); |
676 | WellDone = Standard_False; |
677 | NbrSol = 0; |
678 | |
679 | if (Radius < 0.0) { |
9775fa61 |
680 | throw Standard_NegativeValue(); |
578ce4be |
681 | } |
682 | else { |
683 | // gp_Dir2d Dir(-y1dir,x1dir); |
684 | gp_Circ2d Circ(gp_Ax2d(Point1,gp_Dir2d(1.,0.)),Radius); |
685 | IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol, |
686 | ElCLib::Value(2.*M_PI,Circ),2*M_PI,Tol); |
687 | D1.SetEquivalentParameters(0.,2.*M_PI); |
688 | firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst); |
689 | lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast); |
690 | IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol, |
691 | Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol); |
692 | Geom2dInt_TheIntConicCurveOfGInter Intp(Circ,D1,OnCurv,D2,Tol,Tol); |
693 | if (Intp.IsDone()) { |
694 | if (!Intp.IsEmpty()) { |
695 | for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { |
696 | NbrSol++; |
697 | gp_Pnt2d Center(Intp.Point(i).Value()); |
698 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); |
699 | // ======================================================= |
700 | qualifier1(NbrSol) = GccEnt_noqualifier; |
701 | TheSame1(NbrSol) = 0; |
702 | pararg1(NbrSol) = Intp.Point(i).ParamOnFirst(); |
703 | parcen3(NbrSol) = Intp.Point(i).ParamOnSecond(); |
704 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
705 | pnttg1sol(NbrSol)); |
706 | pnttg1sol(NbrSol) = Point1; |
707 | pntcen3(NbrSol) = Center; |
708 | } |
709 | WellDone = Standard_True; |
710 | } |
711 | } |
712 | } |
713 | } |
714 | |
715 | //========================================================================= |
716 | |
717 | Standard_Boolean Geom2dGcc_Circ2dTanOnRadGeo:: |
718 | IsDone () const { return WellDone; } |
719 | |
720 | Standard_Integer Geom2dGcc_Circ2dTanOnRadGeo:: |
721 | NbSolutions () const { return NbrSol; } |
722 | |
723 | gp_Circ2d Geom2dGcc_Circ2dTanOnRadGeo:: |
724 | ThisSolution (const Standard_Integer Index) const |
725 | { |
726 | |
727 | if (Index > NbrSol || Index <= 0) |
9775fa61 |
728 | throw Standard_OutOfRange(); |
578ce4be |
729 | |
730 | return cirsol(Index); |
731 | } |
732 | |
733 | void Geom2dGcc_Circ2dTanOnRadGeo:: |
734 | WhichQualifier(const Standard_Integer Index , |
735 | GccEnt_Position& Qualif1 ) const |
736 | { |
9775fa61 |
737 | if (!WellDone) { throw StdFail_NotDone(); } |
738 | else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); } |
578ce4be |
739 | else { |
740 | Qualif1 = qualifier1(Index); |
741 | } |
742 | } |
743 | |
744 | void Geom2dGcc_Circ2dTanOnRadGeo:: |
745 | Tangency1 (const Standard_Integer Index, |
746 | Standard_Real& ParSol, |
747 | Standard_Real& ParArg, |
748 | gp_Pnt2d& PntSol) const{ |
749 | if (!WellDone) { |
9775fa61 |
750 | throw StdFail_NotDone(); |
578ce4be |
751 | } |
752 | else if (Index <= 0 ||Index > NbrSol) { |
9775fa61 |
753 | throw Standard_OutOfRange(); |
578ce4be |
754 | } |
755 | else { |
756 | ParSol = par1sol(Index); |
757 | ParArg = pararg1(Index); |
758 | PntSol = gp_Pnt2d(pnttg1sol(Index)); |
759 | } |
760 | } |
761 | |
762 | void Geom2dGcc_Circ2dTanOnRadGeo:: |
763 | CenterOn3 (const Standard_Integer Index, |
764 | Standard_Real& ParArg, |
765 | gp_Pnt2d& PntSol) const { |
766 | if (!WellDone) { |
9775fa61 |
767 | throw StdFail_NotDone(); |
578ce4be |
768 | } |
769 | else if (Index <= 0 ||Index > NbrSol) { |
9775fa61 |
770 | throw Standard_OutOfRange(); |
578ce4be |
771 | } |
772 | else { |
773 | ParArg = parcen3(Index); |
774 | PntSol = pnttg1sol(Index); |
775 | } |
776 | } |
777 | |
778 | Standard_Boolean Geom2dGcc_Circ2dTanOnRadGeo:: |
779 | IsTheSame1 (const Standard_Integer Index) const |
780 | { |
9775fa61 |
781 | if (!WellDone) throw StdFail_NotDone(); |
782 | if (Index <= 0 ||Index > NbrSol) throw Standard_OutOfRange(); |
578ce4be |
783 | |
784 | if (TheSame1(Index) == 0) |
785 | return Standard_False; |
786 | |
787 | return Standard_True; |
788 | } |