b311480e |
1 | // Created on: 1992-01-02 |
2 | // Created by: Remi GILET |
3 | // Copyright (c) 1992-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | #include <GccAna_Circ2d2TanOn.jxx> |
23 | |
24 | #include <ElCLib.hxx> |
25 | #include <gp_Dir2d.hxx> |
26 | #include <gp_Ax2d.hxx> |
27 | #include <IntAna2d_AnaIntersection.hxx> |
28 | #include <IntAna2d_IntPoint.hxx> |
29 | #include <GccAna_CircLin2dBisec.hxx> |
30 | #include <GccInt_IType.hxx> |
31 | #include <GccInt_BCirc.hxx> |
32 | #include <IntAna2d_Conic.hxx> |
33 | #include <TColStd_Array1OfReal.hxx> |
34 | #include <GccEnt_BadQualifier.hxx> |
35 | |
36 | GccAna_Circ2d2TanOn:: |
37 | GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 , |
38 | const GccEnt_QualifiedLin& Qualified2 , |
39 | const gp_Circ2d& OnCirc , |
40 | const Standard_Real Tolerance ): |
41 | cirsol(1,4) , |
42 | qualifier1(1,4) , |
43 | qualifier2(1,4), |
44 | TheSame1(1,4) , |
45 | TheSame2(1,4) , |
46 | pnttg1sol(1,4) , |
47 | pnttg2sol(1,4) , |
48 | pntcen(1,4) , |
49 | par1sol(1,4) , |
50 | par2sol(1,4) , |
51 | pararg1(1,4) , |
52 | pararg2(1,4) , |
53 | parcen3(1,4) |
54 | { |
55 | TheSame1.Init(0); |
56 | TheSame2.Init(0); |
57 | WellDone = Standard_False; |
58 | NbrSol = 0; |
59 | if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || |
60 | Qualified1.IsOutside() || Qualified1.IsUnqualified()) || |
61 | !(Qualified2.IsEnclosed() || |
62 | Qualified2.IsOutside() || Qualified2.IsUnqualified())) { |
63 | GccEnt_BadQualifier::Raise(); |
64 | return; |
65 | } |
66 | Standard_Real Radius=0; |
67 | gp_Dir2d dirx(1.,0.); |
68 | gp_Circ2d C1 = Qualified1.Qualified(); |
69 | gp_Lin2d L2 = Qualified2.Qualified(); |
70 | Standard_Real R1 = C1.Radius(); |
71 | gp_Pnt2d center1(C1.Location()); |
72 | gp_Pnt2d origin2(L2.Location()); |
73 | gp_Dir2d dirL2(L2.Direction()); |
74 | gp_Dir2d normL2(-dirL2.Y(),dirL2.X()); |
75 | |
76 | //========================================================================= |
0d969553 |
77 | // Processing of boundary cases. + |
7fd59977 |
78 | //========================================================================= |
79 | |
80 | Standard_Real Tol = Abs(Tolerance); |
81 | TColStd_Array1OfReal Rradius(1,2); |
82 | Standard_Integer nbsol1 = 1; |
83 | // Standard_Integer nbsol2 = 0; |
84 | Standard_Real Ron = OnCirc.Radius(); |
85 | Standard_Real distcco = OnCirc.Location().Distance(center1); |
86 | gp_Dir2d dircc(OnCirc.Location().XY()-center1.XY()); |
87 | gp_Pnt2d pinterm(center1.XY()+(distcco-Ron)*dircc.XY()); |
88 | Standard_Real distpl2 =L2.Distance(pinterm); |
89 | Standard_Real distcc1 =pinterm.Distance(center1); |
90 | Standard_Real d1 = Abs(distpl2-Abs(distcc1-R1)); |
91 | Standard_Real d2 = Abs(distpl2-(distcc1+R1)); |
92 | if ( d1 > Tol || d2 > Tol ) { |
93 | pinterm = gp_Pnt2d(center1.XY()+(distcco-Ron)*dircc.XY()); |
94 | if ( d1 > Tol || d2 > Tol ) { |
95 | nbsol1 = 0; |
96 | } |
97 | } |
98 | if (nbsol1 > 0) { |
99 | if (Qualified1.IsEnclosed() || Qualified1.IsOutside()) { |
100 | nbsol1 = 1; |
101 | Rradius(1) = Abs(distcc1-R1); |
102 | } |
103 | else if (Qualified1.IsEnclosing()) { |
104 | nbsol1 = 1; |
105 | Rradius(1) = R1+distcc1; |
106 | } |
107 | else if (Qualified1.IsUnqualified()) { |
108 | nbsol1 = 2; |
109 | Rradius(1) = Abs(distcc1-R1); |
110 | Rradius(2) = R1+distcc1; |
111 | } |
112 | gp_Dir2d dirbid(origin2.XY()-pinterm.XY()); |
113 | gp_Dir2d normal(-dirL2.Y(),dirL2.X()); |
114 | if (Qualified1.IsEnclosed() && dirbid.Dot(normal) < 0.) { |
115 | nbsol1 = 0; |
116 | } |
117 | else if (Qualified1.IsOutside() && dirbid.Dot(normal) < 0.) { |
118 | nbsol1 = 0; |
119 | } |
120 | for (Standard_Integer i = 1 ; i <= nbsol1 ; i++) { |
121 | if (Abs(Rradius(i)-distpl2) <= Tol) { |
122 | WellDone = Standard_True; |
123 | NbrSol++; |
124 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),Rradius(i)); |
125 | // =========================================================== |
126 | gp_Dir2d dc1(center1.XY()-pinterm.XY()); |
127 | gp_Dir2d dc2(origin2.XY()-pinterm.XY()); |
128 | distcc1 = pinterm.Distance(center1); |
129 | if (!Qualified1.IsUnqualified()) { |
130 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
131 | } |
132 | else if (Abs(distcc1+Rradius(i)-R1) < Tol) { |
133 | qualifier1(NbrSol) = GccEnt_enclosed; |
134 | } |
135 | else if (Abs(distcc1-R1-Rradius(i)) < Tol) { |
136 | qualifier1(NbrSol) = GccEnt_outside; |
137 | } |
138 | else { qualifier1(NbrSol) = GccEnt_enclosing; } |
139 | if (!Qualified2.IsUnqualified()) { |
140 | qualifier2(NbrSol) = Qualified2.Qualifier(); |
141 | } |
142 | else if (dc2.Dot(normL2) > 0.0) { |
143 | qualifier2(NbrSol) = GccEnt_outside; |
144 | } |
145 | else { qualifier2(NbrSol) = GccEnt_enclosed; } |
146 | |
147 | Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL2.Y(),dirL2.X())); |
148 | dc2 = gp_Dir2d(sign*gp_XY(-dirL2.Y(),dirL2.X())); |
149 | pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+Rradius(i)*dc1.XY()); |
150 | pnttg2sol(NbrSol) = gp_Pnt2d(pinterm.XY()+Rradius(i)*dc2.XY()); |
151 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol)); |
152 | pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol)); |
153 | par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol)); |
154 | pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol)); |
155 | parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol)); |
156 | } |
157 | } |
158 | if (WellDone) { return; } |
159 | } |
160 | |
161 | //========================================================================= |
0d969553 |
162 | // General case. + |
7fd59977 |
163 | //========================================================================= |
164 | |
165 | GccAna_CircLin2dBisec Bis(C1,L2); |
166 | if (Bis.IsDone()) { |
167 | Standard_Integer nbsolution = Bis.NbSolutions(); |
168 | for (Standard_Integer i = 1 ; i <= nbsolution; i++) { |
169 | Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i); |
170 | GccInt_IType type = Sol->ArcType(); |
171 | IntAna2d_AnaIntersection Intp; |
172 | if (type == GccInt_Lin) { |
173 | Intp.Perform(Sol->Line(),OnCirc); |
174 | } |
175 | else if (type == GccInt_Par) { |
176 | Intp.Perform(OnCirc,IntAna2d_Conic(Sol->Parabola())); |
177 | } |
178 | if (Intp.IsDone()) { |
179 | if ((!Intp.IsEmpty())&&(!Intp.ParallelElements())&& |
180 | (!Intp.IdenticalElements())) { |
181 | for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) { |
182 | gp_Pnt2d Center(Intp.Point(j).Value()); |
183 | Standard_Real dist1 = Center.Distance(center1); |
184 | Standard_Real dist2 = L2.Distance(Center); |
185 | // Standard_Integer nbsol = 1; |
186 | Standard_Boolean ok = Standard_False; |
187 | if (Qualified1.IsEnclosed()) { |
188 | if (dist1-R1 < Tolerance) { |
189 | if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; } |
190 | } |
191 | } |
192 | else if (Qualified1.IsOutside()) { |
193 | if (R1-dist1 < Tolerance) { |
194 | if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; } |
195 | } |
196 | } |
197 | else if (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) { |
198 | ok = Standard_True; |
199 | } |
200 | if (Qualified2.IsEnclosed() && ok) { |
201 | if ((((origin2.X()-Center.X())*(-dirL2.Y()))+ |
202 | ((origin2.Y()-Center.Y())*(dirL2.X())))<=0){ |
203 | ok = Standard_True; |
204 | Radius = dist2; |
205 | } |
206 | } |
207 | else if (Qualified2.IsOutside() && ok) { |
208 | if ((((origin2.X()-Center.X())*(-dirL2.Y()))+ |
209 | ((origin2.Y()-Center.Y())*(dirL2.X())))>=0){ |
210 | ok = Standard_True; |
211 | Radius = dist2; |
212 | } |
213 | } |
214 | else if (Qualified2.IsUnqualified() && ok) { |
215 | ok = Standard_True; |
216 | Radius = dist2; |
217 | } |
218 | if (ok) { |
219 | NbrSol++; |
220 | cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); |
221 | // ======================================================= |
222 | gp_Dir2d dc2(origin2.XY()-Center.XY()); |
223 | distcc1 = Center.Distance(center1); |
224 | if (!Qualified1.IsUnqualified()) { |
225 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
226 | } |
227 | else if (Abs(distcc1+Radius-R1) < Tol) { |
228 | qualifier1(NbrSol) = GccEnt_enclosed; |
229 | } |
230 | else if (Abs(distcc1-R1-Radius) < Tol) { |
231 | qualifier1(NbrSol) = GccEnt_outside; |
232 | } |
233 | else { qualifier1(NbrSol) = GccEnt_enclosing; } |
234 | if (!Qualified2.IsUnqualified()) { |
235 | qualifier2(NbrSol) = Qualified2.Qualifier(); |
236 | } |
237 | else if (dc2.Dot(normL2) > 0.0) { |
238 | qualifier2(NbrSol) = GccEnt_outside; |
239 | } |
240 | else { qualifier2(NbrSol) = GccEnt_enclosed; } |
241 | if (Center.Distance(center1) <= Tolerance && |
242 | Abs(Radius-C1.Radius()) <= Tolerance) { |
243 | TheSame1(NbrSol) = 1; |
244 | } |
245 | else { |
246 | TheSame1(NbrSol) = 0; |
247 | gp_Dir2d dc1(center1.XY()-Center.XY()); |
248 | pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY()); |
249 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
250 | pnttg1sol(NbrSol)); |
251 | pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol)); |
252 | } |
253 | TheSame2(NbrSol) = 0; |
254 | Standard_Real sign = dc2.Dot(gp_Dir2d(normL2.XY())); |
255 | dc2 = gp_Dir2d(sign*gp_XY(normL2.XY())); |
256 | pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY()); |
257 | par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), |
258 | pnttg2sol(NbrSol)); |
259 | pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol)); |
260 | pntcen(NbrSol) = Center; |
261 | parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol)); |
262 | } |
263 | } |
264 | } |
265 | WellDone = Standard_True; |
266 | } |
267 | } |
268 | } |
269 | } |
270 | |