7fd59977 |
1 | // File: GccAna_Circ2d2TanOn_7.cxx |
2 | // Created: Thu Jan 2 15:57:15 1992 |
3 | // Author: Remi GILET |
4 | // <reg@topsn3> |
5 | |
6 | #include <GccAna_Circ2d2TanOn.jxx> |
7 | |
8 | #include <ElCLib.hxx> |
9 | #include <gp_Dir2d.hxx> |
10 | #include <gp_Ax2d.hxx> |
11 | #include <IntAna2d_AnaIntersection.hxx> |
12 | #include <IntAna2d_IntPoint.hxx> |
13 | #include <GccAna_CircLin2dBisec.hxx> |
14 | #include <GccInt_IType.hxx> |
15 | #include <GccInt_BCirc.hxx> |
16 | #include <IntAna2d_Conic.hxx> |
17 | #include <TColStd_Array1OfReal.hxx> |
18 | #include <GccEnt_BadQualifier.hxx> |
19 | |
20 | GccAna_Circ2d2TanOn:: |
21 | GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 , |
22 | const GccEnt_QualifiedLin& Qualified2 , |
23 | const gp_Circ2d& OnCirc , |
24 | const Standard_Real Tolerance ): |
25 | cirsol(1,4) , |
26 | qualifier1(1,4) , |
27 | qualifier2(1,4), |
28 | TheSame1(1,4) , |
29 | TheSame2(1,4) , |
30 | pnttg1sol(1,4) , |
31 | pnttg2sol(1,4) , |
32 | pntcen(1,4) , |
33 | par1sol(1,4) , |
34 | par2sol(1,4) , |
35 | pararg1(1,4) , |
36 | pararg2(1,4) , |
37 | parcen3(1,4) |
38 | { |
39 | TheSame1.Init(0); |
40 | TheSame2.Init(0); |
41 | WellDone = Standard_False; |
42 | NbrSol = 0; |
43 | if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || |
44 | Qualified1.IsOutside() || Qualified1.IsUnqualified()) || |
45 | !(Qualified2.IsEnclosed() || |
46 | Qualified2.IsOutside() || Qualified2.IsUnqualified())) { |
47 | GccEnt_BadQualifier::Raise(); |
48 | return; |
49 | } |
50 | Standard_Real Radius=0; |
51 | gp_Dir2d dirx(1.,0.); |
52 | gp_Circ2d C1 = Qualified1.Qualified(); |
53 | gp_Lin2d L2 = Qualified2.Qualified(); |
54 | Standard_Real R1 = C1.Radius(); |
55 | gp_Pnt2d center1(C1.Location()); |
56 | gp_Pnt2d origin2(L2.Location()); |
57 | gp_Dir2d dirL2(L2.Direction()); |
58 | gp_Dir2d normL2(-dirL2.Y(),dirL2.X()); |
59 | |
60 | //========================================================================= |
61 | // Traitement des cas limites. + |
62 | //========================================================================= |
63 | |
64 | Standard_Real Tol = Abs(Tolerance); |
65 | TColStd_Array1OfReal Rradius(1,2); |
66 | Standard_Integer nbsol1 = 1; |
67 | // Standard_Integer nbsol2 = 0; |
68 | Standard_Real Ron = OnCirc.Radius(); |
69 | Standard_Real distcco = OnCirc.Location().Distance(center1); |
70 | gp_Dir2d dircc(OnCirc.Location().XY()-center1.XY()); |
71 | gp_Pnt2d pinterm(center1.XY()+(distcco-Ron)*dircc.XY()); |
72 | Standard_Real distpl2 =L2.Distance(pinterm); |
73 | Standard_Real distcc1 =pinterm.Distance(center1); |
74 | Standard_Real d1 = Abs(distpl2-Abs(distcc1-R1)); |
75 | Standard_Real d2 = Abs(distpl2-(distcc1+R1)); |
76 | if ( d1 > Tol || d2 > Tol ) { |
77 | pinterm = gp_Pnt2d(center1.XY()+(distcco-Ron)*dircc.XY()); |
78 | if ( d1 > Tol || d2 > Tol ) { |
79 | nbsol1 = 0; |
80 | } |
81 | } |
82 | if (nbsol1 > 0) { |
83 | if (Qualified1.IsEnclosed() || Qualified1.IsOutside()) { |
84 | nbsol1 = 1; |
85 | Rradius(1) = Abs(distcc1-R1); |
86 | } |
87 | else if (Qualified1.IsEnclosing()) { |
88 | nbsol1 = 1; |
89 | Rradius(1) = R1+distcc1; |
90 | } |
91 | else if (Qualified1.IsUnqualified()) { |
92 | nbsol1 = 2; |
93 | Rradius(1) = Abs(distcc1-R1); |
94 | Rradius(2) = R1+distcc1; |
95 | } |
96 | gp_Dir2d dirbid(origin2.XY()-pinterm.XY()); |
97 | gp_Dir2d normal(-dirL2.Y(),dirL2.X()); |
98 | if (Qualified1.IsEnclosed() && dirbid.Dot(normal) < 0.) { |
99 | nbsol1 = 0; |
100 | } |
101 | else if (Qualified1.IsOutside() && dirbid.Dot(normal) < 0.) { |
102 | nbsol1 = 0; |
103 | } |
104 | for (Standard_Integer i = 1 ; i <= nbsol1 ; i++) { |
105 | if (Abs(Rradius(i)-distpl2) <= Tol) { |
106 | WellDone = Standard_True; |
107 | NbrSol++; |
108 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),Rradius(i)); |
109 | // =========================================================== |
110 | gp_Dir2d dc1(center1.XY()-pinterm.XY()); |
111 | gp_Dir2d dc2(origin2.XY()-pinterm.XY()); |
112 | distcc1 = pinterm.Distance(center1); |
113 | if (!Qualified1.IsUnqualified()) { |
114 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
115 | } |
116 | else if (Abs(distcc1+Rradius(i)-R1) < Tol) { |
117 | qualifier1(NbrSol) = GccEnt_enclosed; |
118 | } |
119 | else if (Abs(distcc1-R1-Rradius(i)) < Tol) { |
120 | qualifier1(NbrSol) = GccEnt_outside; |
121 | } |
122 | else { qualifier1(NbrSol) = GccEnt_enclosing; } |
123 | if (!Qualified2.IsUnqualified()) { |
124 | qualifier2(NbrSol) = Qualified2.Qualifier(); |
125 | } |
126 | else if (dc2.Dot(normL2) > 0.0) { |
127 | qualifier2(NbrSol) = GccEnt_outside; |
128 | } |
129 | else { qualifier2(NbrSol) = GccEnt_enclosed; } |
130 | |
131 | Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL2.Y(),dirL2.X())); |
132 | dc2 = gp_Dir2d(sign*gp_XY(-dirL2.Y(),dirL2.X())); |
133 | pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+Rradius(i)*dc1.XY()); |
134 | pnttg2sol(NbrSol) = gp_Pnt2d(pinterm.XY()+Rradius(i)*dc2.XY()); |
135 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol)); |
136 | pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol)); |
137 | par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol)); |
138 | pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol)); |
139 | parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol)); |
140 | } |
141 | } |
142 | if (WellDone) { return; } |
143 | } |
144 | |
145 | //========================================================================= |
146 | // Cas general. + |
147 | //========================================================================= |
148 | |
149 | GccAna_CircLin2dBisec Bis(C1,L2); |
150 | if (Bis.IsDone()) { |
151 | Standard_Integer nbsolution = Bis.NbSolutions(); |
152 | for (Standard_Integer i = 1 ; i <= nbsolution; i++) { |
153 | Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i); |
154 | GccInt_IType type = Sol->ArcType(); |
155 | IntAna2d_AnaIntersection Intp; |
156 | if (type == GccInt_Lin) { |
157 | Intp.Perform(Sol->Line(),OnCirc); |
158 | } |
159 | else if (type == GccInt_Par) { |
160 | Intp.Perform(OnCirc,IntAna2d_Conic(Sol->Parabola())); |
161 | } |
162 | if (Intp.IsDone()) { |
163 | if ((!Intp.IsEmpty())&&(!Intp.ParallelElements())&& |
164 | (!Intp.IdenticalElements())) { |
165 | for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) { |
166 | gp_Pnt2d Center(Intp.Point(j).Value()); |
167 | Standard_Real dist1 = Center.Distance(center1); |
168 | Standard_Real dist2 = L2.Distance(Center); |
169 | // Standard_Integer nbsol = 1; |
170 | Standard_Boolean ok = Standard_False; |
171 | if (Qualified1.IsEnclosed()) { |
172 | if (dist1-R1 < Tolerance) { |
173 | if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; } |
174 | } |
175 | } |
176 | else if (Qualified1.IsOutside()) { |
177 | if (R1-dist1 < Tolerance) { |
178 | if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; } |
179 | } |
180 | } |
181 | else if (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) { |
182 | ok = Standard_True; |
183 | } |
184 | if (Qualified2.IsEnclosed() && ok) { |
185 | if ((((origin2.X()-Center.X())*(-dirL2.Y()))+ |
186 | ((origin2.Y()-Center.Y())*(dirL2.X())))<=0){ |
187 | ok = Standard_True; |
188 | Radius = dist2; |
189 | } |
190 | } |
191 | else if (Qualified2.IsOutside() && ok) { |
192 | if ((((origin2.X()-Center.X())*(-dirL2.Y()))+ |
193 | ((origin2.Y()-Center.Y())*(dirL2.X())))>=0){ |
194 | ok = Standard_True; |
195 | Radius = dist2; |
196 | } |
197 | } |
198 | else if (Qualified2.IsUnqualified() && ok) { |
199 | ok = Standard_True; |
200 | Radius = dist2; |
201 | } |
202 | if (ok) { |
203 | NbrSol++; |
204 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); |
205 | // ======================================================= |
206 | gp_Dir2d dc2(origin2.XY()-Center.XY()); |
207 | distcc1 = Center.Distance(center1); |
208 | if (!Qualified1.IsUnqualified()) { |
209 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
210 | } |
211 | else if (Abs(distcc1+Radius-R1) < Tol) { |
212 | qualifier1(NbrSol) = GccEnt_enclosed; |
213 | } |
214 | else if (Abs(distcc1-R1-Radius) < Tol) { |
215 | qualifier1(NbrSol) = GccEnt_outside; |
216 | } |
217 | else { qualifier1(NbrSol) = GccEnt_enclosing; } |
218 | if (!Qualified2.IsUnqualified()) { |
219 | qualifier2(NbrSol) = Qualified2.Qualifier(); |
220 | } |
221 | else if (dc2.Dot(normL2) > 0.0) { |
222 | qualifier2(NbrSol) = GccEnt_outside; |
223 | } |
224 | else { qualifier2(NbrSol) = GccEnt_enclosed; } |
225 | if (Center.Distance(center1) <= Tolerance && |
226 | Abs(Radius-C1.Radius()) <= Tolerance) { |
227 | TheSame1(NbrSol) = 1; |
228 | } |
229 | else { |
230 | TheSame1(NbrSol) = 0; |
231 | gp_Dir2d dc1(center1.XY()-Center.XY()); |
232 | pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY()); |
233 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
234 | pnttg1sol(NbrSol)); |
235 | pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol)); |
236 | } |
237 | TheSame2(NbrSol) = 0; |
238 | Standard_Real sign = dc2.Dot(gp_Dir2d(normL2.XY())); |
239 | dc2 = gp_Dir2d(sign*gp_XY(normL2.XY())); |
240 | pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY()); |
241 | par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
242 | pnttg2sol(NbrSol)); |
243 | pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol)); |
244 | pntcen(NbrSol) = Center; |
245 | parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol)); |
246 | } |
247 | } |
248 | } |
249 | WellDone = Standard_True; |
250 | } |
251 | } |
252 | } |
253 | } |
254 | |