7fd59977 |
1 | // file GccAna_Circ2dTanOnRad_2.cxx, REG 08/07/91 |
2 | |
3 | #include <GccAna_Circ2dTanOnRad.jxx> |
4 | |
5 | #include <ElCLib.hxx> |
6 | #include <math_DirectPolynomialRoots.hxx> |
7 | #include <Standard_NegativeValue.hxx> |
8 | #include <Standard_OutOfRange.hxx> |
9 | #include <gp_Dir2d.hxx> |
10 | |
11 | //========================================================================= |
12 | // typedef des objets manipules : + |
13 | //========================================================================= |
14 | |
15 | typedef math_DirectPolynomialRoots Roots; |
16 | |
17 | //========================================================================= |
18 | // Cercle tangent a un point Point1. + |
19 | // centre sur une droite OnLine. + |
20 | // de rayon Radius. + |
21 | // + |
22 | // On initialise le tableau de solutions cirsol ainsi que tous les + |
23 | // champs. + |
24 | // On elimine les cas ne presentant pas de solution. + |
25 | // On resoud l equation du second degre indiquant que le point de centre + |
26 | // recherche (xc,yc) est a une distance Radius du point Point1 et + |
27 | // sur la droite OnLine. + |
28 | // Les solutions sont representees par les cercles : + |
29 | // - de centre Pntcen(xc,yc) + |
30 | // - de rayon Radius. + |
31 | //========================================================================= |
32 | |
33 | GccAna_Circ2dTanOnRad:: |
34 | GccAna_Circ2dTanOnRad (const gp_Pnt2d& Point1 , |
35 | const gp_Lin2d& OnLine , |
36 | const Standard_Real Radius , |
37 | const Standard_Real Tolerance ): |
38 | cirsol(1,2) , |
39 | qualifier1(1,2) , |
40 | TheSame1(1,2) , |
41 | pnttg1sol(1,2), |
42 | pntcen3(1,2) , |
43 | par1sol(1,2) , |
44 | pararg1(1,2) , |
45 | parcen3(1,2) |
46 | { |
47 | |
48 | gp_Dir2d dirx(1.0,0.0); |
49 | Standard_Real Tol = Abs(Tolerance); |
50 | WellDone = Standard_False; |
51 | NbrSol = 0; |
52 | Standard_Real dp1lin = OnLine.Distance(Point1); |
53 | |
54 | if (Radius < 0.0) { Standard_NegativeValue::Raise(); } |
55 | else { |
56 | if (dp1lin > Radius+Tol) { WellDone = Standard_True; } |
57 | Standard_Real xc; |
58 | Standard_Real yc; |
59 | Standard_Real x1 = Point1.X(); |
60 | Standard_Real y1 = Point1.Y(); |
61 | Standard_Real xbid = 0; |
62 | Standard_Real xdir = (OnLine.Direction()).X(); |
63 | Standard_Real ydir = (OnLine.Direction()).Y(); |
64 | Standard_Real lxloc = (OnLine.Location()).X(); |
65 | Standard_Real lyloc = (OnLine.Location()).Y(); |
66 | if (Abs(dp1lin-Radius) < Tol) { |
67 | WellDone = Standard_True; |
68 | NbrSol = 1; |
69 | if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) { |
70 | gp_Ax2d axe(gp_Pnt2d(x1-ydir*dp1lin,y1+xdir*dp1lin),dirx); |
71 | cirsol(NbrSol) = gp_Circ2d(axe,Radius); |
72 | // ====================================== |
73 | qualifier1(NbrSol) = GccEnt_noqualifier; |
74 | } |
75 | else { |
76 | gp_Ax2d axe(gp_Pnt2d(x1+ydir*dp1lin,y1-xdir*dp1lin),dirx); |
77 | cirsol(NbrSol) = gp_Circ2d(axe,Radius); |
78 | // ====================================== |
79 | qualifier1(NbrSol) = GccEnt_noqualifier; |
80 | } |
81 | TheSame1(NbrSol) = 0; |
82 | pnttg1sol(NbrSol) = Point1; |
83 | pntcen3(NbrSol) = cirsol(NbrSol).Location(); |
84 | pararg1(NbrSol) = 0.0; |
85 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol)); |
86 | parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol)); |
87 | } |
88 | else if (dp1lin < Tol) { |
89 | pntcen3(1) = gp_Pnt2d(Point1.X()+Radius*xdir,Point1.Y()+Radius*ydir); |
90 | pntcen3(2) = gp_Pnt2d(Point1.X()-Radius*xdir,Point1.Y()-Radius*ydir); |
91 | pntcen3(1) = ElCLib::Value(ElCLib::Parameter(OnLine,pntcen3(1)),OnLine); |
92 | pntcen3(2) = ElCLib::Value(ElCLib::Parameter(OnLine,pntcen3(2)),OnLine); |
93 | gp_Ax2d axe(pntcen3(1),OnLine.Direction()); |
94 | cirsol(1) = gp_Circ2d(axe,Radius); |
95 | axe = gp_Ax2d(pntcen3(2),OnLine.Direction()); |
96 | cirsol(2) = gp_Circ2d(axe,Radius); |
97 | TheSame1(1) = 0; |
98 | pnttg1sol(1) = Point1; |
99 | pararg1(1) = 0.0; |
100 | par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1)); |
101 | parcen3(1)=ElCLib::Parameter(OnLine,pntcen3(1)); |
102 | TheSame1(2) = 0; |
103 | pnttg1sol(2) = Point1; |
104 | pararg1(2) = 0.0; |
105 | par1sol(2)=ElCLib::Parameter(cirsol(2),pnttg1sol(2)); |
106 | parcen3(2)=ElCLib::Parameter(OnLine,pntcen3(2)); |
107 | NbrSol = 2; |
108 | } |
109 | else { |
110 | Standard_Real A,B,C; |
111 | OnLine.Coefficients(A,B,C); |
112 | Standard_Real D = A; |
113 | if (A == 0.0) { |
114 | A = B; |
115 | B = D; |
116 | xbid = x1; |
117 | x1 = y1; |
118 | y1 = xbid; |
119 | } |
120 | if (A != 0.0) { |
121 | Roots Sol((B*B+A*A)/(A*A), |
122 | 2.0*(B*C/(A*A)+(B/A)*x1-y1), |
123 | x1*x1+y1*y1+C*C/(A*A)-Radius*Radius+2.0*C*x1/A); |
124 | if (Sol.IsDone()) { |
125 | for (Standard_Integer i = 1 ; i <= Sol.NbSolutions() ; i++) { |
126 | if (D != 0.0) { |
127 | yc = Sol.Value(i); |
128 | xc = -(B/A)*yc-C/A; |
129 | } |
130 | else { |
131 | xc = Sol.Value(i); |
132 | yc = -(B/A)*xc-C/A; |
133 | } |
134 | NbrSol++; |
135 | gp_Pnt2d Center(xc,yc); |
136 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); |
137 | // ======================================================= |
138 | qualifier1(NbrSol) = GccEnt_noqualifier; |
139 | TheSame1(NbrSol) = 0; |
140 | pnttg1sol(NbrSol) = Point1; |
141 | pntcen3(NbrSol) = cirsol(NbrSol).Location(); |
142 | pararg1(NbrSol) = 0.0; |
143 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
144 | pnttg1sol(NbrSol)); |
145 | parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol)); |
146 | } |
147 | WellDone = Standard_True; |
148 | } |
149 | } |
150 | } |
151 | } |
152 | } |