b311480e |
1 | // Created on: 1992-01-02 |
2 | // Created by: Remi GILET |
3 | // Copyright (c) 1992-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
7fd59977 |
17 | |
18 | #include <ElCLib.hxx> |
42cf5bc1 |
19 | #include <GccAna_Circ2d2TanOn.hxx> |
20 | #include <GccAna_Lin2dBisec.hxx> |
21 | #include <GccEnt_BadQualifier.hxx> |
42cf5bc1 |
22 | #include <GccEnt_QualifiedLin.hxx> |
23 | #include <gp.hxx> |
7fd59977 |
24 | #include <gp_Ax2d.hxx> |
42cf5bc1 |
25 | #include <gp_Circ2d.hxx> |
26 | #include <gp_Dir2d.hxx> |
27 | #include <gp_Lin2d.hxx> |
28 | #include <gp_Pnt2d.hxx> |
7fd59977 |
29 | #include <IntAna2d_AnaIntersection.hxx> |
30 | #include <IntAna2d_IntPoint.hxx> |
7fd59977 |
31 | |
32 | GccAna_Circ2d2TanOn:: |
33 | GccAna_Circ2d2TanOn (const GccEnt_QualifiedLin& Qualified1 , |
34 | const GccEnt_QualifiedLin& Qualified2 , |
35 | const gp_Circ2d& OnCirc , |
35e08fe8 |
36 | const Standard_Real ): |
7fd59977 |
37 | cirsol(1,4) , |
38 | qualifier1(1,4) , |
39 | qualifier2(1,4), |
40 | TheSame1(1,4) , |
41 | TheSame2(1,4) , |
42 | pnttg1sol(1,4) , |
43 | pnttg2sol(1,4) , |
44 | pntcen(1,4) , |
45 | par1sol(1,4) , |
46 | par2sol(1,4) , |
47 | pararg1(1,4) , |
48 | pararg2(1,4) , |
49 | parcen3(1,4) |
50 | { |
51 | TheSame1.Init(0); |
52 | TheSame2.Init(0); |
53 | WellDone = Standard_False; |
54 | NbrSol = 0; |
55 | |
56 | gp_Dir2d dirx(1.,0.); |
7fd59977 |
57 | if (!(Qualified1.IsEnclosed() || |
58 | Qualified1.IsOutside() || Qualified1.IsUnqualified()) || |
59 | !(Qualified2.IsEnclosed() || |
60 | Qualified2.IsOutside() || Qualified2.IsUnqualified())) { |
9775fa61 |
61 | throw GccEnt_BadQualifier(); |
7fd59977 |
62 | return; |
63 | } |
64 | gp_Lin2d L1(Qualified1.Qualified()); |
65 | gp_Lin2d L2(Qualified2.Qualified()); |
66 | GccAna_Lin2dBisec Bis(L1,L2); |
67 | Standard_Integer i=0,j=0; |
68 | Standard_Integer nbsol = 0; |
69 | Standard_Real sgn = 1.; |
70 | Standard_Real s = 1.; |
71 | Standard_Boolean ok = Standard_False; |
72 | gp_Dir2d D1(L1.Direction()); |
73 | gp_Dir2d D2(L2.Direction()); |
74 | gp_Dir2d Dnor1(-D1.Y(),D1.X()); |
75 | gp_Dir2d Dnor2(-D2.Y(),D2.X()); |
76 | gp_XY XYnor1(-D1.Y(),D1.X()); |
77 | gp_XY XYnor2(-D2.Y(),D2.X()); |
78 | gp_Pnt2d originL1(L1.Location()); |
79 | gp_Pnt2d originL2(L2.Location()); |
80 | gp_XY Dloc(originL1.XY()-originL2.XY()); |
81 | if (D1.Angle(D2) <= gp::Resolution()) { |
82 | if (Qualified1.IsEnclosed()) { |
83 | if (Dloc.Dot(XYnor1) <= 0.) { ok = Standard_True; } |
84 | else { ok = Standard_False; } |
85 | } |
86 | else if (Qualified1.IsOutside()) { |
87 | if (Dloc.Dot(XYnor1) >= 0.) { ok = Standard_True; } |
88 | else { ok = Standard_False; } |
89 | } |
90 | else {ok = Standard_True; } |
91 | if (Qualified2.IsEnclosed()) { |
92 | if (Dloc.Dot(XYnor2) >= 0.) { ok = Standard_True; } |
93 | else { ok = Standard_False; } |
94 | } |
95 | else if (Qualified2.IsOutside()) { |
96 | if (Dloc.Dot(XYnor2) <= 0.) { ok = Standard_True; } |
97 | else { ok = Standard_False; } |
98 | } |
99 | else {ok = Standard_True; } |
100 | if ( ok ) { |
101 | IntAna2d_AnaIntersection Intp(Bis.ThisSolution(1),OnCirc); |
102 | if (Intp.IsDone()) { |
103 | WellDone = Standard_True; |
104 | if (!Intp.IsEmpty()) { |
105 | for (Standard_Integer l = 1 ; l <= Intp.NbPoints() ; l++) { |
106 | NbrSol++; |
107 | gp_Pnt2d pt(Intp.Point(l).Value()); |
108 | gp_Ax2d axe(pt,dirx); |
109 | cirsol(NbrSol) = gp_Circ2d(axe,L1.Distance(pt)); |
110 | // =============================================== |
111 | gp_Dir2d dc1(originL1.XY()-pt.XY()); |
112 | gp_Dir2d dc2(originL2.XY()-pt.XY()); |
113 | if (!Qualified1.IsUnqualified()) { |
114 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
115 | } |
116 | else if (dc1.Dot(Dnor1) > 0.0) { |
117 | qualifier1(NbrSol) = GccEnt_outside; |
118 | } |
119 | else { qualifier1(NbrSol) = GccEnt_enclosed; } |
120 | if (!Qualified2.IsUnqualified()) { |
121 | qualifier2(NbrSol) = Qualified2.Qualifier(); |
122 | } |
123 | else if (dc2.Dot(Dnor2) > 0.0) { |
124 | qualifier2(NbrSol) = GccEnt_outside; |
125 | } |
126 | else { qualifier2(NbrSol) = GccEnt_enclosed; } |
127 | } |
128 | } |
129 | } |
130 | } |
131 | } |
132 | else if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) { |
133 | //============================================================ |
134 | if (Bis.IsDone()) { |
135 | if (Bis.NbSolutions() == 2) { |
136 | nbsol = 1; |
137 | i = 2; |
138 | j = 1; |
139 | sgn = -1.; |
140 | } |
141 | } |
142 | } |
143 | else if (Qualified1.IsEnclosed() && Qualified2.IsOutside()) { |
144 | //=========================================================== |
145 | if (Bis.IsDone()) { |
146 | if (Bis.NbSolutions() >= 1) { |
147 | nbsol = 1; |
148 | i = 1; |
149 | j = 1; |
150 | if (D1.Angle(D2) >= 0.0) { sgn = -1.; } |
151 | } |
152 | } |
153 | } |
154 | else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) { |
155 | //=========================================================== |
156 | if (Bis.IsDone()) { |
157 | if (Bis.NbSolutions() >= 1) { |
158 | nbsol = 1; |
159 | i = 1; |
160 | j = 1; |
161 | if (D1.Angle(D2) <= 0.0) { sgn = -1.; } |
162 | } |
163 | } |
164 | } |
165 | else if (Qualified1.IsOutside() && Qualified2.IsOutside()) { |
166 | //========================================================== |
167 | if (Bis.IsDone()) { |
168 | if (Bis.NbSolutions() >= 1) { |
169 | nbsol = 1; |
170 | i = 2; |
171 | j = 1; |
172 | } |
173 | } |
174 | } |
175 | else if (Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) { |
176 | //============================================================= |
177 | if (Bis.IsDone()) { |
178 | nbsol = 2; |
179 | if (Bis.NbSolutions() >= 1) { |
180 | i = 1; |
181 | j = 2; |
182 | } |
183 | if (D1.Angle(D2) >= 0.0) { s = -1.; } |
184 | else { sgn = -1.; } |
185 | } |
186 | } |
187 | else if (Qualified1.IsUnqualified() && Qualified2.IsOutside()) { |
188 | //============================================================== |
189 | if (Bis.IsDone()) { |
190 | nbsol = 2; |
191 | if (Bis.NbSolutions() >= 1) { |
192 | i = 1; |
193 | j = 2; |
194 | } |
195 | if (D1.Angle(D2) >= 0.0) { |
196 | s = -1.; |
197 | sgn = -1.; |
198 | } |
199 | } |
200 | } |
201 | else if (Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) { |
202 | //=============================================================== |
203 | if (Bis.IsDone()) { |
204 | nbsol = 2; |
205 | if (Bis.NbSolutions() >= 1) { |
206 | i = 1; |
207 | j = 2; |
208 | } |
209 | if (D1.Angle(D2) >= 0.0) { sgn = -1.; } |
210 | else { s = -1.; } |
211 | } |
212 | } |
213 | else if (Qualified1.IsOutside() && Qualified2.IsUnqualified()) { |
214 | //============================================================== |
215 | if (Bis.IsDone()) { |
216 | nbsol = 2; |
217 | if (Bis.NbSolutions() >= 1) { |
218 | i = 1; |
219 | j = 2; |
220 | } |
221 | if (D1.Angle(D2) <= 0.0) { |
222 | s = -1.; |
223 | sgn = -1.; |
224 | } |
225 | } |
226 | } |
227 | else if (Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) { |
228 | //================================================================== |
229 | nbsol = 4; |
230 | i = 1; |
231 | j = 2; |
232 | } |
233 | if (nbsol >= 1) { |
234 | if (Bis.IsDone()) { |
235 | Standard_Integer kk = 0; |
236 | for (Standard_Integer k = i ; k <= i+j-1 ; k++) { |
237 | kk++; |
238 | IntAna2d_AnaIntersection Intp(Bis.ThisSolution(k),OnCirc); |
239 | if (Intp.IsDone()) { |
240 | if (!Intp.IsEmpty()) { |
241 | for (Standard_Integer l = 1 ; l <= Intp.NbPoints() ; l++) { |
242 | gp_Vec2d V(Intp.Point(l).Value(), |
243 | Bis.ThisSolution(k).Location()); |
244 | if ((kk==1 && sgn*V.Dot(Bis.ThisSolution(k).Direction())>=0.0)|| |
245 | (kk==2 && sgn*s*V.Dot(Bis.ThisSolution(k).Direction())>=0.0) |
246 | || nbsol == 4) { |
247 | NbrSol++; |
248 | gp_Pnt2d pt(Intp.Point(i).Value()); |
249 | gp_Ax2d axe(pt,dirx); |
250 | cirsol(NbrSol) = gp_Circ2d(axe, |
251 | // =============================== |
252 | L1.Distance(Intp.Point(l).Value())); |
253 | // =================================== |
254 | gp_Dir2d dc1(originL1.XY()-pt.XY()); |
255 | gp_Dir2d dc2(originL2.XY()-pt.XY()); |
256 | if (!Qualified1.IsUnqualified()) { |
257 | qualifier1(NbrSol) = Qualified1.Qualifier(); |
258 | } |
259 | else if (dc1.Dot(Dnor1) > 0.0) { |
260 | qualifier1(NbrSol) = GccEnt_outside; |
261 | } |
262 | else { qualifier1(NbrSol) = GccEnt_enclosed; } |
263 | if (!Qualified2.IsUnqualified()) { |
264 | qualifier2(NbrSol) = Qualified2.Qualifier(); |
265 | } |
266 | else if (dc2.Dot(Dnor2) > 0.0) { |
267 | qualifier2(NbrSol) = GccEnt_outside; |
268 | } |
269 | else { qualifier2(NbrSol) = GccEnt_enclosed; } |
270 | } |
271 | } |
272 | } |
273 | WellDone = Standard_True; |
274 | } |
275 | } |
276 | } |
277 | } |
278 | if (NbrSol > 0) { |
279 | for (i =1 ; i <= NbrSol ; i++) { |
280 | gp_Pnt2d pbid(cirsol(i).Location()); |
281 | Standard_Real Radius = cirsol(i).Radius(); |
282 | gp_Dir2d dc2(originL1.XY()-pbid.XY()); |
283 | Standard_Real sign = dc2.Dot(gp_Dir2d(-L1.Direction().Y(), |
284 | L1.Direction().X())); |
285 | dc2 = gp_Dir2d(sign*gp_XY(-L1.Direction().Y(),L1.Direction().X())); |
286 | pnttg1sol(i) = gp_Pnt2d(pbid.XY()+Radius*dc2.XY()); |
287 | dc2 = gp_Dir2d(originL2.XY()-pbid.XY()); |
288 | sign = dc2.Dot(gp_Dir2d(-L2.Direction().Y(),L2.Direction().X())); |
289 | dc2 = gp_Dir2d(sign*gp_XY(-L2.Direction().Y(),L2.Direction().X())); |
290 | pnttg2sol(i) = gp_Pnt2d(pbid.XY()+Radius*dc2.XY()); |
291 | pntcen(i) = pbid; |
292 | par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i)); |
293 | pararg1(i)=ElCLib::Parameter(L1,pnttg1sol(i)); |
294 | par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i)); |
295 | pararg2(i)=ElCLib::Parameter(L2,pnttg2sol(i)); |
296 | parcen3(i)=ElCLib::Parameter(OnCirc,pntcen(i)); |
297 | } |
298 | } |
299 | } |
300 | |