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