1 // file GccAna_Circ2dTanOnRad_2.cxx, REG 08/07/91
3 #include <GccAna_Circ2dTanOnRad.jxx>
6 #include <math_DirectPolynomialRoots.hxx>
7 #include <Standard_NegativeValue.hxx>
8 #include <Standard_OutOfRange.hxx>
9 #include <gp_Dir2d.hxx>
11 //=========================================================================
12 // typedef of handled objects : +
13 //=========================================================================
15 typedef math_DirectPolynomialRoots Roots;
17 //=========================================================================
18 // Circle tangent to a point Point1. +
19 // center on straight line OnLine. +
22 // Initialize the table of solutions cirsol and all fields. +
23 // Eliminate cases not being the solution. +
24 // Solve the equation of second degree showing that the found center point +
25 // (xc,yc) is at distance Radius from point Point1 and on the straight line OnLine. +
26 // The solutions are represented by circles : +
27 // - of center Pntcen(xc,yc) +
28 // - of radius Radius. +
29 //=========================================================================
31 GccAna_Circ2dTanOnRad::
32 GccAna_Circ2dTanOnRad (const gp_Pnt2d& Point1 ,
33 const gp_Lin2d& OnLine ,
34 const Standard_Real Radius ,
35 const Standard_Real Tolerance ):
46 gp_Dir2d dirx(1.0,0.0);
47 Standard_Real Tol = Abs(Tolerance);
48 WellDone = Standard_False;
50 Standard_Real dp1lin = OnLine.Distance(Point1);
52 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
54 if (dp1lin > Radius+Tol) { WellDone = Standard_True; }
57 Standard_Real x1 = Point1.X();
58 Standard_Real y1 = Point1.Y();
59 Standard_Real xbid = 0;
60 Standard_Real xdir = (OnLine.Direction()).X();
61 Standard_Real ydir = (OnLine.Direction()).Y();
62 Standard_Real lxloc = (OnLine.Location()).X();
63 Standard_Real lyloc = (OnLine.Location()).Y();
64 if (Abs(dp1lin-Radius) < Tol) {
65 WellDone = Standard_True;
67 if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) {
68 gp_Ax2d axe(gp_Pnt2d(x1-ydir*dp1lin,y1+xdir*dp1lin),dirx);
69 cirsol(NbrSol) = gp_Circ2d(axe,Radius);
70 // ======================================
71 qualifier1(NbrSol) = GccEnt_noqualifier;
74 gp_Ax2d axe(gp_Pnt2d(x1+ydir*dp1lin,y1-xdir*dp1lin),dirx);
75 cirsol(NbrSol) = gp_Circ2d(axe,Radius);
76 // ======================================
77 qualifier1(NbrSol) = GccEnt_noqualifier;
80 pnttg1sol(NbrSol) = Point1;
81 pntcen3(NbrSol) = cirsol(NbrSol).Location();
82 pararg1(NbrSol) = 0.0;
83 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
84 parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
86 else if (dp1lin < Tol) {
87 pntcen3(1) = gp_Pnt2d(Point1.X()+Radius*xdir,Point1.Y()+Radius*ydir);
88 pntcen3(2) = gp_Pnt2d(Point1.X()-Radius*xdir,Point1.Y()-Radius*ydir);
89 pntcen3(1) = ElCLib::Value(ElCLib::Parameter(OnLine,pntcen3(1)),OnLine);
90 pntcen3(2) = ElCLib::Value(ElCLib::Parameter(OnLine,pntcen3(2)),OnLine);
91 gp_Ax2d axe(pntcen3(1),OnLine.Direction());
92 cirsol(1) = gp_Circ2d(axe,Radius);
93 axe = gp_Ax2d(pntcen3(2),OnLine.Direction());
94 cirsol(2) = gp_Circ2d(axe,Radius);
96 pnttg1sol(1) = Point1;
98 par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
99 parcen3(1)=ElCLib::Parameter(OnLine,pntcen3(1));
101 pnttg1sol(2) = Point1;
103 par1sol(2)=ElCLib::Parameter(cirsol(2),pnttg1sol(2));
104 parcen3(2)=ElCLib::Parameter(OnLine,pntcen3(2));
109 OnLine.Coefficients(A,B,C);
119 Roots Sol((B*B+A*A)/(A*A),
120 2.0*(B*C/(A*A)+(B/A)*x1-y1),
121 x1*x1+y1*y1+C*C/(A*A)-Radius*Radius+2.0*C*x1/A);
123 for (Standard_Integer i = 1 ; i <= Sol.NbSolutions() ; i++) {
133 gp_Pnt2d Center(xc,yc);
134 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
135 // =======================================================
136 qualifier1(NbrSol) = GccEnt_noqualifier;
137 TheSame1(NbrSol) = 0;
138 pnttg1sol(NbrSol) = Point1;
139 pntcen3(NbrSol) = cirsol(NbrSol).Location();
140 pararg1(NbrSol) = 0.0;
141 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
143 parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
145 WellDone = Standard_True;