mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-09-18 14:27:39 +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.
528 lines
20 KiB
C++
528 lines
20 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.
|
|
|
|
//=========================================================================
|
|
// Straight line tangent to two circles or tangent to a circle and passing +
|
|
// through point. +
|
|
//=========================================================================
|
|
|
|
#include <ElCLib.hxx>
|
|
#include <GccAna_Lin2d2Tan.hxx>
|
|
#include <GccEnt_BadQualifier.hxx>
|
|
#include <GccEnt_QualifiedCirc.hxx>
|
|
#include <gp_Circ2d.hxx>
|
|
#include <gp_Dir2d.hxx>
|
|
#include <gp_Lin2d.hxx>
|
|
#include <gp_Pnt2d.hxx>
|
|
#include <gp_Vec2d.hxx>
|
|
#include <gp_XY.hxx>
|
|
#include <Standard_OutOfRange.hxx>
|
|
#include <StdFail_NotDone.hxx>
|
|
|
|
//=========================================================================
|
|
// Straight line passing through two points. +
|
|
// =============================== +
|
|
//=========================================================================
|
|
GccAna_Lin2d2Tan::
|
|
GccAna_Lin2d2Tan (const gp_Pnt2d& ThePoint1,
|
|
const gp_Pnt2d& ThePoint2 ,
|
|
const Standard_Real Tolerance ):
|
|
linsol(1,1),
|
|
qualifier1(1,1),
|
|
qualifier2(1,1) ,
|
|
pnttg1sol(1,1),
|
|
pnttg2sol(1,1),
|
|
par1sol(1,1),
|
|
par2sol(1,1),
|
|
pararg1(1,1),
|
|
pararg2(1,1)
|
|
{
|
|
|
|
Standard_Real Tol = Abs(Tolerance);
|
|
WellDone = Standard_False;
|
|
NbrSol = 0;
|
|
Standard_Real dist = ThePoint1.Distance(ThePoint2);
|
|
qualifier1(1) = GccEnt_noqualifier;
|
|
qualifier2(1) = GccEnt_noqualifier;
|
|
if (dist >= Tol) {
|
|
gp_Dir2d dir(ThePoint2.X()-ThePoint1.X(),ThePoint2.Y()-ThePoint1.Y());
|
|
linsol(1) = gp_Lin2d(ThePoint1,dir);
|
|
// ===================================
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
pnttg1sol(1) = ThePoint1;
|
|
pnttg2sol(1) = ThePoint2;
|
|
par1sol(NbrSol)=ElCLib::Parameter(linsol(NbrSol),pnttg1sol(NbrSol));
|
|
par2sol(NbrSol)=ElCLib::Parameter(linsol(NbrSol),pnttg2sol(NbrSol));
|
|
pararg1(1) = 0.0;
|
|
pararg2(1) = 0.0;
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// Straight line tangent to a circle passing by a point. +
|
|
// ================================================= +
|
|
// Basing on the qualifier attached to circle Qualified1 (C1) define +
|
|
// the direction of the tangent to be calculated. +
|
|
// This tangent will have connection point P1 (point of tangency with the circle. +
|
|
// It has angle A (sinus R1/dist or -R1/dist) with straight line +
|
|
// passing by the center of the circle and ThePoint. +
|
|
//=========================================================================
|
|
|
|
GccAna_Lin2d2Tan::
|
|
GccAna_Lin2d2Tan (const GccEnt_QualifiedCirc& Qualified1,
|
|
const gp_Pnt2d& ThePoint ,
|
|
const Standard_Real Tolerance ):
|
|
linsol(1,2),
|
|
qualifier1(1,2),
|
|
qualifier2(1,2),
|
|
pnttg1sol(1,2),
|
|
pnttg2sol(1,2),
|
|
par1sol(1,2),
|
|
par2sol(1,2),
|
|
pararg1(1,2),
|
|
pararg2(1,2)
|
|
{
|
|
|
|
Standard_Real Tol = Abs(Tolerance);
|
|
WellDone = Standard_False;
|
|
NbrSol = 0;
|
|
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
|
|
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
|
|
throw GccEnt_BadQualifier();
|
|
return;
|
|
}
|
|
gp_Circ2d C1 = Qualified1.Qualified();
|
|
Standard_Real R1 = C1.Radius();
|
|
|
|
if (Qualified1.IsEnclosed()) { throw GccEnt_BadQualifier(); }
|
|
// ============================
|
|
else if (Tol < R1-ThePoint.Distance(C1.Location())) {
|
|
WellDone = Standard_True;
|
|
}
|
|
else if (Abs(ThePoint.Distance(C1.Location())-R1) <= Tol) {
|
|
gp_Dir2d dir(gp_Vec2d(C1.Location(),ThePoint));
|
|
linsol(1) = gp_Lin2d(ThePoint,gp_Dir2d(Standard_Real(-dir.Y()),
|
|
Standard_Real(dir.X())));
|
|
// =====================================================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = GccEnt_noqualifier;
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
pnttg1sol(1) = ThePoint;
|
|
pnttg2sol(1) = ThePoint;
|
|
}
|
|
else {
|
|
Standard_Real signe = 1;
|
|
Standard_Real dist = ThePoint.Distance(C1.Location());
|
|
Standard_Real d = dist - Sqrt(dist*dist - R1*R1);
|
|
if (Qualified1.IsEnclosing()) {
|
|
// =============================
|
|
signe = 1;
|
|
NbrSol = 1;
|
|
}
|
|
else if (Qualified1.IsOutside()) {
|
|
signe = -1;
|
|
NbrSol = 1;
|
|
}
|
|
else if (Qualified1.IsUnqualified()) {
|
|
// ====================================
|
|
signe = 1;
|
|
NbrSol = 2;
|
|
}
|
|
for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
|
|
gp_Pnt2d P1(C1.Location().Rotated(ThePoint,ASin(signe*R1/dist)));
|
|
gp_Dir2d D1(gp_Vec2d(P1,ThePoint));
|
|
P1=gp_Pnt2d(P1.XY() + d*D1.XY());
|
|
linsol(i) = gp_Lin2d(P1,gp_Dir2d(gp_Vec2d(P1,ThePoint)));
|
|
// ========================================================
|
|
qualifier1(i) = Qualified1.Qualifier();
|
|
qualifier2(i) = GccEnt_noqualifier;
|
|
pnttg1sol(i) = P1;
|
|
pnttg2sol(i) = ThePoint;
|
|
signe = -signe;
|
|
}
|
|
WellDone = Standard_True;
|
|
}
|
|
for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
|
|
par1sol(i)=ElCLib::Parameter(linsol(i),pnttg1sol(i));
|
|
par2sol(i)=ElCLib::Parameter(linsol(i),pnttg2sol(i));
|
|
pararg1(i)=ElCLib::Parameter(C1,pnttg1sol(i));
|
|
pararg2(i) = 0.;
|
|
}
|
|
}
|
|
|
|
//=========================================================================
|
|
// Straight line tangent to two circles. +
|
|
// ==================================== +
|
|
// In the boundary cas (two interior circles are tangent to each other) +
|
|
// take the straight line orthogonal to the straight line connecting +
|
|
// two circles. +
|
|
// In other cases subject the center of C1 (Qualified1) or of +
|
|
// C2 (Qualified2), provided that R1 is greater than R2, to a +
|
|
// rotation of angle A with sinus(A) = (R1+R2)/dist or +
|
|
// sinus(A) = (R1-R2)/dist or +
|
|
// sinus(A) = (R2-R1)/dist or +
|
|
// sinus(A) = (-R1-R2)/dist +
|
|
// The point found this way is P1 or P2. +
|
|
// The direction of the straight line to be calculated should pass by +
|
|
// the center of rotation (center of C1 or of C2) and P1 or P2. +
|
|
// Then translate the straight line to make it tangent to C1. +
|
|
//=========================================================================
|
|
|
|
GccAna_Lin2d2Tan::
|
|
GccAna_Lin2d2Tan (const GccEnt_QualifiedCirc& Qualified1,
|
|
const GccEnt_QualifiedCirc& Qualified2,
|
|
const Standard_Real Tolerance ):
|
|
linsol(1,4),
|
|
qualifier1(1,4),
|
|
qualifier2(1,4) ,
|
|
pnttg1sol(1,4),
|
|
pnttg2sol(1,4),
|
|
par1sol(1,4),
|
|
par2sol(1,4),
|
|
pararg1(1,4),
|
|
pararg2(1,4)
|
|
{
|
|
|
|
Standard_Real Tol = Abs(Tolerance);
|
|
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;
|
|
}
|
|
gp_Circ2d C1 = Qualified1.Qualified();
|
|
gp_Circ2d C2 = Qualified2.Qualified();
|
|
|
|
if (Qualified1.IsEnclosed() || Qualified2.IsEnclosed()) {
|
|
// =======================================================
|
|
throw GccEnt_BadQualifier();
|
|
}
|
|
else {
|
|
Standard_Real R1 = C1.Radius();
|
|
Standard_Real R2 = C2.Radius();
|
|
gp_Dir2d D1;
|
|
Standard_Integer signe = 1;
|
|
Standard_Real dist = C1.Location().Distance(C2.Location());
|
|
if (Tol < Max(R1,R2)-dist-Min(R1,R2) ) { WellDone = Standard_True; }
|
|
else if (!Qualified1.IsUnqualified() || !Qualified2.IsUnqualified()) {
|
|
// ====================================================================
|
|
if (Qualified1.IsEnclosing() && Qualified2.IsEnclosing()) {
|
|
// =========================================================
|
|
if (Abs(dist+Min(R1,R2)-Max(R1,R2)) <= Tol && dist >= Tol) {
|
|
if (R1<R2) { D1 = gp_Dir2d(gp_Vec2d(C2.Location(),C1.Location()));}
|
|
else { D1 = gp_Dir2d(gp_Vec2d(C1.Location(),C2.Location())); }
|
|
gp_Pnt2d P1(C1.Location().XY()+R1*D1.XY());
|
|
linsol(1) = gp_Lin2d(P1,gp_Dir2d(-D1.Y(),D1.X()));
|
|
// =================================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified2.Qualifier();
|
|
pnttg1sol(1) = P1;
|
|
pnttg2sol(1) = P1;
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
}
|
|
else {
|
|
gp_Pnt2d P1(C2.Location().Rotated(C1.Location(),
|
|
ASin((R1-R2)/dist)));
|
|
D1 = gp_Dir2d(gp_Vec2d(C1.Location(),P1));
|
|
P1=gp_Pnt2d((C1.Location().XY()+gp_XY(R1*D1.Y(),-R1*D1.X())));
|
|
linsol(1) = gp_Lin2d(P1,D1);
|
|
// ===========================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(1) = P1;
|
|
pnttg2sol(1) = gp_Pnt2d(C2.Location().XY()+
|
|
gp_XY(R2*D1.Y(),-R2*D1.X()));
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
}
|
|
}
|
|
else if ((Qualified1.IsEnclosing() && Qualified2.IsOutside()) ||
|
|
// ================================================================
|
|
(Qualified2.IsEnclosing() && Qualified1.IsOutside())) {
|
|
// =====================================================
|
|
if (Qualified1.IsEnclosing() && Qualified2.IsOutside()) {
|
|
signe = 1;
|
|
}
|
|
else {
|
|
signe = -1;
|
|
}
|
|
if (R1+R2-dist > Tol) { WellDone = Standard_True; }
|
|
else if (Abs(dist-R1-R2)<Tol && dist>Tol) {
|
|
D1 = gp_Dir2d(gp_Vec2d(C1.Location(),C2.Location()));
|
|
gp_Pnt2d P1(C1.Location().XY()+R1*D1.XY());
|
|
linsol(1) = gp_Lin2d(P1,gp_Dir2d(-D1.Y(),D1.X()));
|
|
// =================================================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(1) = P1;
|
|
pnttg2sol(1) = P1;
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
}
|
|
else {
|
|
gp_Pnt2d P1(C2.Location().Rotated(C1.Location(),
|
|
ASin(signe*(R1+R2)/dist)));
|
|
D1 = gp_Dir2d(gp_Vec2d(C1.Location(),P1));
|
|
P1=gp_Pnt2d(C1.Location().XY()+signe*(gp_XY(R1*D1.Y(),
|
|
-R1*D1.X())));
|
|
linsol(1) = gp_Lin2d(P1,D1);
|
|
// ===========================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(1) = P1;
|
|
pnttg2sol(1) = gp_Pnt2d(C2.Location().XY()+
|
|
signe*(gp_XY(-R2*D1.Y(),R2*D1.X())));
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
}
|
|
}
|
|
else if (Qualified1.IsOutside() && Qualified2.IsOutside()) {
|
|
// =========================================================
|
|
if (Abs(dist+Min(R1,R2)-Max(R1,R2)) < Tol && dist > Tol) {
|
|
if (R1<R2) { D1 = gp_Dir2d(gp_Vec2d(C2.Location(),C1.Location()));}
|
|
else { D1 = gp_Dir2d(gp_Vec2d(C1.Location(),C2.Location())); }
|
|
linsol(1) = gp_Lin2d(gp_Pnt2d(C1.Location().XY()+R1*D1.XY()),
|
|
// =============================================================
|
|
gp_Dir2d(D1.Y(),-D1.X()));
|
|
// =========================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(C1.Location().XY()+R1*D1.XY());
|
|
pnttg2sol(1) = pnttg1sol(1);
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
}
|
|
else {
|
|
gp_Pnt2d P1(C2.Location().Rotated(C1.Location(),
|
|
ASin((R2-R1)/dist)));
|
|
D1 = gp_Dir2d(gp_Vec2d(C1.Location(),P1));
|
|
P1 = gp_Pnt2d(C1.Location().XY()+gp_XY(-R1*D1.Y(),R1*D1.X()));
|
|
linsol(1) = gp_Lin2d(P1,D1);
|
|
// ===========================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(1) = P1;
|
|
pnttg2sol(1) = gp_Pnt2d(C2.Location().XY()+
|
|
(gp_XY(-R2*D1.Y(),R2*D1.X())));
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
}
|
|
}
|
|
else {
|
|
if ((Qualified1.IsUnqualified() && Qualified2.IsEnclosing()) ||
|
|
// ===============================================================
|
|
(Qualified2.IsUnqualified() && Qualified1.IsEnclosing())) {
|
|
// =========================================================
|
|
if (Qualified2.IsUnqualified()) { signe = 1; }
|
|
else { signe = -1; }
|
|
if (Abs(dist+Min(R1,R2)-Max(R1,R2)) < Tol && dist > Tol) {
|
|
if (R1<R2) { D1=gp_Dir2d(gp_Vec2d(C2.Location(),C1.Location()));}
|
|
else { D1 = gp_Dir2d(gp_Vec2d(C1.Location(),C2.Location())); }
|
|
linsol(1) = gp_Lin2d(gp_Pnt2d(C1.Location().XY()+R1*D1.XY()),
|
|
// =============================================================
|
|
gp_Dir2d(-D1.Y(),D1.X()));
|
|
// =========================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(C1.Location().XY()+R1*D1.XY());
|
|
pnttg2sol(1) = pnttg1sol(1);
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
}
|
|
else {
|
|
gp_Pnt2d P1(C2.Location().Rotated(C1.Location(),
|
|
ASin((R1-R2)/dist)));
|
|
D1 = gp_Dir2d(gp_Vec2d(C1.Location(),P1));
|
|
P1 = gp_Pnt2d(C1.Location().XY()+gp_XY(R1*D1.Y(),-R1*D1.X()));
|
|
linsol(1) = gp_Lin2d(P1,D1);
|
|
// ===========================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(1) = P1;
|
|
pnttg2sol(1) = gp_Pnt2d(C2.Location().XY()+
|
|
signe*(gp_XY(R2*D1.Y(),-R2*D1.X())));
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
if (Min(R1,R2)+Max(R1,R2)<dist) {
|
|
gp_Pnt2d P2(C2.Location().Rotated(C1.Location(),
|
|
ASin(signe*(R1+R2)/dist)));
|
|
gp_Dir2d D2(gp_Vec2d(C1.Location(),P2));
|
|
P2=gp_Pnt2d(C1.Location().XY()+
|
|
signe*(gp_XY(R1*D2.Y(),-R1*D2.X())));
|
|
linsol(2) = gp_Lin2d(P2,D2);
|
|
// ===========================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(2) = P1;
|
|
pnttg2sol(2) = gp_Pnt2d(C2.Location().XY()+
|
|
(gp_XY(-R2*D2.Y(),R2*D2.X())));
|
|
NbrSol = 2;
|
|
}
|
|
}
|
|
}
|
|
else if ((Qualified1.IsUnqualified() && Qualified2.IsOutside()) ||
|
|
// ==================================================================
|
|
(Qualified2.IsUnqualified() && Qualified1.IsOutside())) {
|
|
// =======================================================
|
|
if (Qualified2.IsUnqualified()) { signe = 1; }
|
|
else { signe = -1; }
|
|
if (Abs(dist+Min(R1,R2)-Max(R1,R2)) <= Tol && dist >= Tol) {
|
|
if (R1<R2) { D1=gp_Dir2d(gp_Vec2d(C2.Location(),C1.Location()));}
|
|
else { D1 = gp_Dir2d(gp_Vec2d(C1.Location(),C2.Location())); }
|
|
linsol(1) = gp_Lin2d(gp_Pnt2d(C1.Location().XY()+R1*D1.XY()),
|
|
// =============================================================
|
|
gp_Dir2d(D1.Y(),-D1.X()));
|
|
// =========================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(1) = gp_Pnt2d(C1.Location().XY()+R1*D1.XY());
|
|
pnttg2sol(1) = pnttg1sol(1);
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
}
|
|
else {
|
|
gp_Pnt2d P1(C2.Location().Rotated(C1.Location(),
|
|
ASin(signe*(R2-R1)/dist)));
|
|
D1 = gp_Dir2d(gp_Vec2d(C1.Location(),P1));
|
|
P1 = gp_Pnt2d(C1.Location().XY()+gp_XY(-R1*D1.Y(),R1*D1.X()));
|
|
linsol(1) = gp_Lin2d(P1,D1);
|
|
// ===========================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(1) = P1;
|
|
pnttg2sol(1) = gp_Pnt2d(C2.Location().XY()+
|
|
signe*(gp_XY(-R2*D1.Y(),R2*D1.X())));
|
|
WellDone = Standard_True;
|
|
NbrSol = 1;
|
|
if (Min(R1,R2)+Max(R1,R2)<dist) {
|
|
gp_Pnt2d P2(C2.Location().Rotated(C1.Location(),
|
|
ASin(signe*(-R2-R1)/dist)));
|
|
gp_Dir2d D2(gp_Vec2d(C1.Location(),P2));
|
|
P2=gp_Pnt2d(C1.Location().XY()+
|
|
signe*(gp_XY(-R1*D2.Y(),R1*D2.X())));
|
|
linsol(2) = gp_Lin2d(P2,D2);
|
|
// ===========================
|
|
qualifier1(1) = Qualified1.Qualifier();
|
|
qualifier2(1) = Qualified1.Qualifier();
|
|
pnttg1sol(2) = P2;
|
|
pnttg2sol(2) = gp_Pnt2d(C2.Location().XY()+
|
|
signe*(gp_XY(R2*D2.Y(),-R2*D2.X())));
|
|
NbrSol = 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
for (Standard_Integer i = 1 ; i <= 2 ; i++) {
|
|
signe = -signe;
|
|
NbrSol++;
|
|
gp_Pnt2d P1(C2.Location().Rotated(C1.Location(),
|
|
ASin(signe*(R2-R1)/dist)));
|
|
D1 = gp_Dir2d(gp_Vec2d(C1.Location(),P1));
|
|
P1 = gp_Pnt2d(C1.Location().XY()+signe*gp_XY(-R1*D1.Y(),R1*D1.X()));
|
|
linsol(NbrSol) = gp_Lin2d(P1,D1);
|
|
// ===========================
|
|
qualifier1(NbrSol) = Qualified1.Qualifier();
|
|
qualifier2(NbrSol) = Qualified1.Qualifier();
|
|
pnttg1sol(NbrSol) = P1;
|
|
pnttg2sol(NbrSol) = gp_Pnt2d(C2.Location().XY()+
|
|
signe*(gp_XY(-R2*D1.Y(),R2*D1.X())));
|
|
WellDone = Standard_True;
|
|
if (Min(R1,R2)+Max(R1,R2)<dist) {
|
|
gp_Pnt2d P2(C2.Location().Rotated(C1.Location(),
|
|
ASin(signe*(R2+R1)/dist)));
|
|
gp_Dir2d D2(gp_Vec2d(C1.Location(),P2));
|
|
P2=gp_Pnt2d(C1.Location().XY()+
|
|
signe*(gp_XY(R1*D2.Y(),-R1*D2.X())));
|
|
NbrSol++;
|
|
linsol(NbrSol) = gp_Lin2d(P2,D2);
|
|
// ================================
|
|
qualifier1(NbrSol) = Qualified1.Qualifier();
|
|
qualifier2(NbrSol) = Qualified1.Qualifier();
|
|
pnttg1sol(NbrSol) = P2;
|
|
pnttg2sol(NbrSol) = gp_Pnt2d(C2.Location().XY()+
|
|
signe*(gp_XY(-R2*D2.Y(),R2*D2.X())));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
|
|
par1sol(i)=ElCLib::Parameter(linsol(i),pnttg1sol(i));
|
|
par2sol(i)=ElCLib::Parameter(linsol(i),pnttg2sol(i));
|
|
pararg1(i)=ElCLib::Parameter(C1,pnttg1sol(i));
|
|
pararg2(i)=ElCLib::Parameter(C2,pnttg2sol(i));
|
|
}
|
|
}
|
|
|
|
Standard_Boolean GccAna_Lin2d2Tan::
|
|
IsDone () const { return WellDone; }
|
|
|
|
Standard_Integer GccAna_Lin2d2Tan::
|
|
NbSolutions () const { return NbrSol; }
|
|
|
|
gp_Lin2d GccAna_Lin2d2Tan::
|
|
ThisSolution (const Standard_Integer Index) const {
|
|
|
|
if (Index > NbrSol || Index <= 0) { throw Standard_OutOfRange(); }
|
|
return linsol(Index);
|
|
}
|
|
|
|
void GccAna_Lin2d2Tan::
|
|
WhichQualifier(const Standard_Integer Index ,
|
|
GccEnt_Position& Qualif1 ,
|
|
GccEnt_Position& Qualif2 ) const
|
|
{
|
|
if (!WellDone) { throw StdFail_NotDone(); }
|
|
else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
|
|
else {
|
|
Qualif1 = qualifier1(Index);
|
|
Qualif2 = qualifier2(Index);
|
|
}
|
|
}
|
|
|
|
void GccAna_Lin2d2Tan::
|
|
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 {
|
|
ParSol = par1sol(Index);
|
|
ParArg = pararg1(Index);
|
|
PntSol = gp_Pnt2d(pnttg1sol(Index));
|
|
}
|
|
}
|
|
|
|
void GccAna_Lin2d2Tan::
|
|
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 {
|
|
ParSol = par2sol(Index);
|
|
ParArg = pararg2(Index);
|
|
PntSol = gp_Pnt2d(pnttg2sol(Index));
|
|
}
|
|
}
|