1 // Created on: 1991-12-13
2 // Created by: Remi GILET
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 //=========================================================================
18 // Creation d un cercle tangent a deux elements : Droite. +
22 // centre sur un troisieme : Droite. +
25 //=========================================================================
27 #include <Geom2dGcc_Circ2d2TanOnGeo.ixx>
30 #include <GccAna_Circ2dBisec.hxx>
31 #include <GccAna_CircLin2dBisec.hxx>
32 #include <GccAna_Lin2dBisec.hxx>
33 #include <GccAna_CircPnt2dBisec.hxx>
34 #include <GccAna_LinPnt2dBisec.hxx>
35 #include <GccAna_Pnt2dBisec.hxx>
37 #include <GccInt_BHyper.hxx>
38 #include <IntRes2d_IntersectionPoint.hxx>
40 #include <Standard_OutOfRange.hxx>
41 #include <StdFail_NotDone.hxx>
43 #include <Adaptor3d_OffsetCurve.hxx>
44 #include <Geom2dAdaptor_HCurve.hxx>
45 #include <Geom2dGcc_CurveToolGeo.hxx>
46 #include <Geom2dInt_TheIntConicCurveOfGInter.hxx>
48 Geom2dGcc_Circ2d2TanOnGeo::
49 Geom2dGcc_Circ2d2TanOnGeo (const GccEnt_QualifiedCirc& Qualified1 ,
50 const GccEnt_QualifiedCirc& Qualified2 ,
51 const Geom2dAdaptor_Curve& OnCurv ,
52 const Standard_Real Tolerance ):
67 WellDone = Standard_False;
68 Standard_Real thefirst = -100000.;
69 Standard_Real thelast = 100000.;
70 Standard_Real firstparam;
71 Standard_Real lastparam;
72 Standard_Real Tol = Abs(Tolerance);
74 TColStd_Array1OfReal Rbid(1,2);
75 TColStd_Array1OfReal RBid(1,2);
76 TColStd_Array1OfReal Radius(1,2);
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();
84 gp_Circ2d C1 = Qualified1.Qualified();
85 gp_Circ2d C2 = Qualified2.Qualified();
86 Standard_Real R1 = C1.Radius();
87 Standard_Real R2 = C2.Radius();
89 gp_Pnt2d center1(C1.Location());
90 gp_Pnt2d center2(C2.Location());
91 GccAna_Circ2dBisec Bis(C1,C2);
93 Geom2dInt_TheIntConicCurveOfGInter Intp;
94 Standard_Integer nbsolution = Bis.NbSolutions();
95 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv);
96 Adaptor3d_OffsetCurve Cu2(HCu2,0.);
97 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(Cu2),thefirst);
98 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(Cu2),thelast);
99 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(Cu2,firstparam),firstparam,Tol,
100 Geom2dGcc_CurveToolGeo::Value(Cu2,lastparam),lastparam,Tol);
101 Standard_Real Tol1 = Abs(Tolerance);
102 Standard_Real Tol2 = Tol1;
103 for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
104 Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
105 GccInt_IType type = Sol->ArcType();
109 gp_Circ2d Circ(Sol->Circle());
110 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol1,
111 ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol2);
112 D1.SetEquivalentParameters(0.,2.*M_PI);
113 Intp.Perform(Circ,D1,Cu2,D2,Tol1,Tol2);
118 gp_Elips2d Elips(Sol->Ellipse());
119 IntRes2d_Domain D1(ElCLib::Value(0.,Elips), 0.,Tol1,
120 ElCLib::Value(2.*M_PI,Elips),2.*M_PI,Tol2);
121 D1.SetEquivalentParameters(0.,2.*M_PI);
122 Intp.Perform(Elips,D1,Cu2,D2,Tol1,Tol2);
127 gp_Hypr2d Hypr(Sol->Hyperbola());
128 IntRes2d_Domain D1(ElCLib::Value(-4.,Hypr),-4.,Tol1,
129 ElCLib::Value(4.,Hypr),4.,Tol2);
130 Intp.Perform(Hypr,D1,Cu2,D2,Tol1,Tol2);
135 gp_Lin2d Line(Sol->Line());
137 Intp.Perform(Line,D1,Cu2,D2,Tol1,Tol2);
142 Standard_ConstructionError::Raise();
146 if ((!Intp.IsEmpty())) {
147 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
148 gp_Pnt2d Center(Intp.Point(j).Value());
149 Standard_Real dist1 = Center.Distance(C1.Location());
150 Standard_Real dist2 = Center.Distance(C2.Location());
151 Standard_Integer nbsol = 0;
152 Standard_Integer nnsol = 0;
155 if (Qualified1.IsEnclosed()) {
156 if (dist1-R1 < Tol) {
158 Rbid(1) = Abs(R1-dist1);
161 else if (Qualified1.IsOutside()) {
162 if (R1-dist1 < Tol) {
164 Rbid(1) = Abs(dist1-R1);
167 else if (Qualified1.IsEnclosing()) {
171 else if (Qualified1.IsUnqualified()) {
174 Rbid(1) = Abs(dist1-R1);
176 if (Qualified2.IsEnclosed() && nbsol != 0) {
177 if (dist2-R2 < Tol) {
178 RBid(1) = Abs(R2-dist2);
181 else if (Qualified2.IsOutside() && nbsol != 0) {
182 if (R2-dist2 < Tol) {
183 RBid(1) = Abs(R2-dist2);
186 else if (Qualified2.IsEnclosing() && nbsol != 0) {
189 else if (Qualified2.IsUnqualified() && nbsol != 0) {
191 RBid(2) = Abs(R2-dist2);
193 for (Standard_Integer isol = 1; isol <= nbsol ; isol++) {
194 for (Standard_Integer jsol = 1; jsol <= nbsol ; jsol++) {
195 if (Abs(Rbid(isol)-RBid(jsol)) <= Tol) {
197 Radius(nnsol) = (RBid(jsol)+Rbid(isol))/2.;
202 for (Standard_Integer k = 1 ; k <= nnsol ; k++) {
204 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
205 // ==========================================================
206 Standard_Real distcc1 = Center.Distance(center1);
207 Standard_Real distcc2 = Center.Distance(center2);
208 if (!Qualified1.IsUnqualified()) {
209 qualifier1(NbrSol) = Qualified1.Qualifier();
211 else if (Abs(distcc1+Radius(i)-R1) < Tol) {
212 qualifier1(NbrSol) = GccEnt_enclosed;
214 else if (Abs(distcc1-R1-Radius(i)) < Tol) {
215 qualifier1(NbrSol) = GccEnt_outside;
217 else { qualifier1(NbrSol) = GccEnt_enclosing; }
218 if (!Qualified2.IsUnqualified()) {
219 qualifier2(NbrSol) = Qualified2.Qualifier();
221 else if (Abs(distcc2+Radius(i)-R2) < Tol) {
222 qualifier2(NbrSol) = GccEnt_enclosed;
224 else if (Abs(distcc2-R2-Radius(i)) < Tol) {
225 qualifier2(NbrSol) = GccEnt_outside;
227 else { qualifier2(NbrSol) = GccEnt_enclosing; }
228 if (dist1 <= Tol && Abs(Radius(k)-C1.Radius()) <= Tol) {
229 TheSame1(NbrSol) = 1;
232 TheSame1(NbrSol) = 0;
233 gp_Dir2d dc1(C1.Location().XY()-Center.XY());
234 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc1.XY());
235 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
237 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
239 if (dist2 <= Tol && Abs(Radius(k)-C2.Radius()) <= Tol) {
240 TheSame2(NbrSol) = 1;
243 TheSame2(NbrSol) = 0;
244 gp_Dir2d dc2(C2.Location().XY()-Center.XY());
245 pnttg2sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc2.XY());
246 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
248 pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
250 pntcen(NbrSol) = Center;
251 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
253 WellDone = Standard_True;
262 //=========================================================================
263 // Creation d un cercle tangent a un Cercle C1 et a une Droite L2. +
264 // centre sur une courbe OnCurv. +
265 // Nous calculons les bissectrices a C1 et L2 qui nous donnent +
266 // l ensemble des lieux possibles des centres de tous les cercles +
267 // tangents a C1 et L2. +
268 // Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous +
269 // donne les points parmis lesquels nous allons choisir les solutions. +
270 // Les choix s effectuent a partir des Qualifieurs qualifiant C1 et L2. +
271 //=========================================================================
273 Geom2dGcc_Circ2d2TanOnGeo::
274 Geom2dGcc_Circ2d2TanOnGeo (const GccEnt_QualifiedCirc& Qualified1 ,
275 const GccEnt_QualifiedLin& Qualified2 ,
276 const Geom2dAdaptor_Curve& OnCurv ,
277 const Standard_Real Tolerance ):
293 WellDone = Standard_False;
294 Standard_Real thefirst = -100000.;
295 Standard_Real thelast = 100000.;
296 Standard_Real firstparam;
297 Standard_Real lastparam;
299 Standard_Real Tol = Abs(Tolerance);
300 Standard_Real Radius;
301 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
302 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
303 !(Qualified2.IsEnclosed() ||
304 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
305 GccEnt_BadQualifier::Raise();
308 gp_Dir2d dirx(1.,0.);
309 gp_Circ2d C1 = Qualified1.Qualified();
310 gp_Lin2d L2 = Qualified2.Qualified();
311 Standard_Real R1 = C1.Radius();
312 gp_Pnt2d center1(C1.Location());
313 gp_Pnt2d origin2(L2.Location());
314 gp_Dir2d dir2(L2.Direction());
315 gp_Dir2d normL2(-dir2.Y(),dir2.X());
317 GccAna_CircLin2dBisec Bis(C1,L2);
319 Standard_Real Tol1 = Abs(Tolerance);
320 Standard_Real Tol2 = Tol1;
321 Geom2dInt_TheIntConicCurveOfGInter Intp;
322 Standard_Integer nbsolution = Bis.NbSolutions();
323 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv);
324 Adaptor3d_OffsetCurve C2(HCu2,0.);
325 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
326 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
327 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
328 Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
329 for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
330 Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
331 GccInt_IType type = Sol->ArcType();
335 gp_Lin2d Line(Sol->Line());
337 Intp.Perform(Line,D1,C2,D2,Tol1,Tol2);
342 gp_Parab2d Parab(Sol->Parabola());
343 IntRes2d_Domain D1(ElCLib::Value(-40,Parab),-40,Tol1,
344 ElCLib::Value(40,Parab),40,Tol1);
345 Intp.Perform(Parab,D1,C2,D2,Tol1,Tol2);
350 Standard_ConstructionError::Raise();
354 if (!Intp.IsEmpty()) {
355 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
356 gp_Pnt2d Center(Intp.Point(j).Value());
357 Standard_Real dist1 = Center.Distance(center1);
358 // Standard_Integer nbsol = 1;
359 Standard_Boolean ok = Standard_False;
360 if (Qualified1.IsEnclosed()) {
361 if (dist1-R1 < Tol) { ok = Standard_True; }
363 else if (Qualified1.IsOutside()) {
364 if (R1-dist1 < Tol) { ok = Standard_True; }
366 else if (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) {
369 Radius = L2.Distance(Center);
370 if (Qualified2.IsEnclosed() && ok) {
372 if ((((origin2.X()-Center.X())*(-dir2.Y()))+
373 ((origin2.Y()-Center.Y())*(dir2.X())))<=0){
377 else if (Qualified2.IsOutside() && ok) {
379 if ((((origin2.X()-Center.X())*(-dir2.Y()))+
380 ((origin2.Y()-Center.Y())*(dir2.X())))>=0){
384 if (Qualified1.IsEnclosing()&&dist1>Radius) { ok=Standard_False; }
387 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
388 // =======================================================
390 gp_Dir2d dc1(center1.XY()-Center.XY());
392 gp_Dir2d dc2(origin2.XY()-Center.XY());
393 Standard_Real distcc1 = Center.Distance(center1);
394 if (!Qualified1.IsUnqualified()) {
395 qualifier1(NbrSol) = Qualified1.Qualifier();
397 else if (Abs(distcc1+Radius-R1) < Tol) {
398 qualifier1(NbrSol) = GccEnt_enclosed;
400 else if (Abs(distcc1-R1-Radius) < Tol) {
401 qualifier1(NbrSol) = GccEnt_outside;
403 else { qualifier1(NbrSol) = GccEnt_enclosing; }
404 if (!Qualified2.IsUnqualified()) {
405 qualifier2(NbrSol) = Qualified2.Qualifier();
407 else if (dc2.Dot(normL2) > 0.0) {
408 qualifier2(NbrSol) = GccEnt_outside;
410 else { qualifier2(NbrSol) = GccEnt_enclosed; }
411 if (dist1 <= Tol && Abs(Radius-C1.Radius()) <= Tol) {
412 TheSame1(NbrSol) = 1;
415 TheSame1(NbrSol) = 0;
416 gp_Dir2d dc1(center1.XY()-Center.XY());
417 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius*dc1.XY());
418 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
420 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
422 TheSame2(NbrSol) = 0;
423 Standard_Real sign = dc2.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
424 dc2 = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
425 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY());
426 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
428 pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
429 pntcen(NbrSol) = Center;
430 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
434 WellDone = Standard_True;
440 //=========================================================================
441 // Creation d un cercle tant a deux Droites L1 et L2. +
442 // centre sur une courbe OnCurv. +
443 // Nous calculons les bissectrices a L1 et L2 qui nous donnent +
444 // l ensemble des lieux possibles des centres de tous les cercles +
445 // tants a L1 et L2. +
446 // Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous +
447 // donne les points parmis lesquels nous allons choisir les solutions. +
448 // Les choix s effectuent a partir des Qualifieurs qualifiant L1 et L2. +
449 //=========================================================================
451 Geom2dGcc_Circ2d2TanOnGeo::
452 Geom2dGcc_Circ2d2TanOnGeo (const GccEnt_QualifiedLin& Qualified1 ,
453 const GccEnt_QualifiedLin& Qualified2 ,
454 const Geom2dAdaptor_Curve& OnCurv ,
455 const Standard_Real Tolerance ):
471 WellDone = Standard_False;
472 Standard_Real thefirst = -100000.;
473 Standard_Real thelast = 100000.;
474 Standard_Real firstparam;
475 Standard_Real lastparam;
477 if (!(Qualified1.IsEnclosed() ||
478 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
479 !(Qualified2.IsEnclosed() ||
480 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
481 GccEnt_BadQualifier::Raise();
484 Standard_Real Tol = Abs(Tolerance);
485 Standard_Real Radius=0;
486 gp_Dir2d dirx(1.,0.);
487 gp_Lin2d L1 = Qualified1.Qualified();
488 gp_Lin2d L2 = Qualified2.Qualified();
489 gp_Dir2d dir1(L1.Direction());
490 gp_Dir2d dir2(L2.Direction());
491 gp_Dir2d Dnor1(-dir1.Y(),dir1.X());
492 gp_Dir2d Dnor2(-dir2.Y(),dir2.X());
493 gp_Pnt2d origin1(L1.Location());
494 gp_Pnt2d origin2(L2.Location());
495 GccAna_Lin2dBisec Bis(L1,L2);
497 Standard_Real Tol1 = Abs(Tolerance);
498 Standard_Real Tol2 = Tol1;
499 Geom2dInt_TheIntConicCurveOfGInter Intp;
500 Standard_Integer nbsolution = Bis.NbSolutions();
501 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv);
502 Adaptor3d_OffsetCurve C2(HCu2,0.);
503 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
504 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
505 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
506 Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
508 for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
509 Intp.Perform(Bis.ThisSolution(i),D1,C2,D2,Tol1,Tol2);
511 if ((!Intp.IsEmpty())) {
512 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
513 gp_Pnt2d Center(Intp.Point(j).Value());
514 Standard_Real dist1 = L1.Distance(Center);
515 Standard_Real dist2 = L2.Distance(Center);
516 // Standard_Integer nbsol = 1;
517 Standard_Boolean ok = Standard_False;
518 if (Qualified1.IsEnclosed()) {
519 if ((((origin1.X()-Center.X())*(-dir1.Y()))+
520 ((origin1.Y()-Center.Y())*(dir1.X())))<=0){
524 else if (Qualified1.IsOutside()) {
525 if ((((origin1.X()-Center.X())*(-dir1.Y()))+
526 ((origin1.Y()-Center.Y())*(dir1.X())))>=0){
530 else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
531 if (Qualified2.IsEnclosed() && ok) {
533 if ((((origin2.X()-Center.X())*(-dir2.Y()))+
534 ((origin2.Y()-Center.Y())*(dir2.X())))<=0){
536 Radius = (dist1+dist2)/2.;
539 else if (Qualified2.IsOutside() && ok) {
541 if ((((origin2.X()-Center.X())*(-dir2.Y()))+
542 ((origin2.Y()-Center.Y())*(dir2.X())))>=0){
544 Radius = (dist1+dist2)/2.;
547 else if (Qualified2.IsUnqualified() && ok) {
548 Radius = (dist1+dist2)/2.;
552 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
553 // =======================================================
554 gp_Dir2d dc1(origin1.XY()-Center.XY());
555 gp_Dir2d dc2(origin2.XY()-Center.XY());
556 if (!Qualified1.IsUnqualified()) {
557 qualifier1(NbrSol) = Qualified1.Qualifier();
559 else if (dc1.Dot(Dnor1) > 0.0) {
560 qualifier1(NbrSol) = GccEnt_outside;
562 else { qualifier1(NbrSol) = GccEnt_enclosed; }
563 if (!Qualified2.IsUnqualified()) {
564 qualifier2(NbrSol) = Qualified2.Qualifier();
566 else if (dc2.Dot(Dnor2) > 0.0) {
567 qualifier2(NbrSol) = GccEnt_outside;
569 else { qualifier2(NbrSol) = GccEnt_enclosed; }
570 TheSame1(NbrSol) = 0;
571 TheSame2(NbrSol) = 0;
572 Standard_Real sign = dc1.Dot(Dnor1);
573 dc1 = gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X()));
574 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
575 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
577 pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
578 sign = dc2.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
579 dc2 = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
580 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY());
581 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
583 pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
584 pntcen(NbrSol) = Center;
585 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
589 WellDone = Standard_True;
595 //=========================================================================
596 // Creation d un cercle tant a un Cercle C1, passant par un point P2 +
597 // centre sur une courbe OnCurv. +
598 // Nous calculons les bissectrices a C1 et Point2 qui nous donnent +
599 // l ensemble des lieux possibles des centres de tous les cercles +
600 // tants a C1 et Point2. +
601 // Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous +
602 // donne les points parmis lesquels nous allons choisir les solutions. +
603 // Les choix s effectuent a partir des Qualifieurs qualifiant C1. +
604 //=========================================================================
606 Geom2dGcc_Circ2d2TanOnGeo::
607 Geom2dGcc_Circ2d2TanOnGeo (const GccEnt_QualifiedCirc& Qualified1 ,
608 const gp_Pnt2d& Point2 ,
609 const Geom2dAdaptor_Curve& OnCurv ,
610 const Standard_Real Tolerance ):
626 WellDone = Standard_False;
627 Standard_Real thefirst = -100000.;
628 Standard_Real thelast = 100000.;
629 Standard_Real firstparam;
630 Standard_Real lastparam;
632 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
633 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
634 GccEnt_BadQualifier::Raise();
637 Standard_Real Tol = Abs(Tolerance);
638 Standard_Real Radius;
639 gp_Dir2d dirx(1.,0.);
640 gp_Circ2d C1 = Qualified1.Qualified();
641 Standard_Real R1 = C1.Radius();
642 gp_Pnt2d center1(C1.Location());
643 GccAna_CircPnt2dBisec Bis(C1,Point2);
645 Standard_Real Tol1 = Abs(Tolerance);
646 Standard_Real Tol2 = Tol1;
647 Geom2dInt_TheIntConicCurveOfGInter Intp;
648 Standard_Integer nbsolution = Bis.NbSolutions();
649 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv);
650 Adaptor3d_OffsetCurve C2(HCu2,0.);
651 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
652 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
653 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
654 Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
655 for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
656 Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
657 GccInt_IType type = Sol->ArcType();
661 gp_Circ2d Circ(Sol->Circle());
662 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol1,
663 ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol2);
664 D1.SetEquivalentParameters(0.,2.*M_PI);
665 Intp.Perform(Circ,D1,C2,D2,Tol1,Tol2);
670 gp_Lin2d Line(Sol->Line());
672 Intp.Perform(Line,D1,C2,D2,Tol1,Tol2);
677 gp_Elips2d Elips(Sol->Ellipse());
678 IntRes2d_Domain D1(ElCLib::Value(0.,Elips), 0.,Tol1,
679 ElCLib::Value(2.*M_PI,Elips),2.*M_PI,Tol2);
680 D1.SetEquivalentParameters(0.,2.*M_PI);
681 Intp.Perform(Elips,D1,C2,D2,Tol1,Tol2);
686 gp_Hypr2d Hypr(Sol->Hyperbola());
687 IntRes2d_Domain D1(ElCLib::Value(-4.,Hypr),-4.,Tol1,
688 ElCLib::Value(4.,Hypr),4.,Tol2);
689 Intp.Perform(Hypr,D1,C2,D2,Tol1,Tol2);
694 Standard_ConstructionError::Raise();
698 if ((!Intp.IsEmpty())) {
699 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
700 gp_Pnt2d Center(Intp.Point(j).Value());
701 Radius = Center.Distance(Point2);
702 Standard_Real dist1 = center1.Distance(Center);
703 // Standard_Integer nbsol = 1;
704 Standard_Boolean ok = Standard_False;
705 if (Qualified1.IsEnclosed()) {
706 if (dist1-R1 <= Tol) { ok = Standard_True; }
708 else if (Qualified1.IsOutside()) {
709 if (R1-dist1 <= Tol) { ok = Standard_True; }
711 else if (Qualified1.IsEnclosing()) { ok = Standard_True; }
712 else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
715 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
716 // =======================================================
717 Standard_Real distcc1 = Center.Distance(center1);
718 if (!Qualified1.IsUnqualified()) {
719 qualifier1(NbrSol) = Qualified1.Qualifier();
721 else if (Abs(distcc1+Radius-R1) < Tol) {
722 qualifier1(NbrSol) = GccEnt_enclosed;
724 else if (Abs(distcc1-R1-Radius) < Tol) {
725 qualifier1(NbrSol) = GccEnt_outside;
727 else { qualifier1(NbrSol) = GccEnt_enclosing; }
728 qualifier2(NbrSol) = GccEnt_noqualifier;
729 if (dist1 <= Tol && Abs(Radius-R1) <= Tol) {
730 TheSame1(NbrSol) = 1;
733 TheSame1(NbrSol) = 0;
734 gp_Dir2d dc1(center1.XY()-Center.XY());
735 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius*dc1.XY());
736 par1sol(NbrSol) = 0.;
737 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
739 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
741 TheSame2(NbrSol) = 0;
742 pnttg2sol(NbrSol) = Point2;
743 pntcen(NbrSol) = Center;
744 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
745 pararg2(NbrSol) = 0.;
746 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
751 WellDone = Standard_True;
757 //=========================================================================
758 // Creation d un cercle tant a une ligne L1, passant par un point P2 +
759 // centre sur une courbe OnCurv. +
760 // Nous calculons les bissectrices a L1 et Point2 qui nous donnent +
761 // l ensemble des lieux possibles des centres de tous les cercles +
762 // tants a L1 et passant par Point2. +
763 // Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous +
764 // donne les points parmis lesquels nous allons choisir les solutions. +
765 // Les choix s effectuent a partir des Qualifieurs qualifiant L1. +
766 //=========================================================================
768 Geom2dGcc_Circ2d2TanOnGeo::
769 Geom2dGcc_Circ2d2TanOnGeo (const GccEnt_QualifiedLin& Qualified1 ,
770 const gp_Pnt2d& Point2 ,
771 const Geom2dAdaptor_Curve& OnCurv ,
772 const Standard_Real Tolerance ):
788 WellDone = Standard_False;
789 Standard_Real thefirst = -100000.;
790 Standard_Real thelast = 100000.;
791 Standard_Real firstparam;
792 Standard_Real lastparam;
793 Standard_Real Tol = Abs(Tolerance);
795 if (!(Qualified1.IsEnclosed() ||
796 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
797 GccEnt_BadQualifier::Raise();
800 gp_Dir2d dirx(1.,0.);
801 gp_Lin2d L1 = Qualified1.Qualified();
802 gp_Pnt2d origin1(L1.Location());
803 gp_Dir2d dir1(L1.Direction());
804 gp_Dir2d normal(-dir1.Y(),dir1.X());
805 GccAna_LinPnt2dBisec Bis(L1,Point2);
807 Standard_Real Tol1 = Abs(Tolerance);
808 Standard_Real Tol2 = Tol1;
809 Geom2dInt_TheIntConicCurveOfGInter Intp;
810 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv);
811 Adaptor3d_OffsetCurve C2(HCu2,0.);
812 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
813 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
814 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
815 Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
816 Handle(GccInt_Bisec) Sol = Bis.ThisSolution();
817 GccInt_IType type = Sol->ArcType();
821 gp_Lin2d Line(Sol->Line());
823 Intp.Perform(Line,D1,C2,D2,Tol1,Tol2);
828 gp_Parab2d Parab(Sol->Parabola());
829 IntRes2d_Domain D1(ElCLib::Value(-40,Parab),-40,Tol1,
830 ElCLib::Value(40,Parab),40,Tol1);
831 Intp.Perform(Parab,D1,C2,D2,Tol1,Tol2);
836 Standard_ConstructionError::Raise();
840 if ((!Intp.IsEmpty())) {
841 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
842 gp_Pnt2d Center(Intp.Point(j).Value());
843 Standard_Real Radius = L1.Distance(Center);
844 // Standard_Integer nbsol = 1;
845 Standard_Boolean ok = Standard_False;
846 if (Qualified1.IsEnclosed()) {
847 if ((((origin1.X()-Center.X())*(-dir1.Y()))+
848 ((origin1.Y()-Center.Y())*(dir1.X())))<=0){
852 else if (Qualified1.IsOutside()) {
853 if ((((origin1.X()-Center.X())*(-dir1.Y()))+
854 ((origin1.Y()-Center.Y())*(dir1.X())))>=0){
858 else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
861 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
862 // =======================================================
863 qualifier2(NbrSol) = GccEnt_noqualifier;
864 gp_Dir2d dc2(origin1.XY()-Center.XY());
865 if (!Qualified1.IsUnqualified()) {
866 qualifier1(NbrSol) = Qualified1.Qualifier();
868 else if (dc2.Dot(normal) > 0.0) {
869 qualifier1(NbrSol) = GccEnt_outside;
871 else { qualifier1(NbrSol) = GccEnt_enclosed; }
872 TheSame1(NbrSol) = 0;
873 TheSame2(NbrSol) = 0;
874 gp_Dir2d dc1(origin1.XY()-Center.XY());
875 Standard_Real sign = dc1.Dot(gp_Dir2d(-dir1.Y(),dir1.X()));
876 dc1=gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X()));
877 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
878 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
880 pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
881 pnttg2sol(NbrSol) = Point2;
882 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
884 pararg2(NbrSol) = 0.;
885 pntcen(NbrSol) = Center;
886 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
890 WellDone = Standard_True;
895 //=========================================================================
896 // Creation d un cercle passant par deux point Point1 et Point2 +
897 // centre sur une courbe OnCurv. +
898 // Nous calculons les bissectrices a Point1 et Point2 qui nous donnent +
899 // l ensemble des lieux possibles des centres de tous les cercles +
900 // passant par Point1 et Point2. +
901 // Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous +
902 // donne les points parmis lesquels nous allons choisir les solutions. +
903 //=========================================================================
905 Geom2dGcc_Circ2d2TanOnGeo::
906 Geom2dGcc_Circ2d2TanOnGeo (const gp_Pnt2d& Point1 ,
907 const gp_Pnt2d& Point2 ,
908 const Geom2dAdaptor_Curve& OnCurv ,
909 const Standard_Real Tolerance ):
925 WellDone = Standard_False;
926 Standard_Real thefirst = -100000.;
927 Standard_Real thelast = 100000.;
928 Standard_Real firstparam;
929 Standard_Real lastparam;
930 Standard_Real Tol = Abs(Tolerance);
932 gp_Dir2d dirx(1.,0.);
933 GccAna_Pnt2dBisec Bis(Point1,Point2);
935 Standard_Real Tol1 = Abs(Tolerance);
936 Standard_Real Tol2 = Tol1;
937 Geom2dInt_TheIntConicCurveOfGInter Intp;
938 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv);
939 Adaptor3d_OffsetCurve Cu2(HCu2,0.);
940 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(Cu2),thefirst);
941 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(Cu2),thelast);
942 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(Cu2,firstparam),firstparam,Tol,
943 Geom2dGcc_CurveToolGeo::Value(Cu2,lastparam),lastparam,Tol);
945 if (Bis.HasSolution()) {
946 Intp.Perform(Bis.ThisSolution(),D1,Cu2,D2,Tol1,Tol2);
948 if ((!Intp.IsEmpty())) {
949 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
950 gp_Pnt2d Center(Intp.Point(j).Value());
951 Standard_Real Radius = Point2.Distance(Center);
953 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
954 // =======================================================
955 qualifier1(NbrSol) = GccEnt_noqualifier;
956 qualifier2(NbrSol) = GccEnt_noqualifier;
957 TheSame1(NbrSol) = 0;
958 TheSame2(NbrSol) = 0;
959 pntcen(NbrSol) = Center;
960 pnttg1sol(NbrSol) = Point1;
961 pnttg2sol(NbrSol) = Point2;
962 pararg1(NbrSol) = 0.;
963 pararg2(NbrSol) = 0.;
964 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
966 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
968 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
971 WellDone = Standard_True;
977 Standard_Boolean Geom2dGcc_Circ2d2TanOnGeo::
978 IsDone () const { return WellDone; }
980 Standard_Integer Geom2dGcc_Circ2d2TanOnGeo::
981 NbSolutions () const{ return NbrSol; }
983 gp_Circ2d Geom2dGcc_Circ2d2TanOnGeo::
984 ThisSolution (const Standard_Integer Index) const
986 if (!WellDone) { StdFail_NotDone::Raise(); }
987 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
989 return cirsol(Index);
992 void Geom2dGcc_Circ2d2TanOnGeo::
993 WhichQualifier(const Standard_Integer Index ,
994 GccEnt_Position& Qualif1 ,
995 GccEnt_Position& Qualif2 ) const
997 if (!WellDone) { StdFail_NotDone::Raise(); }
998 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1000 Qualif1 = qualifier1(Index);
1001 Qualif2 = qualifier2(Index);
1005 void Geom2dGcc_Circ2d2TanOnGeo::
1006 Tangency1 (const Standard_Integer Index ,
1007 Standard_Real& ParSol ,
1008 Standard_Real& ParArg ,
1009 gp_Pnt2d& PntSol ) const{
1010 if (!WellDone) { StdFail_NotDone::Raise(); }
1011 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1013 if (TheSame1(Index) == 0) {
1014 ParSol = par1sol(Index);
1015 ParArg = pararg1(Index);
1016 PntSol = gp_Pnt2d(pnttg1sol(Index));
1018 else { StdFail_NotDone::Raise(); }
1022 void Geom2dGcc_Circ2d2TanOnGeo::
1023 Tangency2 (const Standard_Integer Index ,
1024 Standard_Real& ParSol ,
1025 Standard_Real& ParArg ,
1026 gp_Pnt2d& PntSol ) const{
1027 if (!WellDone) { StdFail_NotDone::Raise(); }
1028 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1030 if (TheSame2(Index) == 0) {
1031 ParSol = par2sol(Index);
1032 ParArg = pararg2(Index);
1033 PntSol = gp_Pnt2d(pnttg2sol(Index));
1035 else { StdFail_NotDone::Raise(); }
1039 void Geom2dGcc_Circ2d2TanOnGeo::
1040 CenterOn3 (const Standard_Integer Index ,
1041 Standard_Real& ParArg ,
1042 gp_Pnt2d& PntSol ) const{
1043 if (!WellDone) { StdFail_NotDone::Raise(); }
1044 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1046 ParArg = parcen3(Index);
1047 PntSol = gp_Pnt2d(pntcen(Index));
1051 Standard_Boolean Geom2dGcc_Circ2d2TanOnGeo::
1052 IsTheSame1 (const Standard_Integer Index) const
1054 if (!WellDone) StdFail_NotDone::Raise();
1055 if (Index <= 0 ||Index > NbrSol) Standard_OutOfRange::Raise();
1057 if (TheSame1(Index) == 0)
1058 return Standard_False;
1060 return Standard_True;
1064 Standard_Boolean Geom2dGcc_Circ2d2TanOnGeo::
1065 IsTheSame2 (const Standard_Integer Index) const
1067 if (!WellDone) StdFail_NotDone::Raise();
1068 if (Index <= 0 ||Index > NbrSol) Standard_OutOfRange::Raise();
1070 if (TheSame2(Index) == 0)
1071 return Standard_False;
1073 return Standard_True;