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 //=========================================================================
28 #include <gp_Dir2d.hxx>
29 #include <gp_Ax2d.hxx>
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>
36 #include <GccInt_IType.hxx>
37 #include <GccInt_BCirc.hxx>
38 #include <GccInt_BLine.hxx>
39 #include <GccInt_BElips.hxx>
40 #include <GccInt_BHyper.hxx>
41 #include <IntRes2d_Domain.hxx>
42 #include <IntRes2d_IntersectionPoint.hxx>
43 #include <Standard_OutOfRange.hxx>
44 #include <StdFail_NotDone.hxx>
45 #include <TColStd_Array1OfReal.hxx>
46 #include <GccEnt_BadQualifier.hxx>
47 #include <Standard_ConstructionError.hxx>
51 GccGeo_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 ,
52 const GccEnt_QualifiedCirc& Qualified2 ,
53 const TheCurve& OnCurv ,
54 const Standard_Real Tolerance ):
70 WellDone = Standard_False;
71 Standard_Real thefirst = -100000.;
72 Standard_Real thelast = 100000.;
73 Standard_Real firstparam;
74 Standard_Real lastparam;
75 Standard_Real Tol = Abs(Tolerance);
77 TColStd_Array1OfReal Rbid(1,2);
78 TColStd_Array1OfReal RBid(1,2);
79 TColStd_Array1OfReal Radius(1,2);
80 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
81 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
82 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
83 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
84 GccEnt_BadQualifier::Raise();
87 gp_Circ2d C1 = Qualified1.Qualified();
88 gp_Circ2d C2 = Qualified2.Qualified();
89 Standard_Real R1 = C1.Radius();
90 Standard_Real R2 = C2.Radius();
92 gp_Pnt2d center1(C1.Location());
93 gp_Pnt2d center2(C2.Location());
94 GccAna_Circ2dBisec Bis(C1,C2);
96 TheIntConicCurve Intp;
97 Standard_Integer nbsolution = Bis.NbSolutions();
98 Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(OnCurv);
99 TheParGenCurve Cu2(HCu2,0.);
100 firstparam = Max(TheCurvePGTool::FirstParameter(Cu2),thefirst);
101 lastparam = Min(TheCurvePGTool::LastParameter(Cu2),thelast);
102 IntRes2d_Domain D2(TheCurvePGTool::Value(Cu2,firstparam),firstparam,Tol,
103 TheCurvePGTool::Value(Cu2,lastparam),lastparam,Tol);
104 Standard_Real Tol1 = Abs(Tolerance);
105 Standard_Real Tol2 = Tol1;
106 for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
107 Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
108 GccInt_IType type = Sol->ArcType();
112 gp_Circ2d Circ(Sol->Circle());
113 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol1,
114 ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol2);
115 D1.SetEquivalentParameters(0.,2.*M_PI);
116 Intp.Perform(Circ,D1,Cu2,D2,Tol1,Tol2);
121 gp_Elips2d Elips(Sol->Ellipse());
122 IntRes2d_Domain D1(ElCLib::Value(0.,Elips), 0.,Tol1,
123 ElCLib::Value(2.*M_PI,Elips),2.*M_PI,Tol2);
124 D1.SetEquivalentParameters(0.,2.*M_PI);
125 Intp.Perform(Elips,D1,Cu2,D2,Tol1,Tol2);
130 gp_Hypr2d Hypr(Sol->Hyperbola());
131 IntRes2d_Domain D1(ElCLib::Value(-4.,Hypr),-4.,Tol1,
132 ElCLib::Value(4.,Hypr),4.,Tol2);
133 Intp.Perform(Hypr,D1,Cu2,D2,Tol1,Tol2);
138 gp_Lin2d Line(Sol->Line());
140 Intp.Perform(Line,D1,Cu2,D2,Tol1,Tol2);
145 Standard_ConstructionError::Raise();
149 if ((!Intp.IsEmpty())) {
150 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
151 gp_Pnt2d Center(Intp.Point(j).Value());
152 Standard_Real dist1 = Center.Distance(C1.Location());
153 Standard_Real dist2 = Center.Distance(C2.Location());
154 Standard_Integer nbsol = 0;
155 Standard_Integer nnsol = 0;
158 if (Qualified1.IsEnclosed()) {
159 if (dist1-R1 < Tol) {
161 Rbid(1) = Abs(R1-dist1);
164 else if (Qualified1.IsOutside()) {
165 if (R1-dist1 < Tol) {
167 Rbid(1) = Abs(dist1-R1);
170 else if (Qualified1.IsEnclosing()) {
174 else if (Qualified1.IsUnqualified()) {
177 Rbid(1) = Abs(dist1-R1);
179 if (Qualified2.IsEnclosed() && nbsol != 0) {
180 if (dist2-R2 < Tol) {
181 RBid(1) = Abs(R2-dist2);
184 else if (Qualified2.IsOutside() && nbsol != 0) {
185 if (R2-dist2 < Tol) {
186 RBid(1) = Abs(R2-dist2);
189 else if (Qualified2.IsEnclosing() && nbsol != 0) {
192 else if (Qualified2.IsUnqualified() && nbsol != 0) {
194 RBid(2) = Abs(R2-dist2);
196 for (Standard_Integer isol = 1; isol <= nbsol ; isol++) {
197 for (Standard_Integer jsol = 1; jsol <= nbsol ; jsol++) {
198 if (Abs(Rbid(isol)-RBid(jsol)) <= Tol) {
200 Radius(nnsol) = (RBid(jsol)+Rbid(isol))/2.;
205 for (Standard_Integer k = 1 ; k <= nnsol ; k++) {
207 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
208 // ==========================================================
209 Standard_Real distcc1 = Center.Distance(center1);
210 Standard_Real distcc2 = Center.Distance(center2);
211 if (!Qualified1.IsUnqualified()) {
212 qualifier1(NbrSol) = Qualified1.Qualifier();
214 else if (Abs(distcc1+Radius(i)-R1) < Tol) {
215 qualifier1(NbrSol) = GccEnt_enclosed;
217 else if (Abs(distcc1-R1-Radius(i)) < Tol) {
218 qualifier1(NbrSol) = GccEnt_outside;
220 else { qualifier1(NbrSol) = GccEnt_enclosing; }
221 if (!Qualified2.IsUnqualified()) {
222 qualifier2(NbrSol) = Qualified2.Qualifier();
224 else if (Abs(distcc2+Radius(i)-R2) < Tol) {
225 qualifier2(NbrSol) = GccEnt_enclosed;
227 else if (Abs(distcc2-R2-Radius(i)) < Tol) {
228 qualifier2(NbrSol) = GccEnt_outside;
230 else { qualifier2(NbrSol) = GccEnt_enclosing; }
231 if (dist1 <= Tol && Abs(Radius(k)-C1.Radius()) <= Tol) {
232 TheSame1(NbrSol) = 1;
235 TheSame1(NbrSol) = 0;
236 gp_Dir2d dc1(C1.Location().XY()-Center.XY());
237 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc1.XY());
238 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
240 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
242 if (dist2 <= Tol && Abs(Radius(k)-C2.Radius()) <= Tol) {
243 TheSame2(NbrSol) = 1;
246 TheSame2(NbrSol) = 0;
247 gp_Dir2d dc2(C2.Location().XY()-Center.XY());
248 pnttg2sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc2.XY());
249 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
251 pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
253 pntcen(NbrSol) = Center;
254 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
256 WellDone = Standard_True;
265 //=========================================================================
266 // Creation d un cercle tangent a un Cercle C1 et a une Droite L2. +
267 // centre sur une courbe OnCurv. +
268 // Nous calculons les bissectrices a C1 et L2 qui nous donnent +
269 // l ensemble des lieux possibles des centres de tous les cercles +
270 // tangents a C1 et L2. +
271 // Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous +
272 // donne les points parmis lesquels nous allons choisir les solutions. +
273 // Les choix s effectuent a partir des Qualifieurs qualifiant C1 et L2. +
274 //=========================================================================
276 GccGeo_Circ2d2TanOn::
277 GccGeo_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 ,
278 const GccEnt_QualifiedLin& Qualified2 ,
279 const TheCurve& OnCurv ,
280 const Standard_Real Tolerance ):
296 WellDone = Standard_False;
297 Standard_Real thefirst = -100000.;
298 Standard_Real thelast = 100000.;
299 Standard_Real firstparam;
300 Standard_Real lastparam;
302 Standard_Real Tol = Abs(Tolerance);
303 Standard_Real Radius;
304 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
305 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
306 !(Qualified2.IsEnclosed() ||
307 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
308 GccEnt_BadQualifier::Raise();
311 gp_Dir2d dirx(1.,0.);
312 gp_Circ2d C1 = Qualified1.Qualified();
313 gp_Lin2d L2 = Qualified2.Qualified();
314 Standard_Real R1 = C1.Radius();
315 gp_Pnt2d center1(C1.Location());
316 gp_Pnt2d origin2(L2.Location());
317 gp_Dir2d dir2(L2.Direction());
318 gp_Dir2d normL2(-dir2.Y(),dir2.X());
320 GccAna_CircLin2dBisec Bis(C1,L2);
322 Standard_Real Tol1 = Abs(Tolerance);
323 Standard_Real Tol2 = Tol1;
324 TheIntConicCurve Intp;
325 Standard_Integer nbsolution = Bis.NbSolutions();
326 Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(OnCurv);
327 TheParGenCurve C2(HCu2,0.);
328 firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst);
329 lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast);
330 IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol,
331 TheCurvePGTool::Value(C2,lastparam),lastparam,Tol);
332 for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
333 Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
334 GccInt_IType type = Sol->ArcType();
338 gp_Lin2d Line(Sol->Line());
340 Intp.Perform(Line,D1,C2,D2,Tol1,Tol2);
345 gp_Parab2d Parab(Sol->Parabola());
346 IntRes2d_Domain D1(ElCLib::Value(-40,Parab),-40,Tol1,
347 ElCLib::Value(40,Parab),40,Tol1);
348 Intp.Perform(Parab,D1,C2,D2,Tol1,Tol2);
353 Standard_ConstructionError::Raise();
357 if (!Intp.IsEmpty()) {
358 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
359 gp_Pnt2d Center(Intp.Point(j).Value());
360 Standard_Real dist1 = Center.Distance(center1);
361 // Standard_Integer nbsol = 1;
362 Standard_Boolean ok = Standard_False;
363 if (Qualified1.IsEnclosed()) {
364 if (dist1-R1 < Tol) { ok = Standard_True; }
366 else if (Qualified1.IsOutside()) {
367 if (R1-dist1 < Tol) { ok = Standard_True; }
369 else if (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) {
372 Radius = L2.Distance(Center);
373 if (Qualified2.IsEnclosed() && ok) {
375 if ((((origin2.X()-Center.X())*(-dir2.Y()))+
376 ((origin2.Y()-Center.Y())*(dir2.X())))<=0){
380 else if (Qualified2.IsOutside() && ok) {
382 if ((((origin2.X()-Center.X())*(-dir2.Y()))+
383 ((origin2.Y()-Center.Y())*(dir2.X())))>=0){
387 if (Qualified1.IsEnclosing()&&dist1>Radius) { ok=Standard_False; }
390 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
391 // =======================================================
393 gp_Dir2d dc1(center1.XY()-Center.XY());
395 gp_Dir2d dc2(origin2.XY()-Center.XY());
396 Standard_Real distcc1 = Center.Distance(center1);
397 if (!Qualified1.IsUnqualified()) {
398 qualifier1(NbrSol) = Qualified1.Qualifier();
400 else if (Abs(distcc1+Radius-R1) < Tol) {
401 qualifier1(NbrSol) = GccEnt_enclosed;
403 else if (Abs(distcc1-R1-Radius) < Tol) {
404 qualifier1(NbrSol) = GccEnt_outside;
406 else { qualifier1(NbrSol) = GccEnt_enclosing; }
407 if (!Qualified2.IsUnqualified()) {
408 qualifier2(NbrSol) = Qualified2.Qualifier();
410 else if (dc2.Dot(normL2) > 0.0) {
411 qualifier2(NbrSol) = GccEnt_outside;
413 else { qualifier2(NbrSol) = GccEnt_enclosed; }
414 if (dist1 <= Tol && Abs(Radius-C1.Radius()) <= Tol) {
415 TheSame1(NbrSol) = 1;
418 TheSame1(NbrSol) = 0;
419 gp_Dir2d dc1(center1.XY()-Center.XY());
420 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius*dc1.XY());
421 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
423 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
425 TheSame2(NbrSol) = 0;
426 Standard_Real sign = dc2.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
427 dc2 = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
428 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY());
429 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
431 pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
432 pntcen(NbrSol) = Center;
433 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
437 WellDone = Standard_True;
443 //=========================================================================
444 // Creation d un cercle tant a deux Droites L1 et L2. +
445 // centre sur une courbe OnCurv. +
446 // Nous calculons les bissectrices a L1 et L2 qui nous donnent +
447 // l ensemble des lieux possibles des centres de tous les cercles +
448 // tants a L1 et L2. +
449 // Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous +
450 // donne les points parmis lesquels nous allons choisir les solutions. +
451 // Les choix s effectuent a partir des Qualifieurs qualifiant L1 et L2. +
452 //=========================================================================
454 GccGeo_Circ2d2TanOn::
455 GccGeo_Circ2d2TanOn (const GccEnt_QualifiedLin& Qualified1 ,
456 const GccEnt_QualifiedLin& Qualified2 ,
457 const TheCurve& OnCurv ,
458 const Standard_Real Tolerance ):
474 WellDone = Standard_False;
475 Standard_Real thefirst = -100000.;
476 Standard_Real thelast = 100000.;
477 Standard_Real firstparam;
478 Standard_Real lastparam;
480 if (!(Qualified1.IsEnclosed() ||
481 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
482 !(Qualified2.IsEnclosed() ||
483 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
484 GccEnt_BadQualifier::Raise();
487 Standard_Real Tol = Abs(Tolerance);
488 Standard_Real Radius=0;
489 gp_Dir2d dirx(1.,0.);
490 gp_Lin2d L1 = Qualified1.Qualified();
491 gp_Lin2d L2 = Qualified2.Qualified();
492 gp_Dir2d dir1(L1.Direction());
493 gp_Dir2d dir2(L2.Direction());
494 gp_Dir2d Dnor1(-dir1.Y(),dir1.X());
495 gp_Dir2d Dnor2(-dir2.Y(),dir2.X());
496 gp_Pnt2d origin1(L1.Location());
497 gp_Pnt2d origin2(L2.Location());
498 GccAna_Lin2dBisec Bis(L1,L2);
500 Standard_Real Tol1 = Abs(Tolerance);
501 Standard_Real Tol2 = Tol1;
502 TheIntConicCurve Intp;
503 Standard_Integer nbsolution = Bis.NbSolutions();
504 Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(OnCurv);
505 TheParGenCurve C2(HCu2,0.);
506 firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst);
507 lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast);
508 IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol,
509 TheCurvePGTool::Value(C2,lastparam),lastparam,Tol);
511 for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
512 Intp.Perform(Bis.ThisSolution(i),D1,C2,D2,Tol1,Tol2);
514 if ((!Intp.IsEmpty())) {
515 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
516 gp_Pnt2d Center(Intp.Point(j).Value());
517 Standard_Real dist1 = L1.Distance(Center);
518 Standard_Real dist2 = L2.Distance(Center);
519 // Standard_Integer nbsol = 1;
520 Standard_Boolean ok = Standard_False;
521 if (Qualified1.IsEnclosed()) {
522 if ((((origin1.X()-Center.X())*(-dir1.Y()))+
523 ((origin1.Y()-Center.Y())*(dir1.X())))<=0){
527 else if (Qualified1.IsOutside()) {
528 if ((((origin1.X()-Center.X())*(-dir1.Y()))+
529 ((origin1.Y()-Center.Y())*(dir1.X())))>=0){
533 else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
534 if (Qualified2.IsEnclosed() && ok) {
536 if ((((origin2.X()-Center.X())*(-dir2.Y()))+
537 ((origin2.Y()-Center.Y())*(dir2.X())))<=0){
539 Radius = (dist1+dist2)/2.;
542 else if (Qualified2.IsOutside() && ok) {
544 if ((((origin2.X()-Center.X())*(-dir2.Y()))+
545 ((origin2.Y()-Center.Y())*(dir2.X())))>=0){
547 Radius = (dist1+dist2)/2.;
550 else if (Qualified2.IsUnqualified() && ok) {
551 Radius = (dist1+dist2)/2.;
555 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
556 // =======================================================
557 gp_Dir2d dc1(origin1.XY()-Center.XY());
558 gp_Dir2d dc2(origin2.XY()-Center.XY());
559 if (!Qualified1.IsUnqualified()) {
560 qualifier1(NbrSol) = Qualified1.Qualifier();
562 else if (dc1.Dot(Dnor1) > 0.0) {
563 qualifier1(NbrSol) = GccEnt_outside;
565 else { qualifier1(NbrSol) = GccEnt_enclosed; }
566 if (!Qualified2.IsUnqualified()) {
567 qualifier2(NbrSol) = Qualified2.Qualifier();
569 else if (dc2.Dot(Dnor2) > 0.0) {
570 qualifier2(NbrSol) = GccEnt_outside;
572 else { qualifier2(NbrSol) = GccEnt_enclosed; }
573 TheSame1(NbrSol) = 0;
574 TheSame2(NbrSol) = 0;
575 Standard_Real sign = dc1.Dot(Dnor1);
576 dc1 = gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X()));
577 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
578 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
580 pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
581 sign = dc2.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
582 dc2 = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
583 pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY());
584 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
586 pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
587 pntcen(NbrSol) = Center;
588 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
592 WellDone = Standard_True;
598 //=========================================================================
599 // Creation d un cercle tant a un Cercle C1, passant par un point P2 +
600 // centre sur une courbe OnCurv. +
601 // Nous calculons les bissectrices a C1 et Point2 qui nous donnent +
602 // l ensemble des lieux possibles des centres de tous les cercles +
603 // tants a C1 et Point2. +
604 // Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous +
605 // donne les points parmis lesquels nous allons choisir les solutions. +
606 // Les choix s effectuent a partir des Qualifieurs qualifiant C1. +
607 //=========================================================================
609 GccGeo_Circ2d2TanOn::
610 GccGeo_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 ,
611 const gp_Pnt2d& Point2 ,
612 const TheCurve& OnCurv ,
613 const Standard_Real Tolerance ):
629 WellDone = Standard_False;
630 Standard_Real thefirst = -100000.;
631 Standard_Real thelast = 100000.;
632 Standard_Real firstparam;
633 Standard_Real lastparam;
635 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
636 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
637 GccEnt_BadQualifier::Raise();
640 Standard_Real Tol = Abs(Tolerance);
641 Standard_Real Radius;
642 gp_Dir2d dirx(1.,0.);
643 gp_Circ2d C1 = Qualified1.Qualified();
644 Standard_Real R1 = C1.Radius();
645 gp_Pnt2d center1(C1.Location());
646 GccAna_CircPnt2dBisec Bis(C1,Point2);
648 Standard_Real Tol1 = Abs(Tolerance);
649 Standard_Real Tol2 = Tol1;
650 TheIntConicCurve Intp;
651 Standard_Integer nbsolution = Bis.NbSolutions();
652 Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(OnCurv);
653 TheParGenCurve C2(HCu2,0.);
654 firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst);
655 lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast);
656 IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol,
657 TheCurvePGTool::Value(C2,lastparam),lastparam,Tol);
658 for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
659 Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
660 GccInt_IType type = Sol->ArcType();
664 gp_Circ2d Circ(Sol->Circle());
665 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol1,
666 ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol2);
667 D1.SetEquivalentParameters(0.,2.*M_PI);
668 Intp.Perform(Circ,D1,C2,D2,Tol1,Tol2);
673 gp_Lin2d Line(Sol->Line());
675 Intp.Perform(Line,D1,C2,D2,Tol1,Tol2);
680 gp_Elips2d Elips(Sol->Ellipse());
681 IntRes2d_Domain D1(ElCLib::Value(0.,Elips), 0.,Tol1,
682 ElCLib::Value(2.*M_PI,Elips),2.*M_PI,Tol2);
683 D1.SetEquivalentParameters(0.,2.*M_PI);
684 Intp.Perform(Elips,D1,C2,D2,Tol1,Tol2);
689 gp_Hypr2d Hypr(Sol->Hyperbola());
690 IntRes2d_Domain D1(ElCLib::Value(-4.,Hypr),-4.,Tol1,
691 ElCLib::Value(4.,Hypr),4.,Tol2);
692 Intp.Perform(Hypr,D1,C2,D2,Tol1,Tol2);
697 Standard_ConstructionError::Raise();
701 if ((!Intp.IsEmpty())) {
702 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
703 gp_Pnt2d Center(Intp.Point(j).Value());
704 Radius = Center.Distance(Point2);
705 Standard_Real dist1 = center1.Distance(Center);
706 // Standard_Integer nbsol = 1;
707 Standard_Boolean ok = Standard_False;
708 if (Qualified1.IsEnclosed()) {
709 if (dist1-R1 <= Tol) { ok = Standard_True; }
711 else if (Qualified1.IsOutside()) {
712 if (R1-dist1 <= Tol) { ok = Standard_True; }
714 else if (Qualified1.IsEnclosing()) { ok = Standard_True; }
715 else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
718 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
719 // =======================================================
720 Standard_Real distcc1 = Center.Distance(center1);
721 if (!Qualified1.IsUnqualified()) {
722 qualifier1(NbrSol) = Qualified1.Qualifier();
724 else if (Abs(distcc1+Radius-R1) < Tol) {
725 qualifier1(NbrSol) = GccEnt_enclosed;
727 else if (Abs(distcc1-R1-Radius) < Tol) {
728 qualifier1(NbrSol) = GccEnt_outside;
730 else { qualifier1(NbrSol) = GccEnt_enclosing; }
731 qualifier2(NbrSol) = GccEnt_noqualifier;
732 if (dist1 <= Tol && Abs(Radius-R1) <= Tol) {
733 TheSame1(NbrSol) = 1;
736 TheSame1(NbrSol) = 0;
737 gp_Dir2d dc1(center1.XY()-Center.XY());
738 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius*dc1.XY());
739 par1sol(NbrSol) = 0.;
740 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
742 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
744 TheSame2(NbrSol) = 0;
745 pnttg2sol(NbrSol) = Point2;
746 pntcen(NbrSol) = Center;
747 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
748 pararg2(NbrSol) = 0.;
749 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
754 WellDone = Standard_True;
760 //=========================================================================
761 // Creation d un cercle tant a une ligne L1, passant par un point P2 +
762 // centre sur une courbe OnCurv. +
763 // Nous calculons les bissectrices a L1 et Point2 qui nous donnent +
764 // l ensemble des lieux possibles des centres de tous les cercles +
765 // tants a L1 et passant par Point2. +
766 // Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous +
767 // donne les points parmis lesquels nous allons choisir les solutions. +
768 // Les choix s effectuent a partir des Qualifieurs qualifiant L1. +
769 //=========================================================================
771 GccGeo_Circ2d2TanOn::
772 GccGeo_Circ2d2TanOn (const GccEnt_QualifiedLin& Qualified1 ,
773 const gp_Pnt2d& Point2 ,
774 const TheCurve& OnCurv ,
775 const Standard_Real Tolerance ):
791 WellDone = Standard_False;
792 Standard_Real thefirst = -100000.;
793 Standard_Real thelast = 100000.;
794 Standard_Real firstparam;
795 Standard_Real lastparam;
796 Standard_Real Tol = Abs(Tolerance);
798 if (!(Qualified1.IsEnclosed() ||
799 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
800 GccEnt_BadQualifier::Raise();
803 gp_Dir2d dirx(1.,0.);
804 gp_Lin2d L1 = Qualified1.Qualified();
805 gp_Pnt2d origin1(L1.Location());
806 gp_Dir2d dir1(L1.Direction());
807 gp_Dir2d normal(-dir1.Y(),dir1.X());
808 GccAna_LinPnt2dBisec Bis(L1,Point2);
810 Standard_Real Tol1 = Abs(Tolerance);
811 Standard_Real Tol2 = Tol1;
812 TheIntConicCurve Intp;
813 Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(OnCurv);
814 TheParGenCurve C2(HCu2,0.);
815 firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst);
816 lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast);
817 IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol,
818 TheCurvePGTool::Value(C2,lastparam),lastparam,Tol);
819 Handle(GccInt_Bisec) Sol = Bis.ThisSolution();
820 GccInt_IType type = Sol->ArcType();
824 gp_Lin2d Line(Sol->Line());
826 Intp.Perform(Line,D1,C2,D2,Tol1,Tol2);
831 gp_Parab2d Parab(Sol->Parabola());
832 IntRes2d_Domain D1(ElCLib::Value(-40,Parab),-40,Tol1,
833 ElCLib::Value(40,Parab),40,Tol1);
834 Intp.Perform(Parab,D1,C2,D2,Tol1,Tol2);
839 Standard_ConstructionError::Raise();
843 if ((!Intp.IsEmpty())) {
844 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
845 gp_Pnt2d Center(Intp.Point(j).Value());
846 Standard_Real Radius = L1.Distance(Center);
847 // Standard_Integer nbsol = 1;
848 Standard_Boolean ok = Standard_False;
849 if (Qualified1.IsEnclosed()) {
850 if ((((origin1.X()-Center.X())*(-dir1.Y()))+
851 ((origin1.Y()-Center.Y())*(dir1.X())))<=0){
855 else if (Qualified1.IsOutside()) {
856 if ((((origin1.X()-Center.X())*(-dir1.Y()))+
857 ((origin1.Y()-Center.Y())*(dir1.X())))>=0){
861 else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
864 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
865 // =======================================================
866 qualifier2(NbrSol) = GccEnt_noqualifier;
867 gp_Dir2d dc2(origin1.XY()-Center.XY());
868 if (!Qualified1.IsUnqualified()) {
869 qualifier1(NbrSol) = Qualified1.Qualifier();
871 else if (dc2.Dot(normal) > 0.0) {
872 qualifier1(NbrSol) = GccEnt_outside;
874 else { qualifier1(NbrSol) = GccEnt_enclosed; }
875 TheSame1(NbrSol) = 0;
876 TheSame2(NbrSol) = 0;
877 gp_Dir2d dc1(origin1.XY()-Center.XY());
878 Standard_Real sign = dc1.Dot(gp_Dir2d(-dir1.Y(),dir1.X()));
879 dc1=gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X()));
880 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
881 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
883 pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
884 pnttg2sol(NbrSol) = Point2;
885 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
887 pararg2(NbrSol) = 0.;
888 pntcen(NbrSol) = Center;
889 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
893 WellDone = Standard_True;
898 //=========================================================================
899 // Creation d un cercle passant par deux point Point1 et Point2 +
900 // centre sur une courbe OnCurv. +
901 // Nous calculons les bissectrices a Point1 et Point2 qui nous donnent +
902 // l ensemble des lieux possibles des centres de tous les cercles +
903 // passant par Point1 et Point2. +
904 // Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous +
905 // donne les points parmis lesquels nous allons choisir les solutions. +
906 //=========================================================================
908 GccGeo_Circ2d2TanOn::
909 GccGeo_Circ2d2TanOn (const gp_Pnt2d& Point1 ,
910 const gp_Pnt2d& Point2 ,
911 const TheCurve& OnCurv ,
912 const Standard_Real Tolerance ):
928 WellDone = Standard_False;
929 Standard_Real thefirst = -100000.;
930 Standard_Real thelast = 100000.;
931 Standard_Real firstparam;
932 Standard_Real lastparam;
933 Standard_Real Tol = Abs(Tolerance);
935 gp_Dir2d dirx(1.,0.);
936 GccAna_Pnt2dBisec Bis(Point1,Point2);
938 Standard_Real Tol1 = Abs(Tolerance);
939 Standard_Real Tol2 = Tol1;
940 TheIntConicCurve Intp;
941 Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(OnCurv);
942 TheParGenCurve Cu2(HCu2,0.);
943 firstparam = Max(TheCurvePGTool::FirstParameter(Cu2),thefirst);
944 lastparam = Min(TheCurvePGTool::LastParameter(Cu2),thelast);
945 IntRes2d_Domain D2(TheCurvePGTool::Value(Cu2,firstparam),firstparam,Tol,
946 TheCurvePGTool::Value(Cu2,lastparam),lastparam,Tol);
948 if (Bis.HasSolution()) {
949 Intp.Perform(Bis.ThisSolution(),D1,Cu2,D2,Tol1,Tol2);
951 if ((!Intp.IsEmpty())) {
952 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
953 gp_Pnt2d Center(Intp.Point(j).Value());
954 Standard_Real Radius = Point2.Distance(Center);
956 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
957 // =======================================================
958 qualifier1(NbrSol) = GccEnt_noqualifier;
959 qualifier2(NbrSol) = GccEnt_noqualifier;
960 TheSame1(NbrSol) = 0;
961 TheSame2(NbrSol) = 0;
962 pntcen(NbrSol) = Center;
963 pnttg1sol(NbrSol) = Point1;
964 pnttg2sol(NbrSol) = Point2;
965 pararg1(NbrSol) = 0.;
966 pararg2(NbrSol) = 0.;
967 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
969 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
971 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
974 WellDone = Standard_True;
980 Standard_Boolean GccGeo_Circ2d2TanOn::
981 IsDone () const { return WellDone; }
983 Standard_Integer GccGeo_Circ2d2TanOn::
984 NbSolutions () const{ return NbrSol; }
986 gp_Circ2d GccGeo_Circ2d2TanOn::
987 ThisSolution (const Standard_Integer Index) const
989 if (!WellDone) { StdFail_NotDone::Raise(); }
990 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
992 return cirsol(Index);
995 void GccGeo_Circ2d2TanOn::
996 WhichQualifier(const Standard_Integer Index ,
997 GccEnt_Position& Qualif1 ,
998 GccEnt_Position& Qualif2 ) const
1000 if (!WellDone) { StdFail_NotDone::Raise(); }
1001 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1003 Qualif1 = qualifier1(Index);
1004 Qualif2 = qualifier2(Index);
1008 void GccGeo_Circ2d2TanOn::
1009 Tangency1 (const Standard_Integer Index ,
1010 Standard_Real& ParSol ,
1011 Standard_Real& ParArg ,
1012 gp_Pnt2d& PntSol ) const{
1013 if (!WellDone) { StdFail_NotDone::Raise(); }
1014 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1016 if (TheSame1(Index) == 0) {
1017 ParSol = par1sol(Index);
1018 ParArg = pararg1(Index);
1019 PntSol = gp_Pnt2d(pnttg1sol(Index));
1021 else { StdFail_NotDone::Raise(); }
1025 void GccGeo_Circ2d2TanOn::
1026 Tangency2 (const Standard_Integer Index ,
1027 Standard_Real& ParSol ,
1028 Standard_Real& ParArg ,
1029 gp_Pnt2d& PntSol ) const{
1030 if (!WellDone) { StdFail_NotDone::Raise(); }
1031 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1033 if (TheSame2(Index) == 0) {
1034 ParSol = par2sol(Index);
1035 ParArg = pararg2(Index);
1036 PntSol = gp_Pnt2d(pnttg2sol(Index));
1038 else { StdFail_NotDone::Raise(); }
1042 void GccGeo_Circ2d2TanOn::
1043 CenterOn3 (const Standard_Integer Index ,
1044 Standard_Real& ParArg ,
1045 gp_Pnt2d& PntSol ) const{
1046 if (!WellDone) { StdFail_NotDone::Raise(); }
1047 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1049 ParArg = parcen3(Index);
1050 PntSol = gp_Pnt2d(pntcen(Index));
1054 Standard_Boolean GccGeo_Circ2d2TanOn::
1055 IsTheSame1 (const Standard_Integer Index) const
1057 if (!WellDone) StdFail_NotDone::Raise();
1058 if (Index <= 0 ||Index > NbrSol) Standard_OutOfRange::Raise();
1060 if (TheSame1(Index) == 0)
1061 return Standard_False;
1063 return Standard_True;
1067 Standard_Boolean GccGeo_Circ2d2TanOn::
1068 IsTheSame2 (const Standard_Integer Index) const
1070 if (!WellDone) StdFail_NotDone::Raise();
1071 if (Index <= 0 ||Index > NbrSol) Standard_OutOfRange::Raise();
1073 if (TheSame2(Index) == 0)
1074 return Standard_False;
1076 return Standard_True;