mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-13 14:27:08 +03:00
Macro NO_CXX_EXCEPTION was removed from code. Method Raise() was replaced by explicit throw statement. Method Standard_Failure::Caught() was replaced by normal C++mechanism of exception transfer. Method Standard_Failure::Caught() is deprecated now. Eliminated empty constructors. Updated samples. Eliminate empty method ChangeValue from NCollection_Map class. Removed not operable methods from NCollection classes.
748 lines
25 KiB
C++
748 lines
25 KiB
C++
// Copyright (c) 1995-1999 Matra Datavision
|
|
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
|
//
|
|
// This file is part of Open CASCADE Technology software library.
|
|
//
|
|
// This library is free software; you can redistribute it and/or modify it under
|
|
// the terms of the GNU Lesser General Public License version 2.1 as published
|
|
// by the Free Software Foundation, with special exception defined in the file
|
|
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
|
// distribution for complete text of the license and disclaimer of any warranty.
|
|
//
|
|
// Alternatively, this file may be used under the terms of Open CASCADE
|
|
// commercial license or contractual agreement.
|
|
|
|
|
|
#include <ElCLib.hxx>
|
|
#include <GccAna_Circ2d2TanRad.hxx>
|
|
#include <GccEnt_BadQualifier.hxx>
|
|
#include <GccEnt_QualifiedCirc.hxx>
|
|
#include <GccEnt_QualifiedLin.hxx>
|
|
#include <gp_Ax2d.hxx>
|
|
#include <gp_Circ2d.hxx>
|
|
#include <gp_Lin2d.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <IntAna2d_AnaIntersection.hxx>
|
|
#include <IntAna2d_IntPoint.hxx>
|
|
#include <Precision.hxx>
|
|
#include <Standard_NegativeValue.hxx>
|
|
#include <Standard_OutOfRange.hxx>
|
|
#include <StdFail_NotDone.hxx>
|
|
|
|
// circular tangent to two cercles and given radius
|
|
//====================================================
|
|
//==================================================================
|
|
// Initialize WellDone to false. +
|
|
// Return circle C1 and circle C2. +
|
|
// Leave with error if the construction is impossible. +
|
|
// Distinguish boundary cases to process them separately. +
|
|
// Create parallel to C1 in the proper direction. +
|
|
// Create parallel to C2 in the proper direction. +
|
|
// Intersect parallels ==> center point of the solution. +
|
|
// Create the solution to be added to already found solutions. +
|
|
// Fill the fields. +
|
|
//==================================================================
|
|
GccAna_Circ2d2TanRad::
|
|
GccAna_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1 ,
|
|
const GccEnt_QualifiedCirc& Qualified2 ,
|
|
const Standard_Real Radius ,
|
|
const Standard_Real Tolerance ):
|
|
qualifier1(1,8) ,
|
|
qualifier2(1,8),
|
|
TheSame1(1,8) ,
|
|
TheSame2(1,8) ,
|
|
cirsol(1,8) ,
|
|
pnttg1sol(1,8) ,
|
|
pnttg2sol(1,8) ,
|
|
par1sol(1,8) ,
|
|
par2sol(1,8) ,
|
|
pararg1(1,8) ,
|
|
pararg2(1,8)
|
|
{
|
|
|
|
Standard_Real Tol = Abs(Tolerance);
|
|
gp_Dir2d dirx(1.,0.);
|
|
WellDone = Standard_False;
|
|
NbrSol = 0;
|
|
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
|
|
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
|
|
!(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
|
|
Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
|
|
throw GccEnt_BadQualifier();
|
|
return;
|
|
}
|
|
Standard_Boolean invers = Standard_False;
|
|
gp_Circ2d C1 = Qualified1.Qualified();
|
|
gp_Circ2d C2 = Qualified2.Qualified();
|
|
Standard_Real R1 = C1.Radius();
|
|
Standard_Real R2 = C2.Radius();
|
|
Standard_Real rbid = 0.;
|
|
Standard_Integer signe=0;
|
|
Standard_Real R3;
|
|
Standard_Real dist;
|
|
TColgp_Array1OfCirc2d C(1,8);
|
|
C(1) = gp_Circ2d(C1);
|
|
C(2) = gp_Circ2d(C2);
|
|
Standard_Integer nbsol = 0;
|
|
gp_Pnt2d center1(C1.Location());
|
|
gp_Pnt2d center2(C2.Location());
|
|
gp_Pnt2d center3;
|
|
if (Radius < 0.0) { throw Standard_NegativeValue(); }
|
|
else if ( C(2).Location().IsEqual(C(1).Location(),Precision::Confusion())){
|
|
WellDone = Standard_True;
|
|
}
|
|
else {
|
|
gp_Dir2d dir1(C(2).Location().XY()-C(1).Location().XY());
|
|
dist = (center2).Distance(center1);
|
|
if ((Qualified1.IsEnclosed()) && Qualified2.IsEnclosed()) {
|
|
// =========================================================
|
|
if (Radius*2.0-Abs(R1+R2-dist) > Tol) { WellDone = Standard_True; }
|
|
else {
|
|
if ((dist-R1-R2>Tol)||(Tol<Max(R1,R2)-dist-Min(R1,R2))) {
|
|
WellDone = Standard_True;
|
|
}
|
|
else if (Abs(dist-R1-R2)<=Tol||Abs(Max(R1,R2)-dist-Min(R1,R2))<=Tol) {
|
|
if (Abs(dist-R1-R2) <= Tol) {
|
|
rbid = R2+(dist-R1-R2)/2.0;
|
|
signe = -1;
|
|
}
|
|
else if (Abs(Max(R1,R2)-dist-Min(R1,R2)) <= Tol) {
|
|
if (R1 > R2) { R3 = R2; }
|
|
else {
|
|
C2 = gp_Circ2d(C1);
|
|
R3 = R1;
|
|
}
|
|
rbid = -R3+(Min(R1,R2)+dist-Max(R1,R2))/2.;
|
|
signe = 1;
|
|
}
|
|
gp_Ax2d axe(gp_Pnt2d(center2.XY()-rbid*dir1.XY()),dirx);
|
|
cirsol(1) = gp_Circ2d(axe,Radius);
|
|
// =================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg1sol(1)=gp_Pnt2d(center2.XY()+signe*R2*dir1.XY());
|
|
pnttg2sol(1)=gp_Pnt2d(center1.XY()+R1*dir1.XY());
|
|
TheSame1(1) = 0;
|
|
TheSame2(1) = 0;
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
}
|
|
else {
|
|
C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
|
|
C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Abs(Radius-R2));
|
|
nbsol = 1;
|
|
}
|
|
}
|
|
}
|
|
else if (((Qualified1.IsEnclosed()) && Qualified2.IsEnclosing()) ||
|
|
// ===================================================================
|
|
((Qualified1.IsEnclosing()) && Qualified2.IsEnclosed())) {
|
|
// ========================================================
|
|
if (Qualified1.IsEnclosing()) {
|
|
R3 = R1;
|
|
C(1) = gp_Circ2d(C2);
|
|
R1 = R2;
|
|
C(2) = gp_Circ2d(C1);
|
|
R2 = R3;
|
|
center3 = center1;
|
|
center1 = center2;
|
|
center2 = center3;
|
|
dir1.Reverse();
|
|
// it is necessary to swap the resulting tangency points
|
|
invers = Standard_True;
|
|
}
|
|
if ((R2-Radius>Tol) || (Tol<Radius-R1) || (Tol>R1-dist-R2) ||
|
|
((Tol<Radius*2-R1-dist-R2)||(Tol<R1+R2-dist-Radius*2.0))) {
|
|
WellDone = Standard_True;
|
|
}
|
|
else if ((Abs(R2-Radius)<=Tol) || (Abs(R1-Radius)<=Tol)) {
|
|
if (Abs(R2-Radius) <= Tol) {
|
|
C(2) = gp_Circ2d(C2);
|
|
R3 = R2;
|
|
TheSame2(1) = 1;
|
|
TheSame1(1) = 0;
|
|
pnttg1sol(1) = gp_Pnt2d(C(2).Location().XY()+R3*dir1.XY());
|
|
}
|
|
else if (Abs(Radius-R1) <= Tol) {
|
|
C(2) = gp_Circ2d(C1);
|
|
R3 = R1;
|
|
TheSame1(1) = 1;
|
|
TheSame2(1) = 0;
|
|
pnttg2sol(1) = gp_Pnt2d(C(2).Location().XY()+R3*dir1.XY());
|
|
}
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
gp_Ax2d axe(C(2).Location(),dirx);
|
|
cirsol(1) = gp_Circ2d(axe,Radius);
|
|
// =================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
}
|
|
else {
|
|
if ((Abs(R2+dist-R1) <= Tol) || (Abs(Radius*2.0-R1-dist-R2) < Tol)) {
|
|
if (Abs(R2+dist-R1) <= Tol) { signe = 1; }
|
|
else if (Abs(Radius*2.0-R1-dist-R2) < Tol) {signe = -1; }
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
gp_Ax2d axe(gp_Pnt2d(center1.XY()+
|
|
signe*(R1-Radius)*dir1.XY()),dirx);
|
|
cirsol(1) = gp_Circ2d(axe,Radius);
|
|
// =================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(center1.XY()+signe*R1*dir1.XY());
|
|
pnttg2sol(1)=gp_Pnt2d(center2.XY()+R2*dir1.XY());
|
|
TheSame1(1) = 0;
|
|
TheSame2(1) = 0;
|
|
}
|
|
else {
|
|
C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
|
|
C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Abs(Radius-R2));
|
|
nbsol = 1;
|
|
}
|
|
}
|
|
}
|
|
else if (((Qualified1.IsEnclosed()) && (Qualified2.IsOutside())) ||
|
|
// ===================================================================
|
|
((Qualified1.IsOutside()) && (Qualified2.IsEnclosed()))) {
|
|
// ========================================================
|
|
if (Qualified1.IsOutside()) {
|
|
C(2) = gp_Circ2d(C1);
|
|
C(1) = gp_Circ2d(C2);
|
|
R3 = R1;
|
|
R1 = R2;
|
|
R2 = R3;
|
|
center3 = center1;
|
|
center1 = center2;
|
|
center2 = center3;
|
|
dir1.Reverse();
|
|
// it is necessary to swap the resulting tangency points
|
|
invers = Standard_True;
|
|
}
|
|
if ((Radius-R1>Tol)||(dist-R2-R1>Tol)||
|
|
((R2-dist-R1+Radius*2>Tol)||(R1-R2-dist-Radius*2>Tol))){
|
|
WellDone = Standard_True;
|
|
}
|
|
else {
|
|
if (((Radius-R1 > 0.0) && (Abs(dist-R1-R2) <= Tol)) ||
|
|
(Abs(R1-R2+dist-Radius*2.0) <= Tol) ||
|
|
(Abs(R1-R2-dist-Radius*2.0) <= Tol) || (Abs(dist-R1-R2) <= Tol)) {
|
|
if (Abs(R1-R2+dist-Radius*2.0) <= Tol) {
|
|
signe = -1;
|
|
}
|
|
else {
|
|
signe = 1;
|
|
if ((Radius-R1 > 0.0) && (Abs(dist-R1-R2) <= Tol)) {
|
|
R2 = R1;
|
|
}
|
|
else if (Abs(dist-R1-R2) <= Tol) {
|
|
R2 = R1;
|
|
if (Abs(R1-Radius) <= Tol) {
|
|
TheSame1(1) = 1;
|
|
}
|
|
}
|
|
}
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
gp_Ax2d axe(gp_Pnt2d(center1.XY()+
|
|
signe*(R1-Radius)*dir1.XY()),dirx);
|
|
cirsol(1) = gp_Circ2d(axe,Radius);
|
|
// =================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(center1.XY()+signe*R1*dir1.XY());
|
|
pnttg2sol(1) = gp_Pnt2d(center2.XY()+signe*R2*dir1.XY());
|
|
TheSame1(1) = 0;
|
|
TheSame2(1) = 0;
|
|
}
|
|
else {
|
|
C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
|
|
C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
|
|
nbsol = 1;
|
|
}
|
|
}
|
|
}
|
|
else if (((Qualified1.IsEnclosed()) && (Qualified2.IsUnqualified())) ||
|
|
// =======================================================================
|
|
((Qualified1.IsUnqualified()) && (Qualified2.IsEnclosed()))) {
|
|
// ============================================================
|
|
if (Qualified1.IsUnqualified()) {
|
|
C(1) = gp_Circ2d(C2);
|
|
C(2) = gp_Circ2d(C1);
|
|
R3 = R1;
|
|
R1 = R2;
|
|
R2 = R3;
|
|
center3 = center1;
|
|
center1 = center2;
|
|
center2 = center3;
|
|
dir1.Reverse();
|
|
// it is necessary to swap the resulting tangency points
|
|
invers = Standard_True;
|
|
}
|
|
if ((Radius-R1 > Tol) || (dist-R2-R1 > Tol)) { WellDone = Standard_True; }
|
|
else {
|
|
if ((Abs(dist-R2-R1) <= Tol) || (Abs(Radius-R1) <= Tol)) {
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
gp_Ax2d ax(gp_Pnt2d(center1.XY()+(R1-Radius)*dir1.XY()),dirx);
|
|
cirsol(1) = gp_Circ2d(ax,Radius);
|
|
// ================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg2sol(1) = gp_Pnt2d(center1.XY()+(dist-R2)*dir1.XY());
|
|
TheSame2(1) = 0;
|
|
if (Abs(Radius-R1) > 0.0) {
|
|
TheSame1(1) = 1;
|
|
}
|
|
else {
|
|
TheSame1(1) = 0;
|
|
pnttg1sol(1) = gp_Pnt2d(center1.XY()+R1*dir1.XY());
|
|
}
|
|
}
|
|
else {
|
|
C(3) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
|
|
C(4) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
|
|
C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
|
|
C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Abs(Radius-R2));
|
|
nbsol = 2;
|
|
}
|
|
}
|
|
}
|
|
else if ((Qualified1.IsEnclosing()) && (Qualified2.IsEnclosing())) {
|
|
// ==================================================================
|
|
if ((Tol < Max(R1,R2)-Radius) || (Tol < Max(R1,R2)-dist-Min(R1,R2)) ||
|
|
(dist+R1+R2-Radius*2.0 > Tol)) { WellDone = Standard_True; }
|
|
else {
|
|
if ((Abs(dist+Min(R1,R2)-Max(R1,R2)) <= Tol) ||
|
|
(Abs(R1+R2+dist-2.0*Radius) <= Tol)) {
|
|
if (Abs(dist+Min(R1,R2)-Max(R1,R2)) <= Tol) {
|
|
signe = 1;
|
|
}
|
|
else {
|
|
signe = -1;
|
|
}
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
gp_Ax2d axe(gp_Pnt2d(center1.XY()+
|
|
signe*(R1-Radius)*dir1.XY()),dirx);
|
|
cirsol(1) = gp_Circ2d(axe,Radius);
|
|
// =================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(center1.XY()+R1*dir1.XY());
|
|
pnttg2sol(1) = gp_Pnt2d(center2.XY()+signe*R2*dir1.XY());
|
|
TheSame1(1) = 0;
|
|
TheSame2(1) = 0;
|
|
}
|
|
else if (Abs(Radius-Max(R1,R2)) <= Tol) {
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
if (R1 > R2) {
|
|
C(1) = gp_Circ2d(C1);
|
|
C(2) = gp_Circ2d(C2);
|
|
TheSame1(1) = 1;
|
|
TheSame2(1) = 0;
|
|
pnttg2sol(1) = gp_Pnt2d(center1.XY()+(dist+R2)*dir1.XY());
|
|
}
|
|
else {
|
|
C(1) = gp_Circ2d(C2);
|
|
C(2) = gp_Circ2d(C1);
|
|
TheSame1(1) = 0;
|
|
TheSame2(1) = 1;
|
|
pnttg1sol(1) = gp_Pnt2d(center1.XY()-R1*dir1.XY());
|
|
}
|
|
gp_Ax2d axe(C(1).Location(),dirx);
|
|
cirsol(1) = gp_Circ2d(axe,Radius);
|
|
// =================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
}
|
|
else {
|
|
C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
|
|
C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Abs(Radius-R2));
|
|
nbsol = 1;
|
|
}
|
|
}
|
|
}
|
|
else if (((Qualified1.IsEnclosing()) && (Qualified2.IsOutside())) ||
|
|
// ====================================================================
|
|
((Qualified1.IsOutside()) && (Qualified2.IsEnclosing()))) {
|
|
// =========================================================
|
|
if (Qualified1.IsOutside()) {
|
|
C(1) = gp_Circ2d(C2);
|
|
C(2) = gp_Circ2d(C1);
|
|
R3 = R1;
|
|
R1 = R2;
|
|
R2 = R3;
|
|
center3 = center1;
|
|
center1 = center2;
|
|
center2 = center3;
|
|
dir1.Reverse();
|
|
// it is necessary to swap the resulting tangency points
|
|
invers = Standard_True;
|
|
}
|
|
if ((R1-Radius > Tol) || (Tol < R1+R2-dist) ||
|
|
(dist-R2+R1-Radius*2.0>Tol)) {
|
|
WellDone = Standard_True;
|
|
}
|
|
else if (((Abs(R1-Radius)<=Tol) || (Abs(R1+R2-dist)<=Tol))||
|
|
(Abs(dist-R2+R1-Radius*2.0) <= Tol)) {
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
if((Abs(R1-Radius) <= Tol) || (Abs(R1+R2-dist) <= Tol)){
|
|
TheSame1(1) = 1;
|
|
}
|
|
else {
|
|
TheSame1(1) = 0;
|
|
}
|
|
TheSame2(1) = 0;
|
|
gp_Ax2d axe(gp_Pnt2d(center1.XY()+(R1-Radius)*dir1.XY()),dirx);
|
|
cirsol(1) = gp_Circ2d(axe,Radius);
|
|
// =================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(center1.XY()-R1*dir1.XY());
|
|
pnttg2sol(1) = gp_Pnt2d(center1.XY()+(dist-R2)*dir1.XY());
|
|
}
|
|
else {
|
|
C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
|
|
C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
|
|
nbsol = 1;
|
|
}
|
|
}
|
|
else if (((Qualified1.IsEnclosing()) && (Qualified2.IsUnqualified())) ||
|
|
// ========================================================================
|
|
((Qualified1.IsUnqualified()) && (Qualified2.IsEnclosing()))) {
|
|
// =============================================================
|
|
if (Qualified1.IsUnqualified()) {
|
|
C(1) = gp_Circ2d(C2);
|
|
C(2) = gp_Circ2d(C1);
|
|
R3 = R1;
|
|
R1 = R2;
|
|
R2 = R3;
|
|
center3 = center1;
|
|
center1 = center2;
|
|
center2 = center3;
|
|
invers = Standard_True;
|
|
dir1.Reverse();
|
|
}
|
|
if ((Tol < R1-dist-R2) || (R1-Radius > Tol)) { WellDone = Standard_True; }
|
|
else if ((Abs(R1-Radius) <= Tol) || (Abs(R1-dist-R2) > 0.0)) {
|
|
if (Abs(R1-Radius) <= Tol) {
|
|
TheSame1(1) = 1;
|
|
if((Abs(Radius-R2) <= Tol) &&
|
|
(center1.Distance(center2) <= Tol)) {
|
|
TheSame2(1) = 1;
|
|
}
|
|
}
|
|
else if (Abs(R1-dist-R2) > 0.0) {
|
|
TheSame1(1) = 0;
|
|
TheSame2(1) = 0;
|
|
}
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
gp_Ax2d axe(gp_Pnt2d(center1.XY()+(Radius-R1)*dir1.XY()),dirx);
|
|
cirsol(1) = gp_Circ2d(axe,Radius);
|
|
// =================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(center1.XY()+R1*dir1.XY());
|
|
pnttg2sol(1) = gp_Pnt2d(center1.XY()+(dist+R2)*dir1.XY());
|
|
}
|
|
else {
|
|
C(3) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
|
|
C(4) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
|
|
C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R1));
|
|
C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Abs(Radius-R2));
|
|
nbsol = 2;
|
|
}
|
|
}
|
|
else if ((Qualified1.IsOutside()) && (Qualified2.IsOutside())) {
|
|
// ==============================================================
|
|
if (Tol < Max(R1,R2)-dist-Min(R1,R2)) { WellDone = Standard_True; }
|
|
else if (dist-R1-R2-Radius*2.0 > Tol) { WellDone = Standard_True; }
|
|
else {
|
|
if (Abs(dist+Min(R1,R2)-Max(R1,R2)) <= Tol) {
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
if (R1 < R2) { signe = -1; }
|
|
else { signe = 1; }
|
|
gp_Ax2d axe(gp_Pnt2d(center1.XY()+signe*(Radius+R1)*dir1.XY()),
|
|
dirx);
|
|
cirsol(1) = gp_Circ2d(axe,Radius);
|
|
// =================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(center1.XY()+signe*R1*dir1.XY());
|
|
pnttg2sol(1) = gp_Pnt2d(pnttg1sol(1));
|
|
TheSame1(1) = 0;
|
|
TheSame2(1) = 0;
|
|
}
|
|
else if (Abs(dist-R1-R2-Radius*2.0) <= Tol) {
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
gp_Ax2d ax(gp_Pnt2d(center1.XY()+(R1+Radius)*dir1.XY()),dirx);
|
|
cirsol(1) = gp_Circ2d(ax,Radius);
|
|
// ================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(center1.XY()+R1*dir1.XY());
|
|
pnttg2sol(1) = gp_Pnt2d(center2.XY()-R2*dir1.XY());
|
|
TheSame1(1) = 0;
|
|
TheSame2(1) = 0;
|
|
}
|
|
else {
|
|
C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Radius+R1);
|
|
C(2) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
|
|
nbsol = 1;
|
|
}
|
|
}
|
|
}
|
|
else if (((Qualified1.IsOutside()) && (Qualified2.IsUnqualified())) ||
|
|
// ======================================================================
|
|
((Qualified1.IsUnqualified()) && (Qualified2.IsOutside()))) {
|
|
// ===========================================================
|
|
if (Qualified1.IsUnqualified()) {
|
|
C(1) = gp_Circ2d(C2);
|
|
R3 = R1;
|
|
R1 = R2;
|
|
C(2) = gp_Circ2d(C1);
|
|
R2 = R3;
|
|
center3 = center1;
|
|
center1 = center2;
|
|
center2 = center3;
|
|
dir1.Reverse();
|
|
// it is necessary to swap the resulting tangency points
|
|
invers = Standard_True;
|
|
}
|
|
if (Tol < R1-dist-R2) { WellDone = Standard_True; }
|
|
else if ((Tol < R2-dist-R1) && (Tol < Radius*2.0-R2-dist+R1)) {
|
|
WellDone = Standard_True;
|
|
}
|
|
else if ((dist-R1-R2 > Tol) && (Tol < dist-R1-R2-Radius*2.0)) {
|
|
WellDone = Standard_True;
|
|
}
|
|
else {
|
|
if ((Abs(R1-R2-dist)<=Tol) ||
|
|
((Abs(dist-R1-R2)<=Tol) && (Abs(Radius*2.0-dist+R1+R2) <= Tol)) ||
|
|
((Abs(dist+R1-R2)<=Tol) && (Abs(R2+dist-R1-Radius*2.0)<=Tol))) {
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
gp_Ax2d axe(gp_Pnt2d(center1.XY()+(Radius+R1)*dir1.XY()),
|
|
dirx);
|
|
cirsol(1) = gp_Circ2d(axe,Radius);
|
|
// =================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(center1.XY()+R1*dir1.XY());
|
|
pnttg2sol(1) = gp_Pnt2d(center1.XY()+(dist+R2)*dir1.XY());
|
|
TheSame1(1) = 0;
|
|
TheSame2(1) = 0;
|
|
}
|
|
else {
|
|
C(3) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Radius+R1);
|
|
C(4) = gp_Circ2d(gp_Ax2d(C(2).Location(),dirx),Radius+R2);
|
|
C(1) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Radius+R1);
|
|
C(2) = gp_Circ2d(gp_Ax2d(C(1).Location(),dirx),Abs(Radius-R2));
|
|
nbsol = 2;
|
|
}
|
|
}
|
|
}
|
|
else if ((Qualified1.IsUnqualified()) && (Qualified2.IsUnqualified())) {
|
|
// ======================================================================
|
|
if ((dist-R1-R2>Tol)&&(Tol<(dist-R1-R2-Radius*2))) {
|
|
WellDone = Standard_True;
|
|
}
|
|
else if ((Max(R1,R2)-dist-Min(R1,R2)>Tol) &&
|
|
(((Max(R1,R2)-dist-Min(R1,R2))-Radius*2.0 > Tol))) {
|
|
WellDone = Standard_True;
|
|
}
|
|
else {
|
|
Standard_Real p3 = Max(R1,R2)-Min(R1,R2)-dist-Radius*2.0;
|
|
Standard_Real p4 = dist-R1-R2;
|
|
Standard_Real p5 = Radius*2.0-dist+R1+R2;
|
|
if (p3 > 0.0) {
|
|
dist = Max(R1,R2)-Min(R1,R2)-Radius*2.0;
|
|
}
|
|
else if (p4 > 0.0 && p5 < 0.0) {
|
|
R1 = dist-R2-Radius*2.0;
|
|
}
|
|
C(1) = gp_Circ2d(gp_Ax2d(center1,dirx),Abs(Radius-R1));
|
|
C(2) = gp_Circ2d(gp_Ax2d(center2,dirx),Abs(Radius-R2));
|
|
C(3) = gp_Circ2d(gp_Ax2d(center1,dirx),Abs(Radius-R1));
|
|
C(4) = gp_Circ2d(gp_Ax2d(center2,dirx),Radius+R2);
|
|
C(5) = gp_Circ2d(gp_Ax2d(center1,dirx),Radius+R1);
|
|
C(6) = gp_Circ2d(gp_Ax2d(center2,dirx),Abs(Radius-R2));
|
|
C(7) = gp_Circ2d(gp_Ax2d(center1,dirx),Radius+R1);
|
|
C(8) = gp_Circ2d(gp_Ax2d(center2,dirx),Radius+R2);
|
|
nbsol = 4;
|
|
}
|
|
}
|
|
if (nbsol > 0) {
|
|
for (Standard_Integer j = 1 ; j <= nbsol ; j++) {
|
|
IntAna2d_AnaIntersection Intp(C(2*j-1),C(2*j));
|
|
if (Intp.IsDone()) {
|
|
if (!Intp.IsEmpty()) {
|
|
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
|
|
NbrSol++;
|
|
gp_Pnt2d Center(Intp.Point(i).Value());
|
|
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
|
|
// =======================================================
|
|
dir1 = gp_Dir2d(Center.XY()-center1.XY());
|
|
gp_Dir2d dir2(Center.XY()-center2.XY());
|
|
Standard_Real distcc1 = Center.Distance(center1);
|
|
Standard_Real distcc2 = Center.Distance(center2);
|
|
if (!Qualified1.IsUnqualified()) {
|
|
qualifier1(NbrSol) = Qualified1.Qualifier();
|
|
}
|
|
else if (Abs(distcc1+Radius-R1) < Tol) {
|
|
qualifier1(NbrSol) = GccEnt_enclosed;
|
|
}
|
|
else if (Abs(distcc1-R1-Radius) < Tol) {
|
|
qualifier1(NbrSol) = GccEnt_outside;
|
|
}
|
|
else { qualifier1(NbrSol) = GccEnt_enclosing; }
|
|
if (!Qualified2.IsUnqualified()) {
|
|
qualifier2(NbrSol) = Qualified2.Qualifier();
|
|
}
|
|
else if (Abs(distcc2+Radius-R2) < Tol) {
|
|
qualifier2(NbrSol) = GccEnt_enclosed;
|
|
}
|
|
else if (Abs(distcc2-R2-Radius) < Tol) {
|
|
qualifier2(NbrSol) = GccEnt_outside;
|
|
}
|
|
else { qualifier2(NbrSol) = GccEnt_enclosing; }
|
|
if ((Center.Distance(center1) > R1) &&
|
|
(Radius < Center.Distance(center1)+R1)) {
|
|
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1.XY());
|
|
}
|
|
else if ((Center.Distance(center1) < R1) &&
|
|
(Radius < R1)) {
|
|
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dir1.XY());
|
|
}
|
|
else {
|
|
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1.XY());
|
|
}
|
|
if ((Center.Distance(center2) > R2) &&
|
|
(Radius < Center.Distance(center2)+R2)) {
|
|
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir2.XY());
|
|
}
|
|
else if ((Center.Distance(center2) < R2) &&
|
|
(Radius < R2)) {
|
|
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dir2.XY());
|
|
}
|
|
else {
|
|
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir2.XY());
|
|
}
|
|
TheSame1(NbrSol) = 0;
|
|
TheSame2(NbrSol) = 0;
|
|
}
|
|
}
|
|
WellDone = Standard_True;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// swapping of resulting tangency points if necessary
|
|
if (invers) {
|
|
gp_Pnt2d Psav;
|
|
for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
|
|
Psav = pnttg1sol(i);
|
|
pnttg1sol(i) = pnttg2sol(i);
|
|
pnttg2sol(i) = Psav;
|
|
}
|
|
}
|
|
// calculation of parameters of tangency points
|
|
for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
|
|
par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
|
|
if (TheSame1(i) == 0) {
|
|
pararg1(i)=ElCLib::Parameter(C1,pnttg1sol(i));
|
|
}
|
|
par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
|
|
if (TheSame2(i) == 0) {
|
|
pararg2(i)=ElCLib::Parameter(C2,pnttg2sol(i));
|
|
}
|
|
}
|
|
}
|
|
|
|
Standard_Boolean GccAna_Circ2d2TanRad::
|
|
IsDone () const { return WellDone; }
|
|
|
|
Standard_Integer GccAna_Circ2d2TanRad::
|
|
NbSolutions () const { return NbrSol; }
|
|
|
|
gp_Circ2d GccAna_Circ2d2TanRad::
|
|
ThisSolution (const Standard_Integer Index) const
|
|
{
|
|
if (!WellDone) { throw StdFail_NotDone(); }
|
|
if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
|
|
return cirsol(Index);
|
|
}
|
|
|
|
void GccAna_Circ2d2TanRad::
|
|
WhichQualifier(const Standard_Integer Index ,
|
|
GccEnt_Position& Qualif1 ,
|
|
GccEnt_Position& Qualif2 ) const
|
|
{
|
|
if (!WellDone) { throw StdFail_NotDone(); }
|
|
if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
|
|
|
|
Qualif1 = qualifier1(Index);
|
|
Qualif2 = qualifier2(Index);
|
|
}
|
|
|
|
void GccAna_Circ2d2TanRad::
|
|
Tangency1 (const Standard_Integer Index,
|
|
Standard_Real& ParSol,
|
|
Standard_Real& ParArg,
|
|
gp_Pnt2d& PntSol) const{
|
|
if (!WellDone) { throw StdFail_NotDone(); }
|
|
else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
|
|
else {
|
|
if (TheSame1(Index) == 0) {
|
|
ParSol = par1sol(Index);
|
|
ParArg = pararg1(Index);
|
|
PntSol = gp_Pnt2d(pnttg1sol(Index));
|
|
}
|
|
else { throw StdFail_NotDone(); }
|
|
}
|
|
}
|
|
|
|
void GccAna_Circ2d2TanRad::
|
|
Tangency2 (const Standard_Integer Index,
|
|
Standard_Real& ParSol,
|
|
Standard_Real& ParArg,
|
|
gp_Pnt2d& PntSol) const{
|
|
if (!WellDone) { throw StdFail_NotDone(); }
|
|
else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
|
|
else {
|
|
if (TheSame2(Index) == 0) {
|
|
ParSol = par2sol(Index);
|
|
ParArg = pararg2(Index);
|
|
PntSol = gp_Pnt2d(pnttg2sol(Index));
|
|
}
|
|
else { throw StdFail_NotDone(); }
|
|
}
|
|
}
|
|
|
|
Standard_Boolean GccAna_Circ2d2TanRad::
|
|
IsTheSame1 (const Standard_Integer Index) const
|
|
{
|
|
if (!WellDone) { throw StdFail_NotDone(); }
|
|
if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
|
|
|
|
if (TheSame1(Index) == 0) { return Standard_False; }
|
|
|
|
return Standard_True;
|
|
}
|
|
|
|
Standard_Boolean GccAna_Circ2d2TanRad::
|
|
IsTheSame2 (const Standard_Integer Index) const
|
|
{
|
|
if (!WellDone) { throw StdFail_NotDone(); }
|
|
if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
|
|
|
|
if (TheSame2(Index) == 0) { return Standard_False; }
|
|
return Standard_True;
|
|
}
|