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