Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1995-1999 Matra Datavision |
973c2be1 | 2 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 3 | // |
973c2be1 | 4 | // This file is part of Open CASCADE Technology software library. |
b311480e | 5 | // |
d5f74e42 | 6 | // This library is free software; you can redistribute it and/or modify it under |
7 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 8 | // by the Free Software Foundation, with special exception defined in the file |
9 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
10 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 11 | // |
973c2be1 | 12 | // Alternatively, this file may be used under the terms of Open CASCADE |
13 | // commercial license or contractual agreement. | |
7fd59977 | 14 | |
15 | #include <ElCLib.hxx> | |
16 | #include <GccAna_Circ2d3Tan.jxx> | |
17 | #include <IntAna2d_AnaIntersection.hxx> | |
18 | #include <IntAna2d_IntPoint.hxx> | |
19 | #include <gp_Lin2d.hxx> | |
20 | #include <gp_Circ2d.hxx> | |
21 | #include <gp_Dir2d.hxx> | |
22 | #include <TColStd_Array1OfReal.hxx> | |
23 | #include <GccAna_Lin2dBisec.hxx> | |
24 | #include <GccEnt_BadQualifier.hxx> | |
25 | ||
26 | //========================================================================= | |
0d969553 Y |
27 | // Creation of a circle tangent to three straight lines. + |
28 | // Create Bissectrices at Qualified1 and Qualified2 and + | |
29 | // Bissectrices at Qualified1 and Qualified3. + | |
30 | // Intersect bissectrices calculated in this way ==> Center points + | |
31 | // Choose the center point that corresponds to qualifiers and + | |
32 | // construct the solution of radius equal to the distance between the + | |
33 | // chosen center point and straight line Qualified1. + | |
7fd59977 | 34 | //========================================================================= |
35 | ||
36 | GccAna_Circ2d3Tan:: | |
37 | GccAna_Circ2d3Tan (const GccEnt_QualifiedLin& Qualified1, | |
38 | const GccEnt_QualifiedLin& Qualified2, | |
39 | const GccEnt_QualifiedLin& Qualified3, | |
35e08fe8 | 40 | const Standard_Real |
7fd59977 | 41 | ): |
42 | ||
43 | //========================================================================= | |
0d969553 | 44 | // Initialization of fields. + |
7fd59977 | 45 | //========================================================================= |
46 | ||
47 | cirsol(1,4) , | |
48 | qualifier1(1,4) , | |
49 | qualifier2(1,4) , | |
50 | qualifier3(1,4) , | |
51 | TheSame1(1,4) , | |
52 | TheSame2(1,4) , | |
53 | TheSame3(1,4) , | |
54 | pnttg1sol(1,4) , | |
55 | pnttg2sol(1,4) , | |
56 | pnttg3sol(1,4) , | |
57 | par1sol(1,4) , | |
58 | par2sol(1,4) , | |
59 | par3sol(1,4) , | |
60 | pararg1(1,4) , | |
61 | pararg2(1,4) , | |
62 | pararg3(1,4) | |
63 | { | |
64 | ||
65 | TheSame1.Init(0); | |
66 | TheSame2.Init(0); | |
67 | TheSame3.Init(0); | |
68 | gp_Dir2d dirx(1.0,0.0); | |
7fd59977 | 69 | WellDone = Standard_False; |
70 | NbrSol = 0; | |
71 | if (!(Qualified1.IsEnclosed() || | |
72 | Qualified1.IsOutside() || Qualified1.IsUnqualified()) || | |
73 | !(Qualified2.IsEnclosed() || | |
74 | Qualified2.IsOutside() || Qualified2.IsUnqualified()) || | |
75 | !(Qualified3.IsEnclosed() || | |
76 | Qualified3.IsOutside() || Qualified3.IsUnqualified())) { | |
77 | GccEnt_BadQualifier::Raise(); | |
78 | return; | |
79 | } | |
80 | ||
81 | //========================================================================= | |
0d969553 | 82 | // Processing. + |
7fd59977 | 83 | //========================================================================= |
84 | ||
85 | gp_Lin2d L1(Qualified1.Qualified()); | |
86 | gp_Lin2d L2(Qualified2.Qualified()); | |
87 | gp_Lin2d L3(Qualified3.Qualified()); | |
88 | gp_Pnt2d origin1(L1.Location()); | |
89 | gp_Dir2d dir1(L1.Direction()); | |
90 | gp_Dir2d normL1(-dir1.Y(),dir1.X()); | |
91 | gp_Pnt2d origin2(L2.Location()); | |
92 | gp_Dir2d dir2(L2.Direction()); | |
93 | gp_Dir2d normL2(-dir2.Y(),dir2.X()); | |
94 | gp_Pnt2d origin3(L3.Location()); | |
95 | gp_Dir2d dir3(L3.Direction()); | |
96 | gp_Dir2d normL3(-dir3.Y(),dir3.X()); | |
97 | Standard_Real xloc1 = origin1.X(); | |
98 | Standard_Real xloc2 = origin2.X(); | |
99 | Standard_Real xloc3 = origin3.X(); | |
100 | Standard_Real yloc1 = origin1.Y(); | |
101 | Standard_Real yloc2 = origin2.Y(); | |
102 | Standard_Real yloc3 = origin3.Y(); | |
103 | Standard_Real xdir1 = dir1.X(); | |
104 | Standard_Real xdir2 = dir2.X(); | |
105 | Standard_Real xdir3 = dir3.X(); | |
106 | Standard_Real ydir1 = dir1.Y(); | |
107 | Standard_Real ydir2 = dir2.Y(); | |
108 | Standard_Real ydir3 = dir3.Y(); | |
109 | GccAna_Lin2dBisec Bisec1(L1,L2); | |
110 | GccAna_Lin2dBisec Bisec2(L1,L3); | |
111 | Standard_Integer ncote1=0; | |
112 | Standard_Integer ncote2=0; | |
113 | Standard_Integer ncote3=0; | |
114 | TColStd_Array1OfReal cote1(1,2); | |
115 | TColStd_Array1OfReal cote2(1,2); | |
116 | TColStd_Array1OfReal cote3(1,2); | |
117 | Standard_Integer nbsol = 0; | |
118 | if (Bisec1.IsDone() && Bisec2.IsDone()) { | |
119 | for (Standard_Integer i = 1 ; i <= Bisec1.NbSolutions() ; i++) { | |
120 | for (Standard_Integer j = 1 ; j <= Bisec2.NbSolutions() ; j++) { | |
121 | IntAna2d_AnaIntersection Intp(Bisec1.ThisSolution(i), | |
122 | Bisec2.ThisSolution(j)); | |
123 | if (Intp.IsDone()) { | |
124 | if (!Intp.IsEmpty()) { | |
125 | for (Standard_Integer k = 1 ; k <= Intp.NbPoints() ; k++) { | |
126 | nbsol++; | |
127 | Standard_Real Radius = (L1.Distance(Intp.Point(k).Value())+ | |
128 | L2.Distance(Intp.Point(k).Value())+ | |
129 | L3.Distance(Intp.Point(k).Value()))/3.0; | |
130 | gp_Pnt2d Center(Intp.Point(k).Value()); | |
131 | Standard_Real cx = Center.X(); | |
132 | Standard_Real cy = Center.Y(); | |
133 | cirsol(nbsol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); | |
134 | // ====================================================== | |
135 | gp_Dir2d dc1(origin1.XY()-Center.XY()); | |
136 | if (!Qualified1.IsUnqualified()) { | |
137 | qualifier1(nbsol) = Qualified1.Qualifier(); | |
138 | } | |
139 | else if (dc1.Dot(normL1) > 0.0) { | |
140 | qualifier1(nbsol) = GccEnt_outside; | |
141 | } | |
142 | else { qualifier1(nbsol) = GccEnt_enclosed; } | |
143 | gp_Dir2d dc2(origin2.XY()-Center.XY()); | |
144 | if (!Qualified2.IsUnqualified()) { | |
145 | qualifier2(nbsol) = Qualified2.Qualifier(); | |
146 | } | |
147 | else if (dc2.Dot(normL2) > 0.0) { | |
148 | qualifier2(nbsol) = GccEnt_outside; | |
149 | } | |
150 | else { qualifier2(nbsol) = GccEnt_enclosed; } | |
151 | gp_Dir2d dc3(origin3.XY()-Center.XY()); | |
152 | if (!Qualified3.IsUnqualified()) { | |
153 | qualifier3(nbsol) = Qualified3.Qualifier(); | |
154 | } | |
155 | else if (dc3.Dot(normL3) > 0.0) { | |
156 | qualifier3(nbsol) = GccEnt_outside; | |
157 | } | |
158 | else { qualifier3(nbsol) = GccEnt_enclosed; } | |
159 | ||
160 | Standard_Real cross1=gp_Dir2d(-ydir1,xdir1) | |
161 | .Dot(gp_Dir2d(xloc1-cx,yloc1-cy)); | |
162 | Standard_Real cross2=gp_Dir2d(-ydir2,xdir2) | |
163 | .Dot(gp_Dir2d(xloc2-cx,yloc2-cy)); | |
164 | Standard_Real cross3=gp_Dir2d(-ydir3,xdir3) | |
165 | .Dot(gp_Dir2d(xloc3-cx,yloc3-cy)); | |
166 | if (cross1 != 0.0) { | |
167 | cross1 = cross1/Abs(cross1); | |
168 | } | |
169 | pnttg1sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+ | |
170 | cross1*Radius*gp_XY(-ydir1,xdir1)); | |
171 | if (cross2 != 0.0) { | |
172 | cross2 = cross2/Abs(cross2); | |
173 | } | |
174 | pnttg2sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+ | |
175 | cross2*Radius*gp_XY(-ydir2,xdir2)); | |
176 | if (cross3 != 0.0) { | |
177 | cross3 = cross3/Abs(cross3); | |
178 | } | |
179 | pnttg3sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+ | |
180 | cross3*Radius*gp_XY(-ydir3,xdir3)); | |
181 | par1sol(nbsol)=ElCLib::Parameter(cirsol(nbsol), | |
182 | pnttg1sol(nbsol)); | |
183 | pararg1(nbsol)=ElCLib::Parameter(L1,pnttg1sol(nbsol)); | |
184 | par2sol(nbsol)=ElCLib::Parameter(cirsol(nbsol), | |
185 | pnttg2sol(nbsol)); | |
186 | pararg2(nbsol)=ElCLib::Parameter(L2,pnttg2sol(nbsol)); | |
187 | par3sol(nbsol)=ElCLib::Parameter(cirsol(nbsol), | |
188 | pnttg3sol(nbsol)); | |
189 | pararg3(nbsol)=ElCLib::Parameter(L3,pnttg3sol(nbsol)); | |
190 | } | |
191 | } | |
192 | WellDone = Standard_True; | |
193 | } | |
194 | } | |
195 | } | |
196 | } | |
197 | if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed() && | |
198 | // ========================================================= | |
199 | Qualified3.IsEnclosed()) { | |
200 | // ======================== | |
201 | ncote1 = 1; | |
202 | ncote2 = 1; | |
203 | ncote3 = 1; | |
204 | cote1(1) = 1.0; | |
205 | cote2(1) = 1.0; | |
206 | cote3(1) = 1.0; | |
207 | } | |
208 | else if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed() && | |
209 | // ============================================================== | |
210 | Qualified3.IsOutside()) { | |
211 | // ======================= | |
212 | ncote1 = 1; | |
213 | ncote2 = 1; | |
214 | ncote3 = 1; | |
215 | cote1(1) = 1.0; | |
216 | cote2(1) = 1.0; | |
217 | cote3(1) = -1.0; | |
218 | } | |
219 | else if (Qualified1.IsEnclosed() && Qualified2.IsOutside() && | |
220 | // ============================================================= | |
221 | Qualified3.IsEnclosed()) { | |
222 | // ======================== | |
223 | ncote1 = 1; | |
224 | ncote2 = 1; | |
225 | ncote3 = 1; | |
226 | cote1(1) = 1.0; | |
227 | cote2(1) = -1.0; | |
228 | cote3(1) = 1.0; | |
229 | } | |
230 | else if (Qualified1.IsEnclosed() && Qualified2.IsOutside() && | |
231 | // ============================================================= | |
232 | Qualified3.IsOutside()) { | |
233 | // ======================= | |
234 | ncote1 = 1; | |
235 | ncote2 = 1; | |
236 | ncote3 = 1; | |
237 | cote1(1) = 1.0; | |
238 | cote2(1) = -1.0; | |
239 | cote3(1) = -1.0; | |
240 | } | |
241 | else if (Qualified1.IsOutside() && Qualified2.IsEnclosed() && | |
242 | // ============================================================= | |
243 | Qualified3.IsEnclosed()) { | |
244 | // ======================== | |
245 | ncote1 = 1; | |
246 | ncote2 = 1; | |
247 | ncote3 = 1; | |
248 | cote1(1) = -1.0; | |
249 | cote2(1) = 1.0; | |
250 | cote3(1) = 1.0; | |
251 | } | |
252 | else if (Qualified1.IsOutside() && Qualified2.IsEnclosed() && | |
253 | // ============================================================= | |
254 | Qualified3.IsOutside()) { | |
255 | // ======================= | |
256 | ncote1 = 1; | |
257 | ncote2 = 1; | |
258 | ncote3 = 1; | |
259 | cote1(1) = -1.0; | |
260 | cote2(1) = 1.0; | |
261 | cote3(1) = -1.0; | |
262 | } | |
263 | else if (Qualified1.IsOutside() && Qualified2.IsOutside() && | |
264 | // ============================================================ | |
265 | Qualified3.IsEnclosed()) { | |
266 | // ======================== | |
267 | ncote1 = 1; | |
268 | ncote2 = 1; | |
269 | ncote3 = 1; | |
270 | cote1(1) = -1.0; | |
271 | cote2(1) = -1.0; | |
272 | cote3(1) = 1.0; | |
273 | } | |
274 | else if (Qualified1.IsOutside() && Qualified2.IsOutside() && | |
275 | // ============================================================ | |
276 | Qualified3.IsOutside()) { | |
277 | // ======================= | |
278 | ncote1 = 1; | |
279 | ncote2 = 1; | |
280 | ncote3 = 1; | |
281 | cote1(1) = -1.0; | |
282 | cote2(1) = -1.0; | |
283 | cote3(1) = -1.0; | |
284 | } | |
285 | else { | |
286 | if (Qualified1.IsUnqualified()) { | |
287 | // ==================================== | |
288 | ncote1 = 2; | |
289 | cote1(1) = 1.0; | |
290 | cote1(2) = -1.0; | |
291 | if (Qualified2.IsUnqualified()) { | |
292 | // =============================== | |
293 | ncote2 = 2; | |
294 | cote2(1) = 1.0; | |
295 | cote2(2) = -1.0; | |
296 | if (Qualified3.IsUnqualified()) { | |
297 | // =============================== | |
298 | ncote3 = 2; | |
299 | cote2(1) = 1.0; | |
300 | cote2(2) = -1.0; | |
301 | NbrSol = nbsol; | |
302 | WellDone = Standard_True; | |
303 | } | |
304 | else if (Qualified3.IsEnclosed()) { | |
305 | // =============================== | |
306 | ncote3 = 1; | |
307 | cote3(1) = 1.0; | |
308 | } | |
309 | else if (Qualified3.IsOutside()) { | |
310 | // ================================ | |
311 | ncote3 = 1; | |
312 | cote3(1) = -1.0; | |
313 | } | |
314 | } | |
315 | else if (Qualified2.IsEnclosed()) { | |
316 | // ================================= | |
317 | ncote2 = 1; | |
318 | cote2(1) = 1.0; | |
319 | if (Qualified3.IsUnqualified()) { | |
320 | // =============================== | |
321 | ncote3 = 2; | |
322 | cote3(1) = 1.0; | |
323 | cote3(1) = -1.0; | |
324 | } | |
325 | else if (Qualified3.IsEnclosed()) { | |
326 | // ================================= | |
327 | ncote3 = 1; | |
328 | cote3(1) = 1.0; | |
329 | } | |
330 | else if (Qualified3.IsOutside()) { | |
331 | // ================================ | |
332 | ncote3 = 1; | |
333 | cote3(1) = -1.0; | |
334 | } | |
335 | } | |
336 | else if (Qualified2.IsOutside()) { | |
337 | // ================================ | |
338 | ncote2 = 1; | |
339 | cote2(1) = -1.0; | |
340 | if (Qualified3.IsUnqualified()) { | |
341 | // =============================== | |
342 | ncote3 = 2; | |
343 | cote3(1) = 1.0; | |
344 | cote3(2) = -1.0; | |
345 | } | |
346 | else if (Qualified3.IsEnclosed()) { | |
347 | // ================================= | |
348 | ncote3 = 1; | |
349 | cote3(1) = 1.0; | |
350 | } | |
351 | else if (Qualified3.IsOutside()) { | |
352 | // ================================ | |
353 | ncote3 = 1; | |
354 | cote3(1) = -1.0; | |
355 | } | |
356 | } | |
357 | } | |
358 | else if (Qualified2.IsUnqualified()) { | |
359 | // =================================== | |
360 | ncote2 = 2; | |
361 | cote2(1) = 1.0; | |
362 | cote2(2) = -1.0; | |
363 | if (Qualified1.IsEnclosed()) { | |
364 | // ============================ | |
365 | ncote1 = 1; | |
366 | cote1(1) = 1.0; | |
367 | if (Qualified3.IsUnqualified()) { | |
368 | // =============================== | |
369 | ncote3 = 2; | |
370 | cote3(1) = -1.0; | |
371 | cote3(1) = -1.0; | |
372 | } | |
373 | else if (Qualified3.IsEnclosed()) { | |
374 | // ================================= | |
375 | ncote3 = 1; | |
376 | cote3(1) = 1.0; | |
377 | } | |
378 | else if (Qualified3.IsOutside()) { | |
379 | // ================================ | |
380 | ncote3 = 1; | |
381 | cote3(1) = -1.0; | |
382 | } | |
383 | } | |
384 | else if (Qualified1.IsOutside()) { | |
385 | // ================================ | |
386 | ncote1 = 1; | |
387 | cote1(1) = 1.0; | |
388 | if (Qualified3.IsUnqualified()) { | |
389 | // =============================== | |
390 | ncote3 = 2; | |
391 | cote3(1) = 1.0; | |
392 | cote3(2) = -1.0; | |
393 | } | |
394 | else if (Qualified3.IsEnclosed()) { | |
395 | // ================================= | |
396 | ncote3 = 1; | |
397 | cote3(1) = 1.0; | |
398 | } | |
399 | else if (Qualified3.IsOutside()) { | |
400 | // ================================ | |
401 | ncote3 = 1; | |
402 | cote3(1) = -1.0; | |
403 | } | |
404 | } | |
405 | } | |
406 | else if (Qualified3.IsUnqualified()) { | |
407 | // =================================== | |
408 | ncote3 = 2; | |
409 | cote3(1) = 1.0; | |
410 | cote3(2) = -1.0; | |
411 | if (Qualified1.IsEnclosed()) { | |
412 | // ============================ | |
413 | ncote1 = 1; | |
414 | cote1(1) = 1.0; | |
415 | if (Qualified2.IsEnclosed()) { | |
416 | // ============================ | |
417 | ncote2 = 1; | |
418 | cote2(1) = 1.0; | |
419 | } | |
420 | else if (Qualified2.IsOutside()) { | |
421 | // =============================== | |
422 | ncote2 = 1; | |
423 | cote2(1) = -1.0; | |
424 | } | |
425 | } | |
426 | else if (Qualified1.IsOutside()) { | |
427 | // ================================ | |
428 | ncote1 = 1; | |
429 | cote1(1) = -1.0; | |
430 | if (Qualified2.IsEnclosed()) { | |
431 | // ============================ | |
432 | ncote2 = 1; | |
433 | cote2(1) = 1.0; | |
434 | } | |
435 | else if (Qualified2.IsOutside()) { | |
436 | // =============================== | |
437 | ncote2 = 1; | |
438 | cote2(1) = -1.0; | |
439 | } | |
440 | } | |
441 | } | |
442 | } | |
443 | if (NbrSol > 0) { return; } | |
444 | for (Standard_Integer i = 1 ; i <= nbsol ; i++) { | |
445 | for (Standard_Integer j1 = 1 ; j1 <= ncote1 ; j1++) { | |
446 | for (Standard_Integer j2 = 1 ; j2 <= ncote2 ; j2++) { | |
447 | for (Standard_Integer j3 = 1 ; j3 <= ncote3 ; j3++) { | |
448 | if ((cote2(j2)*((cirsol(i).Location().X()-origin2.X())* | |
449 | (-dir2.Y())+(cirsol(i).Location().Y()- | |
450 | origin2.Y())*(dir2.X())) > 0.0) && | |
451 | (cote3(j3)*((cirsol(i).Location().X()-origin3.X())* | |
452 | (-dir3.Y())+(cirsol(i).Location().Y()- | |
453 | origin3.Y())*(dir3.X())) > 0.0) && | |
454 | (cote1(j1)*((cirsol(i).Location().X()-origin1.X())* | |
455 | (-dir1.Y())+(cirsol(i).Location().Y()- | |
456 | origin1.Y())*(dir1.X())) > 0.0)) { | |
457 | NbrSol++; | |
458 | cirsol(NbrSol) = gp_Circ2d(cirsol(i)); | |
459 | // ===================================== | |
460 | Standard_Real Radius = cirsol(NbrSol).Radius(); | |
461 | gp_Pnt2d Center(cirsol(NbrSol).Location()); | |
462 | gp_Dir2d dc(origin1.XY()-Center.XY()); | |
463 | Standard_Real sign = dc.Dot(gp_Dir2d(-dir1.Y(),dir1.X())); | |
464 | dc = gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X())); | |
465 | pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY()); | |
466 | dc = gp_Dir2d(origin2.XY()-Center.XY()); | |
467 | sign = dc.Dot(gp_Dir2d(-dir2.Y(),dir2.X())); | |
468 | dc = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X())); | |
469 | pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY()); | |
470 | dc = gp_Dir2d(origin3.XY()-Center.XY()); | |
471 | sign = dc.Dot(gp_Dir2d(-dir3.Y(),dir3.X())); | |
472 | dc = gp_Dir2d(sign*gp_XY(-dir3.Y(),dir3.X())); | |
473 | pnttg3sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY()); | |
474 | par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
475 | pnttg1sol(NbrSol)); | |
476 | pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol)); | |
477 | par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
478 | pnttg2sol(NbrSol)); | |
479 | pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol)); | |
480 | par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), | |
481 | pnttg3sol(NbrSol)); | |
482 | pararg3(NbrSol)=ElCLib::Parameter(L3,pnttg3sol(NbrSol)); | |
483 | } | |
484 | } | |
485 | } | |
486 | } | |
487 | } | |
488 | } |