1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

Integration of OCCT 6.5.0 from SVN

This commit is contained in:
bugmaster
2011-03-16 07:30:28 +00:00
committed by bugmaster
parent 4903637061
commit 7fd59977df
16375 changed files with 3882564 additions and 0 deletions

31
src/GccAna/FILES Executable file
View File

@@ -0,0 +1,31 @@
GccAna_Circ2d2TanOn_1.cxx
GccAna_Circ2d2TanOn_2.cxx
GccAna_Circ2d2TanOn_3.cxx
GccAna_Circ2d2TanOn_4.cxx
GccAna_Circ2d2TanOn_5.cxx
GccAna_Circ2d2TanOn_6.cxx
GccAna_Circ2d2TanOn_7.cxx
GccAna_Circ2d2TanOn_8.cxx
GccAna_Circ2d2TanOn_9.cxx
GccAna_Circ2d2TanOn_10.cxx
GccAna_Circ2d2TanOn_11.cxx
GccAna_Circ2d2TanRad_1.cxx
GccAna_Circ2d2TanRad_2.cxx
GccAna_Circ2d2TanRad_3.cxx
GccAna_Circ2d2TanRad_4.cxx
GccAna_Circ2d2TanRad_5.cxx
GccAna_Circ2d3Tan_1.cxx
GccAna_Circ2d3Tan_2.cxx
GccAna_Circ2d3Tan_3.cxx
GccAna_Circ2d3Tan_4.cxx
GccAna_Circ2d3Tan_5.cxx
GccAna_Circ2d3Tan_6.cxx
GccAna_Circ2d3Tan_7.cxx
GccAna_Circ2d3Tan_8.cxx
GccAna_Circ2d3Tan_9.cxx
GccAna_Circ2dTanOnRad_1.cxx
GccAna_Circ2dTanOnRad_2.cxx
GccAna_Circ2dTanOnRad_3.cxx
GccAna_Circ2dTanOnRad_4.cxx
GccAna_Circ2dTanOnRad_5.cxx

83
src/GccAna/GccAna.cdl Executable file
View File

@@ -0,0 +1,83 @@
-- File: GccAna.cdl
-- Created: Tue Mar 5 11:27:49 1991
-- Author: Philippe DAUTRY
-- <fid@topsn3>
---Copyright: Matra Datavision 1991
package GccAna
---Purpose : This package provides an implementation of analytics
-- algorithms (using only non persistant entities) used
-- to create 2d lines or circles with geometric constraints.
uses Standard,
StdFail,
gp,
TColStd,
TColgp,
GccInt,
GccEnt
is
-- Exceptions :
exception NoSolution inherits Failure from Standard;
class Lin2dTanPar;
---Purpose : Creates a 2d line TANgent to an 2d entity and PARallel
-- to another 2d line.
class Lin2dTanPer;
---Purpose : Creates a 2d line TANgent to an 2d entity and PERpendicular
-- to another 2d entity.
class Lin2dTanObl;
---Purpose : Creates a 2d line TANgent to an 2d entity and OBLic
-- to another 2d entity.
class Lin2d2Tan;
---Purpose : Creates a 2d line TANgent to 2 2d entities.
class Lin2dBisec;
---Purpose : Creates a 2d line BISECting line of 2 2d lines.
class Circ2dTanCen;
---Purpose : Creates a 2d circle TANgent to a 2d entity and CENtered
-- on a 2d point.
class Circ2d3Tan;
---Purpose : Creates a 2d circle TANgent to 3 2d entities.
class Circ2d2TanRad;
---Purpose : Creates a 2d circle TANgent to 2 2d entities with
-- the given RADius.
class Circ2d2TanOn;
---Purpose : Creates a 2d circle TANgent to a 2d entity and centered
-- ON a 2d entity (not a point).
class Circ2dTanOnRad;
---Purpose : Creates a 2d circle TANgent to a 2d entity and centered
-- ON a 2d entity (not a point) with the given radius.
class Pnt2dBisec;
---Purpose : Creates a 2d line BISECting line of 2 2d points.
class Circ2dBisec;
---Purpose : Creates a 2d line BISECting line of 2 2d circles.
class CircLin2dBisec;
---Purpose : Creates a 2d line BISECting line of a 2d circle
-- and a 2d line.
class CircPnt2dBisec;
---Purpose : Creates a 2d line BISECting line of a 2d circle
-- and a 2d point.
class LinPnt2dBisec;
---Purpose : Creates a 2d line BISECting line of a 2d line
-- and a 2d point.
end GccAna;

View File

@@ -0,0 +1,350 @@
-- File: Circ2d2TanOn.cdl
-- Created: Fri Mar 22 10:29:17 1991
-- Author: Remy GILET
-- <Reg@topsn3>
---Copyright: Matra Datavision 1991
class Circ2d2TanOn
from GccAna
---Purpose: Describes functions for building a 2D circle
-- - tangential to 2 curves, or
-- - tangential to a curve and passing through a point, or
-- - passing through 2 points,
-- and with its center on a curve. For these analytic
-- algorithms, curves are circles or lines.
-- A Circ2d2TanOn object provides a framework for:
-- - defining the construction of 2D circles(s),
-- - implementing the construction algorithm, and
-- - consulting the result(s).
uses Pnt2d from gp,
Lin2d from gp,
Circ2d from gp,
QualifiedLin from GccEnt,
QualifiedCirc from GccEnt,
Array1OfReal from TColStd,
Array1OfInteger from TColStd,
Array1OfPnt2d from TColgp,
Array1OfCirc2d from TColgp,
Position from GccEnt,
Array1OfPosition from GccEnt
raises OutOfRange from Standard,
NotDone from StdFail,
BadQualifier from GccEnt
is
---Category : On a 2d line ...............................................
Create(Qualified1 : QualifiedCirc ;
Qualified2 : QualifiedCirc ;
OnLine : Lin2d ;
Tolerance : Real ) returns Circ2d2TanOn
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to two 2d circles and
-- having the center ON a 2d line.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedCirc ;
Qualified2 : QualifiedLin ;
OnLine : Lin2d ;
Tolerance : Real ) returns Circ2d2TanOn
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to a 2d circle and a 2d line
-- having the center ON a 2d line.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedLin ;
Qualified2 : QualifiedLin ;
OnLine : Lin2d ;
Tolerance : Real ) returns Circ2d2TanOn
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to two 2d lines
-- having the center ON a 2d line.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedCirc ;
Point2 : Pnt2d ;
OnLine : Lin2d ;
Tolerance : Real ) returns Circ2d2TanOn
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to a 2d circle and a point
-- having the center ON a 2d line.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedLin ;
Point2 : Pnt2d ;
OnLine : Lin2d ;
Tolerance : Real ) returns Circ2d2TanOn
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to a 2d line and a point
-- having the center ON a 2d line.
raises BadQualifier from GccEnt;
Create(Point1 : Pnt2d ;
Point2 : Pnt2d ;
OnLine : Lin2d ;
Tolerance : Real ) returns Circ2d2TanOn;
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to two points
-- having the center ON a 2d line.
---Category: On a 2d Circle ...............................................
Create(Qualified1 : QualifiedCirc ;
Qualified2 : QualifiedCirc ;
OnCirc : Circ2d ;
Tolerance : Real ) returns Circ2d2TanOn
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to two 2d circles and
-- having the center ON a 2d circle.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedCirc ;
Qualified2 : QualifiedLin ;
OnCirc : Circ2d ;
Tolerance : Real ) returns Circ2d2TanOn
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to a circle and a line
-- having the center ON a 2d circle.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedCirc ;
Point2 : Pnt2d ;
OnCirc : Circ2d ;
Tolerance : Real ) returns Circ2d2TanOn
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to a circle and a point
-- having the center ON a 2d circle.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedLin ;
Qualified2 : QualifiedLin ;
OnCirc : Circ2d ;
Tolerance : Real ) returns Circ2d2TanOn
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to two 2d lines
-- having the center ON a 2d circle.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedLin ;
Point2 : Pnt2d ;
OnCirc : Circ2d ;
Tolerance : Real ) returns Circ2d2TanOn
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to a line and a point
-- having the center ON a 2d circle.
raises BadQualifier from GccEnt;
Create(Point1 : Pnt2d ;
Point2 : Pnt2d ;
OnCirc : Circ2d ;
Tolerance : Real ) returns Circ2d2TanOn;
---Purpose: This method implements the algorithms used to create
-- 2d circles TANgent to two points having the center ON
-- a 2d circle.
-- ....................................................................
IsDone(me) returns Boolean
is static;
---Purpose:
-- Returns true if the construction algorithm does not fail
-- (even if it finds no solution).
-- Note: IsDone protects against a failure arising from a
-- more internal intersection algorithm, which has reached its numeric limits.
NbSolutions(me) returns Integer
raises NotDone
is static;
---Purpose:
-- Returns the number of circles, representing solutions
-- computed by this algorithm.
-- Exceptions
-- StdFail_NotDone if the construction fails.
ThisSolution(me ; Index : Integer) returns Circ2d
raises OutOfRange, NotDone
is static;
---Purpose: Returns the solution number Index and raises OutOfRange
-- exception if Index is greater than the number of solutions.
-- Be careful: the Index is only a way to get all the
-- solutions, but is not associated to those outside the context
-- of the algorithm-object.
-- Exceptions
-- Standard_OutOfRange if Index is less than zero or
-- greater than the number of solutions computed by this algorithm.
-- StdFail_NotDone if the construction fails.
WhichQualifier(me ;
Index : Integer from Standard;
Qualif1 : out Position from GccEnt ;
Qualif2 : out Position from GccEnt )
raises OutOfRange, NotDone
is static;
---Purpose: Returns the qualifiers Qualif1 and Qualif2 of the
-- tangency arguments for the solution of index Index
-- computed by this algorithm.
-- The returned qualifiers are:
-- - those specified at the start of construction when the
-- solutions are defined as enclosed, enclosing or
-- outside with respect to the arguments, or
-- - those computed during construction (i.e. enclosed,
-- enclosing or outside) when the solutions are defined
-- as unqualified with respect to the arguments, or
-- - GccEnt_noqualifier if the tangency argument is a point.
-- Exceptions
-- Standard_OutOfRange if Index is less than zero or
-- greater than the number of solutions computed by this algorithm.
-- StdFail_NotDone if the construction fails.
Tangency1(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns the informations about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point PntSol on
-- the solution
-- ParArg is the intrinsic parameter of the point PntSol on
-- the first argument. Raises OutOfRange if Index is greater than the number
-- of solutions and NotDone if IsDone returns false.
raises OutOfRange, NotDone
is static;
Tangency2(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns the informations about the tangency point between the
-- result number Index and the second argument.
-- ParSol is the intrinsic parameter of the point PntSol on
-- the solution.
-- ParArg is the intrinsic parameter of the point PntSol on
-- the second argument. Raises OutOfRange if Index is greater than the number
-- of solutions and NotDone if IsDone returns false.
raises OutOfRange, NotDone
is static;
CenterOn3 (me ;
Index : Integer from Standard;
ParArg : out Real from Standard;
PntArg : out Pnt2d from gp )
---Purpose: Returns the informations about the center (on the curv) of
-- the result number Index and the third argument.
-- ParArg is the intrinsic parameter of the point PntArg on
-- the third argument.
-- Exceptions
-- Standard_OutOfRange if Index is less than zero or
-- greater than the number of solutions computed by this algorithm.
-- StdFail_NotDone if the construction fails.
raises OutOfRange, NotDone
is static;
IsTheSame1(me ;
Index : Integer from Standard) returns Boolean from Standard
---Purpose: True if the solution and the first argument are the same
-- (2 circles).
-- If R1 is the radius of the first argument and Rsol the radius
-- of the solution and dist the distance between the two centers,
-- we concider the two circles are identical if R1+dist-Rsol is
-- less than Tolerance.
-- False in the other cases.
-- Raises OutOfRange if Index is greater than the number
-- of solutions and NotDone if IsDone returns false.
raises OutOfRange, NotDone
is static;
IsTheSame2(me ;
Index : Integer from Standard) returns Boolean from Standard
---Purpose: True if the solution and the second argument are the same
-- (2 circles).
-- If R2 is the radius of the second argument and Rsol the radius
-- of the solution and dist the distance between the two centers,
-- we concider the two circles are identical if R2+dist-Rsol is
-- less than Tolerance.
-- False in the other cases.
-- Raises OutOfRange if Index is greater than the number
-- of solutions and NotDone if IsDone returns false.
raises OutOfRange, NotDone
is static;
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose: The number of possible solutions.
cirsol : Array1OfCirc2d from TColgp;
---Purpose: The solutions.
qualifier1 : Array1OfPosition from GccEnt;
---Purpose: The qualifiers of the first argument.
qualifier2 : Array1OfPosition from GccEnt;
---Purpose: The qualifiers of the second argument.
TheSame1 : Array1OfInteger from TColStd;
---Purpose: 1 if the solution and the first argument are the same
-- (2 circles).
-- If R1 is the radius of the first argument and Rsol the radius
-- of the solution and dist the distance between the two centers,
-- we concider the two circles are identical if R1+dist-Rsol is
-- less than Tolerance.
-- 0 in the other cases.
TheSame2 : Array1OfInteger from TColStd;
---Purpose: 1 if the solution and the second argument are the same
-- (2 circles).
-- If R2 is the radius of the second argument and Rsol the radius
-- of the solution and dist the distance between the two centers,
-- we concider the two circles are identical if R2+dist-Rsol is
-- less than Tolerance.
-- 0 in the other cases.
pnttg1sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the first
-- argument.
pnttg2sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the second
-- argument.
pntcen : Array1OfPnt2d from TColgp;
---Purpose: The center point of the solution.
par1sol : Array1OfReal from TColStd;
---Purpose: The parameter of pnttg1sol on the solution.
-- pnttg1sol is the tangency point between the solution
-- and the first argument.
par2sol : Array1OfReal from TColStd;
---Purpose: The parameter of pnttg2sol on the solution.
-- pnttg2sol is the tangency point between the solution and the
-- second argument.
pararg1 : Array1OfReal from TColStd;
---Purpose: The parameter of pnttg1sol on the first argument.
-- pnttg1sol is the tangency point between the solution and the
-- first argument.
pararg2 : Array1OfReal from TColStd;
---Purpose: The parameter of pnttg2sol on the second argument.
-- pnttg2sol is the tangency point between the solution and the
-- second argument.
parcen3 : Array1OfReal from TColStd;
---Purpose: The parameter of the center point of the solution on the
-- third argument.
end Circ2d2TanOn;

View File

@@ -0,0 +1,411 @@
// File GccAna_Circ2d2TanOn.cxx, REG 08/07/91
#include <GccAna_Circ2d2TanOn.ixx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_SequenceOfReal.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <Standard_OutOfRange.hxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BCirc.hxx>
#include <GccInt_BLine.hxx>
#include <IntAna2d_Conic.hxx>
#include <StdFail_NotDone.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <GccAna_Circ2dBisec.hxx>
//=========================================================================
// Cercles tangents a deux cercles C1 et C2 et centres sur une droite. +
// Nous commencons par distinguer les differents cas limites que nous +
// allons traiter separement. +
// Pour le cas general: +
// ==================== +
// Nous calculons les bissectrices aux deux cercles qui nous donnent +
// l ensemble des lieux possibles des centres de tous les cercles +
// tangents a C1 et C2. +
// Nous intersectons ces bissectrices avec la droite OnLine ce qui nous +
// donne les points parmis lesquels nous allons choisir les solutions. +
// Les choix s effectuent a partir des Qualifieurs qualifiant C1 et C2. +
//=========================================================================
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 ,
const GccEnt_QualifiedCirc& Qualified2 ,
const gp_Lin2d& OnLine ,
const Standard_Real Tolerance ):
cirsol(1,4) ,
qualifier1(1,4),
qualifier2(1,4) ,
TheSame1(1,4) ,
TheSame2(1,4) ,
pnttg1sol(1,4),
pnttg2sol(1,4),
pntcen(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
Standard_Integer nbsol = 0;
Standard_Real Tol = Abs(Tolerance);
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
gp_Circ2d C1 = Qualified1.Qualified();
gp_Circ2d C2 = Qualified2.Qualified();
Standard_Real R1 = C1.Radius();
Standard_Real R2 = C2.Radius();
gp_Dir2d dirx(1.,0.);
gp_Pnt2d center1(C1.Location());
gp_Pnt2d center2(C2.Location());
TColStd_Array1OfReal Radius(1,2);
#ifdef DEB
Standard_Real distance = center1.Distance(center2);
#else
center1.Distance(center2);
#endif
Standard_Real dist1 = OnLine.Distance(center1);
Standard_Real dist2 = OnLine.Distance(center2);
Standard_Real d1 = dist1+R1;
Standard_Real d2 = dist2+R2;
Standard_Real d3 = dist1-R1;
Standard_Real d4 = dist2-R2;
//=========================================================================
// Traitement des cas limites. +
//=========================================================================
if (Abs(d3-d4)<Tol &&
(Qualified1.IsEnclosed() || Qualified1.IsOutside() ||
Qualified1.IsUnqualified()) &&
(Qualified2.IsEnclosed() || Qualified2.IsOutside() ||
Qualified2.IsUnqualified())) {
nbsol++;
Radius(nbsol) = Abs(d3);
WellDone = Standard_True;
}
if (Abs(d1-d2)<Tol &&
(Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) &&
(Qualified2.IsEnclosing() || Qualified2.IsUnqualified())){
nbsol++;
Radius(nbsol) = Abs(d1);
WellDone = Standard_True;
}
if (Abs(d1-d4)<Tol &&
(Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) &&
(Qualified2.IsEnclosed() || Qualified2.IsOutside() ||
Qualified2.IsUnqualified())){
nbsol++;
Radius(nbsol) = Abs(d1);
WellDone = Standard_True;
}
if (Abs(d3-d2)<Tol &&
(Qualified2.IsEnclosing() || Qualified2.IsUnqualified()) &&
(Qualified1.IsEnclosed() || Qualified1.IsOutside() ||
Qualified1.IsUnqualified())){
nbsol++;
Radius(nbsol) = Abs(d3);
WellDone = Standard_True;
}
gp_Lin2d L(center1,gp_Dir2d(center2.XY()-center1.XY()));
IntAna2d_AnaIntersection Intp(OnLine,L);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()){
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
for (Standard_Integer i = 1 ; i <= nbsol ; i++) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(i));
// ==========================================================
WellDone = Standard_True;
Standard_Real distcc1 = Center.Distance(center1);
Standard_Real distcc2 = Center.Distance(center2);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(i)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(i)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (Abs(distcc2+Radius(i)-R2) < Tol) {
qualifier2(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc2-R2-Radius(i)) < Tol) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosing; }
gp_Dir2d dc1(center1.XY()-Center.XY());
gp_Dir2d dc2(center2.XY()-Center.XY());
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(i)*dc1.XY());
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(i)*dc2.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
pntcen(NbrSol) = cirsol(NbrSol).Location();
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
}
}
}
}
//=========================================================================
// Cas general. +
//=========================================================================
if (!WellDone) {
GccAna_Circ2dBisec Bis(C1,C2);
if (Bis.IsDone()) {
TColStd_Array1OfReal Rbid(1,2);
TColStd_Array1OfReal RBid(1,2);
Standard_Integer nbsolution = Bis.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution ; i++) {
Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
GccInt_IType typ = Sol->ArcType();
if (typ == GccInt_Cir) {
Intp.Perform(OnLine,Sol->Circle());
}
else if (typ == GccInt_Lin) {
Intp.Perform(OnLine,Sol->Line());
}
else if (typ == GccInt_Hpr) {
Intp.Perform(OnLine,IntAna2d_Conic(Sol->Hyperbola()));
}
else if (typ == GccInt_Ell) {
Intp.Perform(OnLine,IntAna2d_Conic(Sol->Ellipse()));
}
if (Intp.IsDone()) {
if (!Intp.IsEmpty()){
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
dist1 = Center.Distance(center1);
dist2 = Center.Distance(center2);
nbsol = 0;
Standard_Integer nsol = 0;
Standard_Integer nnsol = 0;
R1 = C1.Radius();
R2 = C2.Radius();
if (Qualified1.IsEnclosed()) {
if (dist1-R1 < Tol) {
nbsol = 1;
Rbid(1) = Abs(R1-dist1);
}
}
else if (Qualified1.IsOutside()) {
if (R1-dist1 < Tol) {
nbsol = 1;
Rbid(1) = Abs(dist1-R1);
}
}
else if (Qualified1.IsEnclosing()) {
nbsol = 1;
Rbid(1) = dist1+R1;
}
else if (Qualified1.IsUnqualified()) {
nbsol = 2;
Rbid(1) = dist1+R1;
Rbid(1) = Abs(dist1-R1);
}
if (Qualified2.IsEnclosed() && nbsol != 0) {
if (dist2-R2 < Tol) {
nsol = 1;
RBid(1) = Abs(R2-dist2);
}
}
else if (Qualified2.IsOutside() && nbsol != 0) {
if (R2-dist2 < Tol) {
nsol = 1;
RBid(1) = Abs(R2-dist2);
}
}
else if (Qualified2.IsEnclosing() && nbsol != 0) {
nsol = 1;
RBid(1) = dist2+R2;
}
else if (Qualified2.IsUnqualified() && nbsol != 0) {
nsol = 2;
RBid(1) = dist2+R2;
RBid(2) = Abs(R2-dist2);
}
for (Standard_Integer isol = 1; isol <= nbsol ; isol++) {
for (Standard_Integer jsol = 1; jsol <= nsol ; jsol++) {
if (Abs(Rbid(isol)-RBid(jsol)) <= Tol) {
nnsol++;
Radius(nnsol) = (RBid(jsol)+Rbid(isol))/2.;
}
}
}
if (nnsol > 0) {
for (Standard_Integer k = 1 ; k <= nnsol ; k++) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
// ==========================================================
Standard_Real distcc1 = Center.Distance(center1);
Standard_Real distcc2 = Center.Distance(center2);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(i)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(i)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (Abs(distcc2+Radius(i)-R2) < Tol) {
qualifier2(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc2-R2-Radius(i)) < Tol) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosing; }
if (Center.Distance(center1) <= Tol &&
Abs(Radius(k)-C1.Radius()) <= Tol) {TheSame1(NbrSol)=1;}
else {
TheSame1(NbrSol) = 0;
gp_Dir2d dc1(center1.XY()-Center.XY());
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+
Radius(k)*dc1.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg2sol(NbrSol));
}
if (Center.Distance(center2) <= Tol &&
Abs(Radius(k)-C2.Radius()) <= Tol) {TheSame2(NbrSol)=1;}
else {
TheSame2(NbrSol) = 0;
gp_Dir2d dc2(center2.XY()-Center.XY());
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+
Radius(k)*dc2.XY());
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
}
pntcen(NbrSol) = Center;
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
}
}
}
}
WellDone = Standard_True;
}
}
}
}
}
//========================================================================
Standard_Boolean GccAna_Circ2d2TanOn::
IsDone () const{ return WellDone; }
Standard_Integer GccAna_Circ2d2TanOn::
NbSolutions () const{ return NbrSol; }
gp_Circ2d GccAna_Circ2d2TanOn::
ThisSolution (const Standard_Integer Index) const{ return cirsol(Index); }
void GccAna_Circ2d2TanOn::
WhichQualifier(const Standard_Integer Index ,
GccEnt_Position& Qualif1 ,
GccEnt_Position& Qualif2 ) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
Qualif1 = qualifier1(Index);
Qualif2 = qualifier2(Index);
}
}
void GccAna_Circ2d2TanOn::
Tangency1 (const Standard_Integer Index ,
Standard_Real& ParSol ,
Standard_Real& ParArg ,
gp_Pnt2d& PntSol ) const{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
if (TheSame1(Index) == 0) {
ParSol = par1sol(Index);
ParArg = pararg1(Index);
PntSol = gp_Pnt2d(pnttg1sol(Index));
}
else { StdFail_NotDone::Raise(); }
}
}
void GccAna_Circ2d2TanOn::
Tangency2 (const Standard_Integer Index ,
Standard_Real& ParSol ,
Standard_Real& ParArg ,
gp_Pnt2d& PntSol ) const{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
if (TheSame2(Index) == 0) {
ParSol = par2sol(Index);
ParArg = pararg2(Index);
PntSol = gp_Pnt2d(pnttg2sol(Index));
}
else { StdFail_NotDone::Raise(); }
}
}
void GccAna_Circ2d2TanOn::
CenterOn3 (const Standard_Integer Index ,
Standard_Real& ParArg ,
gp_Pnt2d& PntSol ) const{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
ParArg = parcen3(Index);
PntSol = pnttg1sol(Index);
}
}
Standard_Boolean GccAna_Circ2d2TanOn::
IsTheSame1 (const Standard_Integer Index) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
if (TheSame1(Index) == 0) { return Standard_False; }
return Standard_True;
}
Standard_Boolean GccAna_Circ2d2TanOn::
IsTheSame2 (const Standard_Integer Index) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
if (TheSame2(Index) == 0) { return Standard_False; }
return Standard_True;
}

View File

@@ -0,0 +1,266 @@
// File: GccAna_Circ2d2TanOn_1.cxx
// Created: Thu Jan 2 15:50:43 1992
// Author: Remi GILET
// <reg@topsn3>
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <GccAna_CircLin2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BCirc.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Creation d un cercle tangent a un Cercle C1 et a une Droite L2. +
// centre sur une Droite. +
// Nous commencons par distinguer les differents cas limites que nous +
// allons traiter separement. +
// Pour le cas general: +
// ==================== +
// Nous calculons les bissectrices a C1 et L2 qui nous donnent +
// l ensemble des lieux possibles des centres de tous les cercles +
// tangents a C1 et L2. +
// Nous intersectons ces bissectrices avec la droite OnLine ce qui nous +
// donne les points parmis lesquels nous allons choisir les solutions. +
// Les choix s effectuent a partir des Qualifieurs qualifiant C1 et L2. +
//=========================================================================
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 ,
const GccEnt_QualifiedLin& Qualified2 ,
const gp_Lin2d& OnLine ,
const Standard_Real Tolerance ):
cirsol(1,4) ,
qualifier1(1,4) ,
qualifier2(1,4),
TheSame1(1,4) ,
TheSame2(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
pntcen(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Real Tol = Abs(Tolerance);
Standard_Real Radius=0;
Standard_Boolean ok = Standard_False;
gp_Dir2d dirx(1.,0.);
gp_Circ2d C1 = Qualified1.Qualified();
gp_Lin2d L2 = Qualified2.Qualified();
Standard_Real R1 = C1.Radius();
gp_Pnt2d center1(C1.Location());
gp_Pnt2d origin2(L2.Location());
gp_Dir2d dirL2(L2.Direction());
gp_Dir2d normL2(-dirL2.Y(),dirL2.X());
//=========================================================================
// Traitement des cas limites. +
//=========================================================================
Standard_Real distcl = OnLine.Distance(center1);
gp_Pnt2d pinterm(center1.XY()+distcl*
gp_XY(-OnLine.Direction().Y(),OnLine.Direction().X()));
if (OnLine.Distance(pinterm) > Tolerance) {
pinterm = gp_Pnt2d(center1.XY()+distcl*
gp_XY(-OnLine.Direction().Y(),OnLine.Direction().X()));
}
Standard_Real dist2 = L2.Distance(pinterm);
if (Qualified1.IsEnclosed() || Qualified1.IsOutside()) {
if (Abs(distcl-R1-dist2) <= Tol) { ok = Standard_True; }
}
else if (Qualified1.IsEnclosing()) {
if (Abs(dist2-distcl-R1) <= Tol) { ok = Standard_True; }
}
else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
else {
GccEnt_BadQualifier::Raise();
return;
}
if (ok) {
if (Qualified2.IsOutside()) {
gp_Pnt2d pbid(pinterm.XY()+dist2*gp_XY(-dirL2.Y(),dirL2.X()));
if (L2.Distance(pbid) <= Tol) { WellDone = Standard_True; }
}
else if (Qualified2.IsEnclosed()) {
gp_Pnt2d pbid(pinterm.XY()-dist2*gp_XY(-dirL2.Y(),dirL2.X()));
if (L2.Distance(pbid) <= Tol) { WellDone = Standard_True; }
}
else if (Qualified2.IsUnqualified()) { WellDone = Standard_False; }
else {
GccEnt_BadQualifier::Raise();
return;
}
}
if (WellDone) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),dist2);
// =======================================================
gp_Dir2d dc1(center1.XY()-pinterm.XY());
gp_Dir2d dc2(origin2.XY()-pinterm.XY());
Standard_Real distcc1 = pinterm.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+dist2-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-dist2) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (dc2.Dot(normL2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL2.Y(),dirL2.X()));
dc2 = gp_Dir2d(sign*gp_XY(-dirL2.Y(),dirL2.X()));
pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dist2*dc1.XY());
pnttg2sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dist2*dc2.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
pntcen(NbrSol) = cirsol(NbrSol).Location();
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
return;
}
//=========================================================================
// Cas general. +
//=========================================================================
GccAna_CircLin2dBisec Bis(C1,L2);
if (Bis.IsDone()) {
Standard_Integer nbsolution = Bis.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
GccInt_IType type = Sol->ArcType();
IntAna2d_AnaIntersection Intp;
if (type == GccInt_Lin) {
Intp.Perform(OnLine,Sol->Line());
}
else if (type == GccInt_Par) {
Intp.Perform(OnLine,IntAna2d_Conic(Sol->Parabola()));
}
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = Center.Distance(center1);
dist2 = L2.Distance(Center);
// Standard_Integer nbsol = 1;
ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if (dist1-R1 < Tolerance) {
if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; }
}
}
else if (Qualified1.IsOutside()) {
if (R1-dist1 < Tolerance) {
if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; }
}
}
else if (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) {
ok = Standard_True;
}
if (Qualified2.IsEnclosed() && ok) {
if ((((origin2.X()-Center.X())*(-dirL2.Y()))+
((origin2.Y()-Center.Y())*(dirL2.X())))<=0){
ok = Standard_True;
Radius = dist2;
}
}
else if (Qualified2.IsOutside() && ok) {
if ((((origin2.X()-Center.X())*(-dirL2.Y()))+
((origin2.Y()-Center.Y())*(dirL2.X())))>=0){
ok = Standard_True;
Radius = dist2;
}
}
else if (Qualified2.IsUnqualified() && ok) {
ok = Standard_True;
Radius = dist2;
}
if (ok) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
gp_Dir2d dc1(center1.XY()-Center.XY());
gp_Dir2d dc2(origin2.XY()-Center.XY());
Standard_Real distcc1 = Center.Distance(center1);
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 (dc2.Dot(normL2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
if (Center.Distance(center1) <= Tolerance &&
Abs(Radius-C1.Radius()) <= Tolerance) {
TheSame1(NbrSol) = 1;
}
else {
TheSame1(NbrSol) = 0;
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
TheSame2(NbrSol) = 0;
Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL2.Y(),dirL2.X()));
dc2 = gp_Dir2d(sign*gp_XY(-dirL2.Y(),dirL2.X()));
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY());
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
pntcen(NbrSol) = Center;
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
}
}
}
WellDone = Standard_True;
}
}
}
}

View File

@@ -0,0 +1,194 @@
// File: GccAna_Circ2d2TanOn_10.cxx
// Created: Thu Jan 2 16:00:00 1992
// Author: Remi GILET
// <reg@topsn3>
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <GccAna_LinPnt2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_Bisec.hxx>
#include <GccInt_BLine.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Creation d un cercle tangent a une Droite L1 et a un point Point2. +
// centre sur un cercle. +
// Nous commencons par distinguer les differents cas limites que nous +
// allons traiter separement. +
// Pour le cas general: +
// ==================== +
// Nous calculons les bissectrices a L1 et Point2 qui nous donnent +
// l ensemble des lieux possibles des centres de tous les cercles +
// tangents a L1 et Point2. +
// Nous intersectons ces bissectrices avec le cerclee OnCirc ce qui nous +
// donne les points parmis lesquels nous allons choisir les solutions. +
// Les choix s effectuent a partir des Qualifieurs qualifiant L1. +
//=========================================================================
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const GccEnt_QualifiedLin& Qualified1 ,
const gp_Pnt2d& Point2 ,
const gp_Circ2d& OnCirc ,
const Standard_Real Tolerance ):
cirsol(1,4) ,
qualifier1(1,4) ,
qualifier2(1,4) ,
TheSame1(1,4) ,
TheSame2(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
pntcen(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Real Tol = Abs(Tolerance);
gp_Dir2d dirx(1.,0.);
gp_Lin2d L1 = Qualified1.Qualified();
gp_Pnt2d originL1(L1.Location());
gp_Dir2d dirL1(L1.Direction());
gp_Dir2d normL1(-dirL1.Y(),dirL1.X());
//=========================================================================
// Traitement des cas limites. +
//=========================================================================
Standard_Real Ron = OnCirc.Radius();
Standard_Real distpc = OnCirc.Location().Distance(Point2);
gp_Dir2d dir(OnCirc.Location().XY()-Point2.XY());
gp_Pnt2d pinterm(Point2.XY()+(distpc+Ron)*dir.XY());
Standard_Real dist1 = L1.Distance(pinterm);
if (Abs(dist1-distpc-Ron) > Tol) {
#ifdef DEB
gp_Pnt2d pinterm(Point2.XY()+(distpc-Ron)*dir.XY()); // Unused ! BUG ???
Standard_Real dist1 = L1.Distance(pinterm); // Unused ! BUG ???
#endif
}
if (Abs(dist1-distpc+Ron) <= Tol) {
dir = gp_Dir2d(-dirL1.Y(),dirL1.X());
gp_Dir2d direc(originL1.XY()-pinterm.XY());
if (Qualified1.IsOutside()) {
if (direc.Dot(dir) >= 0.0) { WellDone = Standard_True; }
}
else if (Qualified1.IsEnclosed()) {
if (direc.Dot(dir) <= 0.0) { WellDone = Standard_True; }
}
else { WellDone = Standard_True; }
if (WellDone) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),dist1);
// =======================================================
gp_Dir2d dc1(originL1.XY()-pinterm.XY());
Standard_Real sign = dc1.Dot(normL1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc1.Dot(normL1) > 0.0) { qualifier1(NbrSol) = GccEnt_outside; }
else { qualifier1(NbrSol) = GccEnt_enclosed; }
qualifier2(NbrSol) = GccEnt_noqualifier;
dc1 = gp_Dir2d(sign*gp_XY(-dirL1.Y(),dirL1.X()));
pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dist1*dc1.XY());
par1sol(NbrSol) = ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
pntcen(NbrSol) = pinterm;
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol));
parcen3(NbrSol) = 0.;
pnttg2sol(NbrSol) = Point2;
pararg2(NbrSol) = 0.;
par2sol(NbrSol) = ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
return;
}
}
//=========================================================================
// Cas general. +
//=========================================================================
GccAna_LinPnt2dBisec Bis(L1,Point2);
if (Bis.IsDone()) {
Handle(GccInt_Bisec) Sol = Bis.ThisSolution();
GccInt_IType type = Sol->ArcType();
IntAna2d_AnaIntersection Intp;
if (type == GccInt_Lin) {
Intp.Perform(Sol->Line(),OnCirc);
}
if (type == GccInt_Par) {
Intp.Perform(OnCirc,IntAna2d_Conic(Sol->Parabola()));
}
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real Radius = L1.Distance(Center);
// Standard_Integer nbsol = 1;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
((originL1.Y()-Center.Y())*(dirL1.X())))<=0){
ok = Standard_True;
}
}
else if (Qualified1.IsOutside()) {
if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
((originL1.Y()-Center.Y())*(dirL1.X())))>=0){
ok = Standard_True;
}
}
else if (Qualified1.IsUnqualified()) {
ok = Standard_True;
}
if (ok) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
TheSame1(NbrSol) = 0;
TheSame2(NbrSol) = 0;
gp_Dir2d dc1(originL1.XY()-Center.XY());
Standard_Real sign = dc1.Dot(normL1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc1.Dot(normL1) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
qualifier2(NbrSol) = GccEnt_noqualifier;
dc1=gp_Dir2d(sign*gp_XY(-dirL1.Y(),dirL1.X()));
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+dist1*dc1.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
pntcen(NbrSol) = Center;
parcen3(NbrSol) = ElCLib::Parameter(OnCirc,pntcen(NbrSol));
pnttg2sol(NbrSol) = Point2;
pararg2(NbrSol) = 0.;
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
qualifier2(NbrSol) = GccEnt_noqualifier;
}
}
}
WellDone = Standard_True;
}
}
}

View File

@@ -0,0 +1,105 @@
// File: GccAna_Circ2d2TanOn_11.cxx
// Created: Thu Jan 2 16:00:53 1992
// Author: Remi GILET
// <reg@topsn3>
//=========================================================================
// Creation d un cercle tangent a deux elements : Droite. +
// Cercle. +
// Point. +
// centre sur un troisieme : Droite. +
// Cercle. +
//=========================================================================
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <GccAna_Lin2dBisec.hxx>
//=========================================================================
// Creation d un cercle Passant par : 2 points Point1 et Point2. +
// Centre sur : 1 cercle OnCirc. +
// avec une Tolerance de precision : Tolerance. +
// +
// On cree L1 la droite des points equidistant de Point1 et Point2. +
// On cree alors les solutions cirsol telles que : +
// cirsol est l ensemble des cercle ayant pour centre une des inter- +
// sections de L1 avec OnCirc et de rayon la distance entre Point1 et +
// le point ci dessus calcule. +
//=========================================================================
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const gp_Pnt2d& Point1 ,
const gp_Pnt2d& Point2 ,
const gp_Circ2d& OnCirc ,
const Standard_Real Tolerance ):
cirsol(1,2) ,
qualifier1(1,2) ,
qualifier2(1,2) ,
TheSame1(1,2) ,
TheSame2(1,2) ,
pnttg1sol(1,2) ,
pnttg2sol(1,2) ,
pntcen(1,2) ,
par1sol(1,2) ,
par2sol(1,2) ,
pararg1(1,2) ,
pararg2(1,2) ,
parcen3(1,2)
{
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
gp_Dir2d dirx(1.,0.);
Standard_Real Tol = Abs(Tolerance);
Standard_Real dist = Point1.Distance(Point2);
Standard_Real dp1cen = Point1.Distance(OnCirc.Location());
Standard_Real dp2cen = Point2.Distance(OnCirc.Location());
Standard_Real R = OnCirc.Radius();
gp_Circ2d C1 = OnCirc;
if (dist<Tol||Abs(dp1cen+2*R-dp2cen)<Tol||Abs(dp2cen+2*R-dp1cen)<Tol){
WellDone = Standard_True;
return;
}
gp_Lin2d L1(gp_Pnt2d((Point1.XY()+Point2.XY())/2.0),
gp_Dir2d(Point1.Y()-Point2.Y(),Point2.X()-Point1.X()));
if (Abs(dp1cen+2*R-dp2cen)<Tol || Abs(dp2cen+2*R-dp1cen)<Tol) {
if (Abs(dp1cen+2*R-dp2cen)<Tol) {
C1 = gp_Circ2d(gp_Ax2d(OnCirc.Location(),dirx),
OnCirc.Radius()+Abs(dp2cen-dp1cen-2.0*R));
}
else if (Abs(dp1cen+2*R-dp2cen)<Tol) {
C1 = gp_Circ2d(gp_Ax2d(OnCirc.Location(),dirx),
OnCirc.Radius()+Abs(dp2cen-dp1cen-2.0*R));
}
}
IntAna2d_AnaIntersection Intp(L1,C1);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
NbrSol++;
gp_Ax2d axe(Intp.Point(i).Value(),dirx);
cirsol(NbrSol) = gp_Circ2d(axe,Point1.Distance(Intp.Point(i).Value()));
// ======================================================================
qualifier1(NbrSol) = GccEnt_noqualifier;
qualifier2(NbrSol) = GccEnt_noqualifier;
pnttg1sol(NbrSol) = Point1;
pararg1(NbrSol) = 0.;
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
pnttg2sol(NbrSol) = Point2;
pararg2(NbrSol) = 0.;
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
pntcen(NbrSol) = cirsol(NbrSol).Location();
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol));
}
}
WellDone = Standard_True;
}
}

View File

@@ -0,0 +1,156 @@
// File: GccAna_Circ2d2TanOn_2.cxx
// Created: Thu Jan 2 15:52:15 1992
// Author: Remi GILET
// <reg@topsn3>
// JCT 06/07/98 cas des droites confondues (PRO14405)
// JCT 16/11/98 tri des solutions apres le calcul (PRO16384)
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <GccAna_Lin2dBisec.hxx>
#include <gp.hxx>
#include <GccEnt_BadQualifier.hxx>
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const GccEnt_QualifiedLin& Qualified1 ,
const GccEnt_QualifiedLin& Qualified2 ,
const gp_Lin2d& OnLine ,
const Standard_Real Tolerance ):
cirsol(1,2) ,
qualifier1(1,2) ,
qualifier2(1,2) ,
TheSame1(1,2) ,
TheSame2(1,2) ,
pnttg1sol(1,2) ,
pnttg2sol(1,2) ,
pntcen(1,2) ,
par1sol(1,2) ,
par2sol(1,2) ,
pararg1(1,2) ,
pararg2(1,2) ,
parcen3(1,2)
{
// initialisations
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
gp_Dir2d dirx(1.,0.);
Standard_Real Tol = Abs(Tolerance);
// calcul de la (des) bisectrice(s) de L1 et L2
gp_Lin2d L1(Qualified1.Qualified());
gp_Lin2d L2(Qualified2.Qualified());
gp_Pnt2d originL1(L1.Location());
gp_Pnt2d originL2(L2.Location());
GccAna_Lin2dBisec Bis(L1,L2);
if (Bis.IsDone()) {
if (Bis.NbSolutions() == 1 || Bis.NbSolutions() == 2) {
// si 1 bisectrice, L1 et L2 sont paralleles
// si 2 bisectrices, L1 et L2 sont secantes
for (Standard_Integer k = 1 ; k <= Bis.NbSolutions() ; k++) {
IntAna2d_AnaIntersection Intp(Bis.ThisSolution(k),OnLine);
if (Intp.IsDone()) {
WellDone = Standard_True;
// pour les cas degeneres, pas de solution acceptable
// (OnLine et bisectrice paralleles strictement ou pas)
if (!Intp.IdenticalElements()
&& !Intp.ParallelElements()
&& !Intp.IsEmpty()) {
// au maximum 1 point d'intersection !
for (Standard_Integer l = 1 ; l <= Intp.NbPoints() ; l++) {
gp_Pnt2d pt(Intp.Point(l).Value());
gp_Ax2d axe(pt,dirx);
Standard_Real Radius = L1.Distance(pt);
if (!L1.Contains(pt,Tol) && Radius<1.0/Tol && NbrSol<2) {
// solution acceptable : le rayon est correct
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(axe,Radius);
}
}
}
}
}
}
}
// tri selon les qualifiers des NbrSol solutions acceptables
for (Standard_Integer i=1 ; i <= NbrSol ; i++) {
gp_Pnt2d pbid(cirsol(i).Location());
Standard_Real Radius = cirsol(i).Radius();
Standard_Boolean ok = Standard_False;
// solution Outside ou Enclosed / L1
gp_Dir2d dc1(originL1.XY()-pbid.XY());
Standard_Real sign1 = dc1.Dot(gp_Dir2d(-L1.Direction().Y(),
L1.Direction().X()));
if (sign1>0.0) ok = (Qualified1.IsUnqualified()
|| Qualified1.IsOutside());
else ok = (Qualified1.IsUnqualified()
|| Qualified1.IsEnclosed());
// solution Outside ou Enclosed / L2
gp_Dir2d dc2(originL2.XY()-pbid.XY());
Standard_Real sign2 = dc2.Dot(gp_Dir2d(-L2.Direction().Y(),
L2.Direction().X()));
if (sign2>0.0) ok = ok && (Qualified2.IsUnqualified()
|| Qualified2.IsOutside());
else ok = ok &&(Qualified2.IsUnqualified()
|| Qualified2.IsEnclosed());
if (ok) {
// solution a garder
dc1 = gp_Dir2d(sign1*gp_XY(-L1.Direction().Y(),
L1.Direction().X()));
pnttg1sol(i) = gp_Pnt2d(pbid.XY()+Radius*dc1.XY());
if (sign1>0.0) qualifier1(i) = GccEnt_outside;
else qualifier1(i) = GccEnt_enclosed;
dc2 = gp_Dir2d(sign2*gp_XY(-L2.Direction().Y(),
L2.Direction().X()));
pnttg2sol(i) = gp_Pnt2d(pbid.XY()+Radius*dc2.XY());
if (sign2>0.0) qualifier2(i) = GccEnt_outside;
else qualifier2(i) = GccEnt_enclosed;
pntcen(i) = pbid;
par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
pararg1(i)=ElCLib::Parameter(L1,pnttg1sol(i));
par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
pararg2(i)=ElCLib::Parameter(L2,pnttg2sol(i));
parcen3(i)=ElCLib::Parameter(OnLine,pntcen(i));
}
else {
// solution a jeter
if (i==NbrSol) NbrSol--;
else {
for (Standard_Integer k = i+1 ; k <= NbrSol ; k++) {
cirsol(k-1) = cirsol(k);
}
NbrSol--;
i--;
}
}
}
}

View File

@@ -0,0 +1,229 @@
// File: GccAna_Circ2d2TanOn_3.cxx
// Created: Thu Jan 2 15:53:42 1992
// Author: Remi GILET
// <reg@topsn3>
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_Bisec.hxx>
#include <GccInt_BLine.hxx>
#include <GccInt_BCirc.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccAna_CircPnt2dBisec.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Cercles tangents un cercle C1, passant par un point Point2 et centres +
// sur une droite OnLine. +
// Nous commencons par distinguer les differents cas limites que nous +
// allons traiter separement. +
// Pour le cas general: +
// ==================== +
// Nous calculons les bissectrices a C1 et Point2 qui nous donnent +
// l ensemble des lieux possibles des centres de tous les cercles +
// tangents a C1 et passant par Point2. +
// Nous intersectons ces bissectrices avec la droite OnLine ce qui nous +
// donne les points parmis lesquels nous allons choisir les solutions. +
// Les choix s effectuent a partir des Qualifieurs qualifiant C1 et C2. +
//=========================================================================
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 ,
const gp_Pnt2d& Point2 ,
const gp_Lin2d& OnLine ,
const Standard_Real Tolerance ):
cirsol(1,4),
qualifier1(1,4) ,
qualifier2(1,4) ,
TheSame1(1,4) ,
TheSame2(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
pntcen(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
TheSame2.Init(0);
Standard_Real Tol = Abs(Tolerance);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
TColStd_Array1OfReal Radius(1,2);
gp_Dir2d dirx(1.,0.);
gp_Circ2d C1 = Qualified1.Qualified();
Standard_Real R1 = C1.Radius();
gp_Pnt2d center1(C1.Location());
//=========================================================================
// Traitement des cas limites. +
//=========================================================================
Standard_Real dp2l = OnLine.Distance(Point2);
gp_Dir2d donline(OnLine.Direction());
gp_Pnt2d pinterm(Point2.XY()+dp2l*gp_XY(-donline.Y(),donline.X()));
if (OnLine.Distance(pinterm) > Tol) {
pinterm = gp_Pnt2d(Point2.XY()-dp2l*gp_XY(-donline.Y(),donline.X()));
}
Standard_Real dist = pinterm.Distance(center1);
if (Qualified1.IsEnclosed() && Abs(R1-dist-dp2l) <= Tol) {
WellDone = Standard_True;
}
else if (Qualified1.IsEnclosing() && Abs(R1+dist-dp2l) <= Tol) {
WellDone = Standard_True;
}
else if (Qualified1.IsOutside() && Abs(dist-dp2l) <= Tol) {
WellDone = Standard_True;
}
else if (Qualified1.IsUnqualified() &&
(Abs(dist-dp2l) <= Tol || Abs(R1-dist-dp2l) <= Tol ||
Abs(R1+dist-dp2l) <= Tol)) {
WellDone = Standard_True;
}
if (WellDone) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),dp2l);
// ======================================================
gp_Dir2d dc1(center1.XY()-pinterm.XY());
Standard_Real distcc1 = pinterm.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+dp2l-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-dp2l) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
qualifier2(NbrSol) = GccEnt_noqualifier;
pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dp2l*dc1.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
pnttg2sol(NbrSol) = Point2;
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
pntcen(NbrSol) = cirsol(NbrSol).Location();
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
return;
}
//=========================================================================
// cas general. +
//=========================================================================
GccAna_CircPnt2dBisec Bis(C1,Point2);
if (Bis.IsDone()) {
Standard_Integer nbsolution = Bis.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
GccInt_IType type = Sol->ArcType();
IntAna2d_AnaIntersection Intp;
if (type == GccInt_Lin) {
Intp.Perform(OnLine,Sol->Line());
}
else if (type == GccInt_Cir) {
Intp.Perform(OnLine,Sol->Circle());
}
else if (type == GccInt_Ell) {
Intp.Perform(OnLine,IntAna2d_Conic(Sol->Ellipse()));
}
else if (type == GccInt_Hpr) {
Intp.Perform(OnLine,IntAna2d_Conic(Sol->Hyperbola()));
}
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = center1.Distance(Center);
Standard_Integer nbsol = 1;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if (dist1-C1.Radius() <= Tolerance) {
ok = Standard_True;
Radius(1) = Abs(C1.Radius()-dist1);
}
}
else if (Qualified1.IsOutside()) {
if (C1.Radius()-dist1 <= Tolerance) {
ok = Standard_True;
Radius(1) = Abs(C1.Radius()-dist1);
}
}
else if (Qualified1.IsEnclosing()) {
ok = Standard_True;
Radius(1) = C1.Radius()+dist1;
}
/* else if (Qualified1.IsUnqualified() && ok) {
ok = Standard_True;
nbsol = 2;
Radius(1) = Abs(C1.Radius()-dist1);
Radius(2) = C1.Radius()+dist1;
}
*/
else if (Qualified1.IsUnqualified() ) {
Standard_Real popradius = Center.Distance(Point2);
if (Abs(popradius-dist1)) {
ok = Standard_True;
Radius(1) = popradius;
}
}
if (ok) {
for (Standard_Integer k = 1 ; k <= nbsol ; k++) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
// ==========================================================
Standard_Real distcc1 = Center.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(k)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(k)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
qualifier2(NbrSol) = GccEnt_noqualifier;
if (Center.Distance(center1) <= Tolerance &&
Abs(Radius(k)-C1.Radius()) <= Tolerance) {
TheSame1(NbrSol) = 1;
}
else {
TheSame1(NbrSol) = 0;
gp_Dir2d dc1(center1.XY()-Center.XY());
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc1.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(i)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
TheSame2(NbrSol) = 0;
pnttg2sol(NbrSol) = Point2;
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=0.;
pntcen(NbrSol) = Center;
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
}
}
}
}
WellDone = Standard_True;
}
}
}
}

View File

@@ -0,0 +1,202 @@
// File: GccAna_Circ2d2TanOn_4.cxx
// Created: Thu Jan 2 15:54:38 1992
// Author: Remi GILET
// <reg@topsn3>
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <GccAna_LinPnt2dBisec.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_Bisec.hxx>
#include <GccInt_BCirc.hxx>
#include <GccInt_BLine.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <Precision.hxx>
//=========================================================================
// Creation d un cercle Tangent a : 1 droite L1. +
// Passant par : 1 point Point2. +
// Centre sur : 1 droite OnLine. +
// avec une Tolerance de precision : Tolerance. +
// +
// Nous commencons par distinguer les differents cas limites que nous +
// allons traiter separement. +
// Pour le cas general: +
// ==================== +
// Nous calculons les bissectrices a L1 et Point2 qui nous donnent +
// l ensemble des lieux possibles des centres de tous les cercles +
// tangents a L1 et passant par Point2. +
// Nous intersectons ces bissectrices avec la droite OnLine ce qui nous +
// donne les points parmis lesquels nous allons choisir les solutions. +
// Les choix s effectuent a partir des Qualifieurs qualifiant L1. +
//=========================================================================
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const GccEnt_QualifiedLin& Qualified1 ,
const gp_Pnt2d& Point2 ,
const gp_Lin2d& OnLine ,
const Standard_Real Tolerance ):
cirsol(1,4) ,
qualifier1(1,4) ,
qualifier2(1,4),
TheSame1(1,4) ,
TheSame2(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
pntcen(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Real Tol = Abs(Tolerance);
gp_Dir2d dirx(1.,0.);
gp_Lin2d L1 = Qualified1.Qualified();
gp_Pnt2d originL1(L1.Location());
gp_Dir2d dirL1(L1.Direction());
gp_Dir2d normal(-dirL1.Y(),dirL1.X());
//=========================================================================
// Traitement des cas limites. +
//=========================================================================
if (dirL1.IsEqual(OnLine.Direction(),Precision::Confusion()) &&
OnLine.Distance(originL1)<Precision::Confusion()) {
// POP : l2s 2 droites sont identiques : pas de Sol
NbrSol = 0;
return ;
}
Standard_Real dp2l = OnLine.Distance(Point2);
gp_Dir2d donline(OnLine.Direction());
gp_Pnt2d pinterm(Point2.XY()+dp2l*gp_XY(-donline.Y(),donline.X()));
if (OnLine.Distance(pinterm) > Tol) {
pinterm = gp_Pnt2d(Point2.XY()-dp2l*gp_XY(-donline.Y(),donline.X()));
}
Standard_Real dist = L1.Distance(pinterm);
if (Abs(dist-dp2l) <= Tol) {
gp_Dir2d dirbid(originL1.XY()-pinterm.XY());
if (Qualified1.IsEnclosed() && dirbid.Dot(normal)<0.) {
WellDone = Standard_True;
}
else if (Qualified1.IsOutside() && dirbid.Dot(normal) > 0.) {
WellDone = Standard_True;
}
else if (Qualified1.IsUnqualified()) { WellDone = Standard_True; }
if (WellDone) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),dp2l);
// ======================================================
qualifier2(NbrSol) = GccEnt_noqualifier;
gp_Dir2d dc2(originL1.XY()-pinterm.XY());
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc2.Dot(normal) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL1.Y(),
dirL1.X()));
dc2 = gp_Dir2d(sign*gp_XY(-dirL1.Y(),dirL1.X()));
pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dp2l*dc2.XY());
pnttg2sol(NbrSol) = Point2;
pntcen(NbrSol) = pinterm;
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
pararg2(NbrSol) = 0.;
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
return;
}
}
//=========================================================================
// cas general. +
//=========================================================================
GccAna_LinPnt2dBisec Bis(L1,Point2);
if (Bis.IsDone()) {
Handle(GccInt_Bisec) Sol = Bis.ThisSolution();
GccInt_IType type = Sol->ArcType();
IntAna2d_AnaIntersection Intp;
if (type == GccInt_Lin) {
Intp.Perform(OnLine,Sol->Line());
}
if (type == GccInt_Par) {
Intp.Perform(OnLine,IntAna2d_Conic(Sol->Parabola()));
}
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real Radius = L1.Distance(Center);
// Standard_Integer nbsol = 1;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
((originL1.Y()-Center.Y())*(dirL1.X())))<=0){
ok = Standard_True;
}
}
else if (Qualified1.IsOutside()) {
if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
((originL1.Y()-Center.Y())*(dirL1.X())))>=0){
ok = Standard_True;
}
}
else if (Qualified1.IsUnqualified()) {
ok = Standard_True;
}
if (ok) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
qualifier2(NbrSol) = GccEnt_noqualifier;
gp_Dir2d dc2(originL1.XY()-Center.XY());
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc2.Dot(normal) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
TheSame1(NbrSol) = 0;
TheSame2(NbrSol) = 0;
gp_Dir2d dc1(originL1.XY()-Center.XY());
Standard_Real sign = dc1.Dot(gp_Dir2d(normal));
dc1=gp_Dir2d(sign*(normal.XY()));
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
pnttg2sol(NbrSol) = Point2;
pntcen(NbrSol) = Center;
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol) = 0.;
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
}
}
}
WellDone = Standard_True;
}
}
}

View File

@@ -0,0 +1,85 @@
// File: GccAna_Circ2d2TanOn_5.cxx
// Created: Thu Jan 2 15:55:26 1992
// Author: Remi GILET
// <reg@topsn3>
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
//=========================================================================
// Creation d un cercle Passant par : 2 points Point1 et Point2. +
// Centre sur : 1 droite OnLine. +
// avec une Tolerance de precision : Tolerance. +
// +
// On cree L1 la droite des points equidistant de Point1 et Point2. +
// On cree alors la solutions cirsol telle que : +
// cirsol est l ensemble des cercle ayant pour centre l intersections +
// de L1 avec OnLine et de rayon la distance entre Point1 et le point +
// ci dessus calcule. +
//=========================================================================
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const gp_Pnt2d& Point1 ,
const gp_Pnt2d& Point2 ,
const gp_Lin2d& OnLine ,
const Standard_Real Tolerance ):
cirsol(1,2) ,
qualifier1(1,2) ,
qualifier2(1,2),
TheSame1(1,2) ,
TheSame2(1,2) ,
pnttg1sol(1,2) ,
pnttg2sol(1,2) ,
pntcen(1,2) ,
par1sol(1,2) ,
par2sol(1,2) ,
pararg1(1,2) ,
pararg2(1,2) ,
parcen3(1,2)
{
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
gp_Dir2d dirx(1.,0.);
Standard_Real dist = Point1.Distance(Point2);
if (dist < Abs(Tolerance)) { WellDone = Standard_True; }
else {
gp_Lin2d L1(gp_Pnt2d((Point1.XY()+Point2.XY())/2.0),
gp_Dir2d(Point1.Y()-Point2.Y(),Point2.X()-Point1.X()));
IntAna2d_AnaIntersection Intp(L1,OnLine);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
NbrSol++;
gp_Ax2d axe(Intp.Point(i).Value(),dirx);
cirsol(NbrSol)=gp_Circ2d(axe,Point1.Distance(Intp.Point(i).Value()));
// ====================================================================
qualifier1(NbrSol) = GccEnt_noqualifier;
qualifier2(NbrSol) = GccEnt_noqualifier;
pnttg1sol(NbrSol) = Point1;
pnttg2sol(NbrSol) = Point2;
pntcen(NbrSol) = cirsol(NbrSol).Location();
pararg1(NbrSol) = 0.;
pararg2(NbrSol) = 0.;
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
}
}
WellDone = Standard_True;
}
}
}

View File

@@ -0,0 +1,329 @@
// File: GccAna_Circ2d2TanOn_6.cxx
// Created: Thu Jan 2 15:56:04 1992
// Author: Remi GILET
// <reg@topsn3>
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <GccAna_Circ2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BCirc.hxx>
#include <GccInt_BLine.hxx>
#include <IntAna2d_Conic.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Creation d un cercle tangent a deux cercle C1 et C2. +
// centre sur un cercle. +
// Nous commencons par distinguer les differents cas limites que nous +
// allons traiter separement. +
// Pour le cas general: +
// ==================== +
// Nous calculons les bissectrices a C1 et C2 qui nous donnent +
// l ensemble des lieux possibles des centres de tous les cercles +
// tangents aC1 et C2. +
// Nous intersectons ces bissectrices avec le cercle OnCirc ce qui nous +
// donne les points parmis lesquels nous allons choisir les solutions. +
// Les choix s effectuent a partir des Qualifieurs qualifiant C1 et C2. +
//=========================================================================
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 ,
const GccEnt_QualifiedCirc& Qualified2 ,
const gp_Circ2d& OnCirc ,
const Standard_Real Tolerance ):
cirsol(1,8) ,
qualifier1(1,8) ,
qualifier2(1,8) ,
TheSame1(1,8) ,
TheSame2(1,8) ,
pnttg1sol(1,8) ,
pnttg2sol(1,8) ,
pntcen(1,8) ,
par1sol(1,8) ,
par2sol(1,8) ,
pararg1(1,8) ,
pararg2(1,8) ,
parcen3(1,8)
{
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Real Tol= Abs(Tolerance);
gp_Circ2d C1 = Qualified1.Qualified();
gp_Circ2d C2 = Qualified2.Qualified();
gp_Dir2d dirx(1.,0.);
TColStd_Array1OfReal Radius(1,2);
TColStd_Array1OfReal Rradius(1,2);
gp_Pnt2d center1(C1.Location());
gp_Pnt2d center2(C2.Location());
#ifdef DEB
Standard_Real distance = center1.Distance(center2);
#else
center1.Distance(center2);
#endif
Standard_Real R1 = C1.Radius();
Standard_Real R2 = C2.Radius();
//=========================================================================
// Traitement des cas limites. +
//=========================================================================
Standard_Integer nbsol1 = 1;
Standard_Integer nbsol2 = 0;
Standard_Real Ron = OnCirc.Radius();
Standard_Real distcco = OnCirc.Location().Distance(center1);
gp_Dir2d dircc(OnCirc.Location().XY()-center1.XY());
gp_Pnt2d pinterm(center1.XY()+(distcco-Ron)*dircc.XY());
Standard_Real distcc2 =pinterm.Distance(center2);
Standard_Real distcc1 =pinterm.Distance(center1);
Standard_Real d1 = Abs(distcc2-R2-Abs(distcc1-R1));
Standard_Real d2 = Abs(distcc2+R2-Abs(distcc1-R1));
Standard_Real d3 = Abs(distcc2-R2-(distcc1+R1));
Standard_Real d4 = Abs(distcc2+R2-(distcc1+R1));
if ( d1 > Tol || d2 > Tol || d3 > Tol || d4 > Tol) {
pinterm = gp_Pnt2d(center1.XY()+(distcco+Ron)*dircc.XY());
distcc2 =pinterm.Distance(center2);
distcc1 =pinterm.Distance(center1);
d1 = Abs(distcc2-R2-Abs(distcc1-R1));
d2 = Abs(distcc2+R2-Abs(distcc1-R1));
d3 = Abs(distcc2-R2-(distcc1+R1));
d4 = Abs(distcc2+R2-(distcc1+R1));
if ( d1 > Tol || d2 > Tol || d3 > Tol || d4 > Tol) { nbsol1 = 0; }
}
if (nbsol1 > 0) {
if (Qualified1.IsEnclosed() || Qualified1.IsOutside()) {
nbsol1 = 1;
Radius(1) = Abs(distcc1-R1);
}
else if (Qualified1.IsEnclosing()) {
nbsol1 = 1;
Radius(1) = R1+distcc1;
}
else if (Qualified1.IsUnqualified()) {
nbsol1 = 2;
Radius(1) = Abs(distcc1-R1);
Radius(2) = R1+distcc1;
}
if (Qualified2.IsEnclosed() || Qualified2.IsOutside()) {
nbsol2 = 1;
Rradius(1) = Abs(distcc2-R2);
}
else if (Qualified2.IsEnclosing()) {
nbsol2 = 1;
Rradius(1) = R2+distcc2;
}
else if (Qualified2.IsUnqualified()) {
nbsol2 = 2;
Rradius(1) = Abs(distcc2-R2);
Rradius(2) = R2+distcc2;
}
for (Standard_Integer i = 1 ; i <= nbsol1 ; i++) {
for (Standard_Integer j = 1 ; j <= nbsol2 ; j++) {
if (Abs(Radius(i)-Rradius(j)) <= Tol) {
WellDone = Standard_True;
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),Radius(i));
// ===========================================================
gp_Dir2d dc1(center1.XY()-pinterm.XY());
gp_Dir2d dc2(center2.XY()-pinterm.XY());
distcc1 = pinterm.Distance(center1);
distcc2 = pinterm.Distance(center2);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(i)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(i)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (Abs(distcc2+Radius(i)-R2) < Tol) {
qualifier2(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc2-R2-Radius(i)) < Tol) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosing; }
pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+Radius(i)*dc1.XY());
pnttg2sol(NbrSol) = gp_Pnt2d(pinterm.XY()+Radius(i)*dc2.XY());
pntcen(NbrSol) = cirsol(NbrSol).Location();
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol));
}
}
}
if (WellDone) { return; }
}
//=========================================================================
// Cas general. +
//=========================================================================
GccAna_Circ2dBisec Bis(C1,C2);
if (Bis.IsDone()) {
TColStd_Array1OfReal Rbid(1,2);
TColStd_Array1OfReal RBid(1,2);
Standard_Integer nbsolution = Bis.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution ; i++) {
Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
GccInt_IType typ = Sol->ArcType();
IntAna2d_AnaIntersection Intp;
if (typ == GccInt_Cir) {
Intp.Perform(OnCirc,Sol->Circle());
}
else if (typ == GccInt_Lin) {
Intp.Perform(Sol->Line(),OnCirc);
}
else if (typ == GccInt_Hpr) {
Intp.Perform(OnCirc,IntAna2d_Conic(Sol->Hyperbola()));
}
else if (typ == GccInt_Ell) {
Intp.Perform(OnCirc,IntAna2d_Conic(Sol->Ellipse()));
}
if (Intp.IsDone()) {
if ((!Intp.IsEmpty())&&(!Intp.ParallelElements())&&
(!Intp.IdenticalElements())) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = Center.Distance(center1);
Standard_Real dist2 = Center.Distance(center2);
Standard_Integer nbsol = 0;
Standard_Integer nsol = 0;
Standard_Integer nnsol = 0;
R1 = C1.Radius();
R2 = C2.Radius();
if (Qualified1.IsEnclosed()) {
if (dist1-R1 < Tol) {
nbsol = 1;
Rbid(1) = Abs(R1-dist1);
}
}
else if (Qualified1.IsOutside()) {
if (R1-dist1 < Tol) {
nbsol = 1;
Rbid(1) = Abs(dist1-R1);
}
}
else if (Qualified1.IsEnclosing()) {
nbsol = 1;
Rbid(1) = dist1+R1;
}
else if (Qualified1.IsUnqualified()) {
nbsol = 2;
Rbid(1) = dist1+R1;
Rbid(1) = Abs(dist1-R1);
}
if (Qualified2.IsEnclosed() && nbsol != 0) {
if (dist2-R2 < Tol) {
nsol = 1;
RBid(1) = Abs(R2-dist2);
}
}
else if (Qualified2.IsOutside() && nbsol != 0) {
if (R2-dist2 < Tol) {
nsol = 1;
RBid(1) = Abs(R2-dist2);
}
}
else if (Qualified2.IsEnclosing() && nbsol != 0) {
nsol = 1;
RBid(1) = dist2+R2;
}
else if (Qualified2.IsUnqualified() && nbsol != 0) {
nsol = 2;
RBid(1) = dist2+R2;
RBid(2) = Abs(R2-dist2);
}
for (Standard_Integer isol = 1; isol <= nbsol ; isol++) {
for (Standard_Integer jsol = 1; jsol <= nsol ; jsol++) {
if (Abs(Rbid(isol)-RBid(jsol)) <= Tol) {
nnsol++;
Radius(nnsol) = (RBid(jsol)+Rbid(isol))/2.;
}
}
}
if (nnsol > 0) {
for (Standard_Integer k = 1 ; k <= nnsol ; k++) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
// ==========================================================
distcc1 = Center.Distance(center1);
distcc2 = Center.Distance(center2);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(k)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(k)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (Abs(distcc2+Radius(k)-R2) < Tol) {
qualifier2(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc2-R2-Radius(k)) < Tol) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosing; }
if (Center.Distance(center1) <= Tolerance &&
Abs(Radius(k)-C1.Radius()) <= Tolerance) {
TheSame1(NbrSol) = 1;
}
else {
TheSame1(NbrSol) = 0;
gp_Dir2d dc1(center1.XY()-Center.XY());
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc1.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
if (Center.Distance(center2) <= Tolerance &&
Abs(Radius(k)-C2.Radius()) <= Tolerance) {
TheSame2(NbrSol) = 1;
}
else {
TheSame2(NbrSol) = 0;
gp_Dir2d dc2(center2.XY()-Center.XY());
pnttg2sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc2.XY());
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
}
pntcen(NbrSol) = Center;
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol));
}
}
}
}
WellDone = Standard_True;
}
}
}
}

View File

@@ -0,0 +1,254 @@
// File: GccAna_Circ2d2TanOn_7.cxx
// Created: Thu Jan 2 15:57:15 1992
// Author: Remi GILET
// <reg@topsn3>
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <GccAna_CircLin2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BCirc.hxx>
#include <IntAna2d_Conic.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccEnt_BadQualifier.hxx>
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 ,
const GccEnt_QualifiedLin& Qualified2 ,
const gp_Circ2d& OnCirc ,
const Standard_Real Tolerance ):
cirsol(1,4) ,
qualifier1(1,4) ,
qualifier2(1,4),
TheSame1(1,4) ,
TheSame2(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
pntcen(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Real Radius=0;
gp_Dir2d dirx(1.,0.);
gp_Circ2d C1 = Qualified1.Qualified();
gp_Lin2d L2 = Qualified2.Qualified();
Standard_Real R1 = C1.Radius();
gp_Pnt2d center1(C1.Location());
gp_Pnt2d origin2(L2.Location());
gp_Dir2d dirL2(L2.Direction());
gp_Dir2d normL2(-dirL2.Y(),dirL2.X());
//=========================================================================
// Traitement des cas limites. +
//=========================================================================
Standard_Real Tol = Abs(Tolerance);
TColStd_Array1OfReal Rradius(1,2);
Standard_Integer nbsol1 = 1;
// Standard_Integer nbsol2 = 0;
Standard_Real Ron = OnCirc.Radius();
Standard_Real distcco = OnCirc.Location().Distance(center1);
gp_Dir2d dircc(OnCirc.Location().XY()-center1.XY());
gp_Pnt2d pinterm(center1.XY()+(distcco-Ron)*dircc.XY());
Standard_Real distpl2 =L2.Distance(pinterm);
Standard_Real distcc1 =pinterm.Distance(center1);
Standard_Real d1 = Abs(distpl2-Abs(distcc1-R1));
Standard_Real d2 = Abs(distpl2-(distcc1+R1));
if ( d1 > Tol || d2 > Tol ) {
pinterm = gp_Pnt2d(center1.XY()+(distcco-Ron)*dircc.XY());
if ( d1 > Tol || d2 > Tol ) {
nbsol1 = 0;
}
}
if (nbsol1 > 0) {
if (Qualified1.IsEnclosed() || Qualified1.IsOutside()) {
nbsol1 = 1;
Rradius(1) = Abs(distcc1-R1);
}
else if (Qualified1.IsEnclosing()) {
nbsol1 = 1;
Rradius(1) = R1+distcc1;
}
else if (Qualified1.IsUnqualified()) {
nbsol1 = 2;
Rradius(1) = Abs(distcc1-R1);
Rradius(2) = R1+distcc1;
}
gp_Dir2d dirbid(origin2.XY()-pinterm.XY());
gp_Dir2d normal(-dirL2.Y(),dirL2.X());
if (Qualified1.IsEnclosed() && dirbid.Dot(normal) < 0.) {
nbsol1 = 0;
}
else if (Qualified1.IsOutside() && dirbid.Dot(normal) < 0.) {
nbsol1 = 0;
}
for (Standard_Integer i = 1 ; i <= nbsol1 ; i++) {
if (Abs(Rradius(i)-distpl2) <= Tol) {
WellDone = Standard_True;
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),Rradius(i));
// ===========================================================
gp_Dir2d dc1(center1.XY()-pinterm.XY());
gp_Dir2d dc2(origin2.XY()-pinterm.XY());
distcc1 = pinterm.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Rradius(i)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Rradius(i)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (dc2.Dot(normL2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
Standard_Real sign = dc2.Dot(gp_Dir2d(-dirL2.Y(),dirL2.X()));
dc2 = gp_Dir2d(sign*gp_XY(-dirL2.Y(),dirL2.X()));
pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+Rradius(i)*dc1.XY());
pnttg2sol(NbrSol) = gp_Pnt2d(pinterm.XY()+Rradius(i)*dc2.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol));
}
}
if (WellDone) { return; }
}
//=========================================================================
// Cas general. +
//=========================================================================
GccAna_CircLin2dBisec Bis(C1,L2);
if (Bis.IsDone()) {
Standard_Integer nbsolution = Bis.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
GccInt_IType type = Sol->ArcType();
IntAna2d_AnaIntersection Intp;
if (type == GccInt_Lin) {
Intp.Perform(Sol->Line(),OnCirc);
}
else if (type == GccInt_Par) {
Intp.Perform(OnCirc,IntAna2d_Conic(Sol->Parabola()));
}
if (Intp.IsDone()) {
if ((!Intp.IsEmpty())&&(!Intp.ParallelElements())&&
(!Intp.IdenticalElements())) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = Center.Distance(center1);
Standard_Real dist2 = L2.Distance(Center);
// Standard_Integer nbsol = 1;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if (dist1-R1 < Tolerance) {
if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; }
}
}
else if (Qualified1.IsOutside()) {
if (R1-dist1 < Tolerance) {
if (Abs(Abs(R1-dist1)-dist2)<Tolerance) { ok=Standard_True; }
}
}
else if (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) {
ok = Standard_True;
}
if (Qualified2.IsEnclosed() && ok) {
if ((((origin2.X()-Center.X())*(-dirL2.Y()))+
((origin2.Y()-Center.Y())*(dirL2.X())))<=0){
ok = Standard_True;
Radius = dist2;
}
}
else if (Qualified2.IsOutside() && ok) {
if ((((origin2.X()-Center.X())*(-dirL2.Y()))+
((origin2.Y()-Center.Y())*(dirL2.X())))>=0){
ok = Standard_True;
Radius = dist2;
}
}
else if (Qualified2.IsUnqualified() && ok) {
ok = Standard_True;
Radius = dist2;
}
if (ok) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
gp_Dir2d dc2(origin2.XY()-Center.XY());
distcc1 = Center.Distance(center1);
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 (dc2.Dot(normL2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
if (Center.Distance(center1) <= Tolerance &&
Abs(Radius-C1.Radius()) <= Tolerance) {
TheSame1(NbrSol) = 1;
}
else {
TheSame1(NbrSol) = 0;
gp_Dir2d dc1(center1.XY()-Center.XY());
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
TheSame2(NbrSol) = 0;
Standard_Real sign = dc2.Dot(gp_Dir2d(normL2.XY()));
dc2 = gp_Dir2d(sign*gp_XY(normL2.XY()));
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY());
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
pntcen(NbrSol) = Center;
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol));
}
}
}
WellDone = Standard_True;
}
}
}
}

View File

@@ -0,0 +1,249 @@
// File: GccAna_Circ2d2TanOn_8.cxx
// Created: Thu Jan 2 15:58:06 1992
// Author: Remi GILET
// <reg@topsn3>
//=========================================================================
// Creation d un cercle tangent a deux elements : Droite. +
// Cercle. +
// Point. +
// centre sur un troisieme : Droite. +
// Cercle. +
//=========================================================================
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <Standard_ConstructionError.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_Bisec.hxx>
#include <GccInt_BLine.hxx>
#include <GccInt_BCirc.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccAna_CircPnt2dBisec.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <Precision.hxx>
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc& Qualified1 ,
const gp_Pnt2d& Point2 ,
const gp_Circ2d& OnCirc ,
const Standard_Real Tolerance ):
cirsol(1,4) ,
qualifier1(1,4) ,
qualifier2(1,4),
TheSame1(1,4) ,
TheSame2(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
pntcen(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Real Tol = Abs(Tolerance);
TColStd_Array1OfReal Radius(1,2);
gp_Dir2d dirx(1.,0.);
gp_Circ2d C1 = Qualified1.Qualified();
Standard_Real R1 = C1.Radius();
gp_Pnt2d center1(C1.Location());
//=========================================================================
// Traitement des cas limites. +
//=========================================================================
Standard_Integer nbsol1 = 1;
// Standard_Integer nbsol2 = 0;
Standard_Real Ron = OnCirc.Radius();
Standard_Real distcco = OnCirc.Location().Distance(center1);
gp_Pnt2d pinterm;
gp_Dir2d dircc;
Standard_Boolean SameCenter(Standard_False);
if (!OnCirc.Location().IsEqual(center1,Precision::Confusion())) {
dircc = gp_Dir2d(OnCirc.Location().XY()-center1.XY());
pinterm = gp_Pnt2d(center1.XY()+(distcco-Ron)*dircc.XY());
Standard_Real distcc2 =pinterm.Distance(Point2);
Standard_Real distcc1 =pinterm.Distance(center1);
Standard_Real d1 = Abs(distcc2-Abs(distcc1-R1));
Standard_Real d2 = Abs(distcc2-(distcc1+R1));
if ( d1 > Tol || d2 > Tol) {
if (!SameCenter) pinterm = gp_Pnt2d(center1.XY()+(distcco+Ron)*dircc.XY());
distcc2 =pinterm.Distance(Point2);
distcc1 =pinterm.Distance(center1);
d1 = Abs(distcc2-Abs(distcc1-R1));
d2 = Abs(distcc2-(distcc1+R1));
if ( d1 > Tol || d2 > Tol ) { nbsol1 = 0; }
}
if (nbsol1 > 0) {
if (Qualified1.IsEnclosed() || Qualified1.IsOutside()) {
nbsol1 = 1;
Radius(1) = Abs(distcc1-R1);
}
else if (Qualified1.IsEnclosing()) {
nbsol1 = 1;
Radius(1) = R1+distcc1;
}
else if (Qualified1.IsUnqualified()) {
nbsol1 = 2;
Radius(1) = Abs(distcc1-R1);
Radius(2) = R1+distcc1;
}
for (Standard_Integer i = 1 ; i <= nbsol1 ; i++) {
WellDone = Standard_True;
if (!(i == 1 && SameCenter)) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),Radius(i));
// ===========================================================
gp_Dir2d dc1;
if (!SameCenter) dc1 = gp_Dir2d(center1.XY()-pinterm.XY());
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(i)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(i)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
qualifier2(NbrSol) = GccEnt_noqualifier;
if (!SameCenter)
pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+Radius(i)*dc1.XY());
else
pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY());
pnttg2sol(NbrSol) = Point2;
pntcen(NbrSol) = cirsol(NbrSol).Location();
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
pararg2(NbrSol) = 0.;
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol));
}
}
if (WellDone) { return; }
}
}
//=========================================================================
// cas general. +
//=========================================================================
GccAna_CircPnt2dBisec Bis(C1,Point2);
if (Bis.IsDone()) {
Standard_Integer nbsolution = Bis.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution; i++) {
Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
GccInt_IType type = Sol->ArcType();
IntAna2d_AnaIntersection Intp;
if (type == GccInt_Lin) {
Intp.Perform(Sol->Line(),OnCirc);
}
else if (type == GccInt_Cir) {
Intp.Perform(OnCirc,Sol->Circle());
}
else if (type == GccInt_Hpr) {
Intp.Perform(OnCirc,IntAna2d_Conic(Sol->Hyperbola()));
}
else if (type == GccInt_Ell) {
Intp.Perform(OnCirc,IntAna2d_Conic(Sol->Ellipse()));
}
if (Intp.IsDone()) {
if ((!Intp.IsEmpty())&&(!Intp.ParallelElements())&&
(!Intp.IdenticalElements())) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = center1.Distance(Center);
Standard_Integer nbsol = 1;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if (dist1-C1.Radius() <= Tol) {
ok = Standard_True;
Radius(1) = Abs(C1.Radius()-dist1);
}
}
else if (Qualified1.IsOutside()) {
if (C1.Radius()-dist1 <= Tol) {
ok = Standard_True;
Radius(1) = Abs(C1.Radius()-dist1);
}
}
else if (Qualified1.IsEnclosing()) {
ok = Standard_True;
Radius(1) = C1.Radius()+dist1;
}
else if (Qualified1.IsUnqualified()) {
ok = Standard_True;
nbsol = 2;
Radius(1) = Abs(C1.Radius()-dist1);
Radius(2) = C1.Radius()+dist1;
}
if (ok) {
for (Standard_Integer k = 1 ; k <= nbsol ; k++) {
// pop : protection contre le cas center1 == Center
if (center1.IsEqual(Center,Precision::Confusion())) {
continue;
}
if (OnCirc.Distance(Center)>Tol) {
continue;
}
if (NbrSol == 4 ) break;
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
// ==========================================================
Standard_Real distcc1 = Center.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(k)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(k)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
qualifier2(NbrSol) = GccEnt_noqualifier;
if (distcc1 <= Tol && Abs(Radius(k)-C1.Radius()) <= Tol) {
TheSame1(NbrSol) = 1;
}
else {
TheSame1(NbrSol) = 0;
gp_Dir2d dc1(center1.XY()-Center.XY());
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+
Radius(k)*dc1.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
TheSame2(NbrSol) = 0;
pntcen(NbrSol) = Center;
pnttg2sol(NbrSol) = Point2;
pararg2(NbrSol) = 0.;
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol));
}
}
}
}
WellDone = Standard_True;
}
}
}
}

View File

@@ -0,0 +1,292 @@
// File: GccAna_Circ2d2TanOn_9.cxx
// Created: Thu Jan 2 15:58:51 1992
// Author: Remi GILET
// <reg@topsn3>
#include <GccAna_Circ2d2TanOn.jxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <GccAna_Lin2dBisec.hxx>
#include <gp.hxx>
#include <GccEnt_BadQualifier.hxx>
GccAna_Circ2d2TanOn::
GccAna_Circ2d2TanOn (const GccEnt_QualifiedLin& Qualified1 ,
const GccEnt_QualifiedLin& Qualified2 ,
const gp_Circ2d& OnCirc ,
const Standard_Real
#ifdef DEB
Tolerance
#endif
):
cirsol(1,4) ,
qualifier1(1,4) ,
qualifier2(1,4),
TheSame1(1,4) ,
TheSame2(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
pntcen(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
TheSame2.Init(0);
WellDone = Standard_False;
NbrSol = 0;
gp_Dir2d dirx(1.,0.);
#ifdef DEB
Standard_Real Tol = Abs(Tolerance);
#endif
if (!(Qualified1.IsEnclosed() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
gp_Lin2d L1(Qualified1.Qualified());
gp_Lin2d L2(Qualified2.Qualified());
GccAna_Lin2dBisec Bis(L1,L2);
Standard_Integer i=0,j=0;
Standard_Integer nbsol = 0;
Standard_Real sgn = 1.;
Standard_Real s = 1.;
Standard_Boolean ok = Standard_False;
gp_Dir2d D1(L1.Direction());
gp_Dir2d D2(L2.Direction());
gp_Dir2d Dnor1(-D1.Y(),D1.X());
gp_Dir2d Dnor2(-D2.Y(),D2.X());
gp_XY XYnor1(-D1.Y(),D1.X());
gp_XY XYnor2(-D2.Y(),D2.X());
gp_Pnt2d originL1(L1.Location());
gp_Pnt2d originL2(L2.Location());
gp_XY Dloc(originL1.XY()-originL2.XY());
if (D1.Angle(D2) <= gp::Resolution()) {
if (Qualified1.IsEnclosed()) {
if (Dloc.Dot(XYnor1) <= 0.) { ok = Standard_True; }
else { ok = Standard_False; }
}
else if (Qualified1.IsOutside()) {
if (Dloc.Dot(XYnor1) >= 0.) { ok = Standard_True; }
else { ok = Standard_False; }
}
else {ok = Standard_True; }
if (Qualified2.IsEnclosed()) {
if (Dloc.Dot(XYnor2) >= 0.) { ok = Standard_True; }
else { ok = Standard_False; }
}
else if (Qualified2.IsOutside()) {
if (Dloc.Dot(XYnor2) <= 0.) { ok = Standard_True; }
else { ok = Standard_False; }
}
else {ok = Standard_True; }
if ( ok ) {
IntAna2d_AnaIntersection Intp(Bis.ThisSolution(1),OnCirc);
if (Intp.IsDone()) {
WellDone = Standard_True;
if (!Intp.IsEmpty()) {
for (Standard_Integer l = 1 ; l <= Intp.NbPoints() ; l++) {
NbrSol++;
gp_Pnt2d pt(Intp.Point(l).Value());
gp_Ax2d axe(pt,dirx);
cirsol(NbrSol) = gp_Circ2d(axe,L1.Distance(pt));
// ===============================================
gp_Dir2d dc1(originL1.XY()-pt.XY());
gp_Dir2d dc2(originL2.XY()-pt.XY());
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc1.Dot(Dnor1) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (dc2.Dot(Dnor2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
}
}
}
}
}
else if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
//============================================================
if (Bis.IsDone()) {
if (Bis.NbSolutions() == 2) {
nbsol = 1;
i = 2;
j = 1;
sgn = -1.;
}
}
}
else if (Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
//===========================================================
if (Bis.IsDone()) {
if (Bis.NbSolutions() >= 1) {
nbsol = 1;
i = 1;
j = 1;
if (D1.Angle(D2) >= 0.0) { sgn = -1.; }
}
}
}
else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
//===========================================================
if (Bis.IsDone()) {
if (Bis.NbSolutions() >= 1) {
nbsol = 1;
i = 1;
j = 1;
if (D1.Angle(D2) <= 0.0) { sgn = -1.; }
}
}
}
else if (Qualified1.IsOutside() && Qualified2.IsOutside()) {
//==========================================================
if (Bis.IsDone()) {
if (Bis.NbSolutions() >= 1) {
nbsol = 1;
i = 2;
j = 1;
}
}
}
else if (Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
//=============================================================
if (Bis.IsDone()) {
nbsol = 2;
if (Bis.NbSolutions() >= 1) {
i = 1;
j = 2;
}
if (D1.Angle(D2) >= 0.0) { s = -1.; }
else { sgn = -1.; }
}
}
else if (Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
//==============================================================
if (Bis.IsDone()) {
nbsol = 2;
if (Bis.NbSolutions() >= 1) {
i = 1;
j = 2;
}
if (D1.Angle(D2) >= 0.0) {
s = -1.;
sgn = -1.;
}
}
}
else if (Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
//===============================================================
if (Bis.IsDone()) {
nbsol = 2;
if (Bis.NbSolutions() >= 1) {
i = 1;
j = 2;
}
if (D1.Angle(D2) >= 0.0) { sgn = -1.; }
else { s = -1.; }
}
}
else if (Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
//==============================================================
if (Bis.IsDone()) {
nbsol = 2;
if (Bis.NbSolutions() >= 1) {
i = 1;
j = 2;
}
if (D1.Angle(D2) <= 0.0) {
s = -1.;
sgn = -1.;
}
}
}
else if (Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
//==================================================================
nbsol = 4;
i = 1;
j = 2;
}
if (nbsol >= 1) {
if (Bis.IsDone()) {
Standard_Integer kk = 0;
for (Standard_Integer k = i ; k <= i+j-1 ; k++) {
kk++;
IntAna2d_AnaIntersection Intp(Bis.ThisSolution(k),OnCirc);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer l = 1 ; l <= Intp.NbPoints() ; l++) {
gp_Vec2d V(Intp.Point(l).Value(),
Bis.ThisSolution(k).Location());
if ((kk==1 && sgn*V.Dot(Bis.ThisSolution(k).Direction())>=0.0)||
(kk==2 && sgn*s*V.Dot(Bis.ThisSolution(k).Direction())>=0.0)
|| nbsol == 4) {
NbrSol++;
gp_Pnt2d pt(Intp.Point(i).Value());
gp_Ax2d axe(pt,dirx);
cirsol(NbrSol) = gp_Circ2d(axe,
// ===============================
L1.Distance(Intp.Point(l).Value()));
// ===================================
gp_Dir2d dc1(originL1.XY()-pt.XY());
gp_Dir2d dc2(originL2.XY()-pt.XY());
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc1.Dot(Dnor1) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (dc2.Dot(Dnor2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
}
}
}
WellDone = Standard_True;
}
}
}
}
if (NbrSol > 0) {
for (i =1 ; i <= NbrSol ; i++) {
gp_Pnt2d pbid(cirsol(i).Location());
Standard_Real Radius = cirsol(i).Radius();
gp_Dir2d dc2(originL1.XY()-pbid.XY());
Standard_Real sign = dc2.Dot(gp_Dir2d(-L1.Direction().Y(),
L1.Direction().X()));
dc2 = gp_Dir2d(sign*gp_XY(-L1.Direction().Y(),L1.Direction().X()));
pnttg1sol(i) = gp_Pnt2d(pbid.XY()+Radius*dc2.XY());
dc2 = gp_Dir2d(originL2.XY()-pbid.XY());
sign = dc2.Dot(gp_Dir2d(-L2.Direction().Y(),L2.Direction().X()));
dc2 = gp_Dir2d(sign*gp_XY(-L2.Direction().Y(),L2.Direction().X()));
pnttg2sol(i) = gp_Pnt2d(pbid.XY()+Radius*dc2.XY());
pntcen(i) = pbid;
par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
pararg1(i)=ElCLib::Parameter(L1,pnttg1sol(i));
par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
pararg2(i)=ElCLib::Parameter(L2,pnttg2sol(i));
parcen3(i)=ElCLib::Parameter(OnCirc,pntcen(i));
}
}
}

View File

@@ -0,0 +1,266 @@
-- File: Circ2d2TanRad.cdl
-- Created: Thu Mar 21 02:26:20 1991
-- Author: Philippe DAUTRY
-- <fid@phobox>
---Copyright: Matra Datavision 1991
class Circ2d2TanRad
from GccAna
---Purpose: This class implements the algorithms used to
-- create 2d circles tangent to 2
-- points/lines/circles and with a given radius.
-- For each construction methods arguments are:
-- - Two Qualified elements for tangency constraints.
-- (for example EnclosedCirc if we want the
-- solution inside the argument EnclosedCirc).
-- - Two Reals. One (Radius) for the radius and the
-- other (Tolerance) for the tolerance.
-- Tolerance is only used for the limit cases.
-- For example :
-- We want to create a circle inside a circle C1 and
-- inside a circle C2 with a radius Radius and a
-- tolerance Tolerance.
-- If we do not use Tolerance it is impossible to
-- find a solution in the following case : C2 is
-- inside C1 and there is no intersection point
-- between the two circles.
-- With Tolerance it gives a solution if the lowest
-- distance between C1 and C2 is lower than or equal
-- Tolerance.
uses Pnt2d from gp,
Circ2d from gp,
QualifiedLin from GccEnt,
QualifiedCirc from GccEnt,
Array1OfReal from TColStd,
Array1OfInteger from TColStd,
Array1OfCirc2d from TColgp,
Array1OfPnt2d from TColgp,
Position from GccEnt,
Array1OfPosition from GccEnt
raises NegativeValue from Standard,
OutOfRange from Standard,
BadQualifier from GccEnt,
NotDone from StdFail
is
Create(Qualified1 : QualifiedCirc from GccEnt ;
Qualified2 : QualifiedCirc from GccEnt ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2d2TanRad
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to two 2d circle with a
-- radius of Radius.
raises NegativeValue, BadQualifier;
---Purpose: It raises NegativeValue if Radius is lower than zero.
Create(Qualified1 : QualifiedCirc from GccEnt ;
Qualified2 : QualifiedLin from GccEnt ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2d2TanRad
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to a 2d circle and a 2d line
-- with a radius of Radius.
raises NegativeValue, BadQualifier;
---Purpose: It raises NegativeValue if Radius is lower than zero.
Create(Qualified1 : QualifiedCirc from GccEnt ;
Point2 : Pnt2d from gp ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2d2TanRad
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to a 2d circle and a point
-- with a radius of Radius.
raises NegativeValue, BadQualifier;
---Purpose: It raises NegativeValue if Radius is lower than zero.
Create(Qualified1 : QualifiedLin from GccEnt ;
Point2 : Pnt2d from gp ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2d2TanRad
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to a 2d line and a point
-- with a radius of Radius.
raises NegativeValue, BadQualifier;
---Purpose: It raises NegativeValue if Radius is lower than zero.
Create(Qualified1 : QualifiedLin from GccEnt ;
Qualified2 : QualifiedLin from GccEnt ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2d2TanRad
---Purpose: This method implements the algorithms used to
-- create 2d circles TANgent to two 2d lines
-- with a radius of Radius.
raises NegativeValue, BadQualifier;
---Purpose: It raises NegativeValue if Radius is lower than zero.
Create(Point1 : Pnt2d from gp ;
Point2 : Pnt2d from gp ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2d2TanRad
---Purpose: This method implements the algorithms used to
-- create 2d circles passing through two points with a
-- radius of Radius.
raises NegativeValue;
---Purpose: It raises NegativeValue if Radius is lower than zero.
-- -- ....................................................................
IsDone(me) returns Boolean from Standard
is static;
---Purpose: This method returns True if the algorithm succeeded.
-- Note: IsDone protects against a failure arising from a
-- more internal intersection algorithm, which has reached its numeric limits.
NbSolutions(me) returns Integer from Standard
---Purpose: This method returns the number of circles, representing solutions computed by this algorithm.
-- Exceptions
-- StdFail_NotDone if the construction fails. of solutions.
raises NotDone
is static;
ThisSolution(me ;
Index : Integer from Standard) returns Circ2d from gp
---Purpose: Returns the solution number Index.
-- Be careful: the Index is only a way to get all the
-- solutions, but is not associated to those outside the context
-- of the algorithm-object. Raises OutOfRange exception if Index is greater
-- than the number of solutions.
-- It raises NotDone if the construction algorithm did not
-- succeed.
raises OutOfRange, NotDone
is static;
WhichQualifier(me ;
Index : Integer from Standard;
Qualif1 : out Position from GccEnt ;
Qualif2 : out Position from GccEnt )
raises OutOfRange, NotDone
is static;
---Purpose: Returns the information about the qualifiers of
-- the tangency arguments concerning the solution number Index.
-- It returns the real qualifiers (the qualifiers given to the
-- constructor method in case of enclosed, enclosing and outside
-- and the qualifiers computedin case of unqualified).
Tangency1(me ;
Index : Integer from Standard;
ParSol : out Real from Standard;
ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns information about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point PntSol on the solution.
-- ParArg is the intrinsic parameter of the point PntSol on the first
-- argument. Raises OutOfRange if Index is greater than the number
-- of solutions.
-- It raises NotDone if the construction algorithm did not succeed
raises OutOfRange, NotDone
is static;
Tangency2(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns information about the tangency point between the
-- result number Index and the second argument.
-- ParSol is the intrinsic parameter of the point PntSol on
-- the solution.
-- ParArg is the intrinsic parameter of the point PntArg on
-- the second argument. Raises OutOfRange if Index is greater than the number
-- of solutions.
-- It raises NotDone if the construction algorithm did not succeed.
raises OutOfRange, NotDone
is static;
IsTheSame1(me ;
Index : Integer from Standard) returns Boolean from Standard
---Purpose: Returns True if the solution number Index is equal to
-- the first argument. Raises OutOfRange if Index is greater than the number
-- of solutions.
-- It raises NotDone if the construction algorithm did not
-- succeed.
raises OutOfRange, NotDone
is static;
IsTheSame2(me ;
Index : Integer from Standard) returns Boolean from Standard
---Purpose: Returns True if the solution number Index is equal to
-- the second argument. Raises OutOfRange if Index is greater than the number
-- of solutions.
-- It raises NotDone if the construction algorithm did not succeed.
raises OutOfRange, NotDone
is static;
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
qualifier1 : Array1OfPosition from GccEnt;
-- The qualifiers of the first argument.
qualifier2 : Array1OfPosition from GccEnt;
-- The qualifiers of the second argument.
TheSame1 : Array1OfInteger from TColStd;
---Purpose: 1 if the solution and the first argument are the same
-- (2 circles).
-- If R1 is the radius of the first argument and Rsol the radius
-- of the solution and dist the distance between the two centers,
-- we consider the two circles are identical if R1+dist-Rsol is
-- less than Tolerance.
-- 0 in the other cases.
TheSame2 : Array1OfInteger from TColStd;
---Purpose: 1 if the solution and the second argument are the same
-- (2 circles).
-- If R2 is the radius of the second argument and Rsol the radius
-- of the solution and dist the distance between the two centers,
-- we consider the two circles are identical if R2+dist-Rsol is
-- less than Tolerance.
-- 0 in the other cases.
NbrSol : Integer from Standard;
---Purpose: The number of possible solutions.
cirsol : Array1OfCirc2d from TColgp;
---Purpose: The solutions.
pnttg1sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the first
-- argument on the solution.
pnttg2sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the second
-- argument on the solution.
par1sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the solution.
par2sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the second argument on the solution.
pararg1 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the first argument.
pararg2 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the second argument on the second argument.
end Circ2d2TanRad;

View File

@@ -0,0 +1,741 @@
// File GccAna_Circ2d2TanRad.cxx, REG 08/07/91
// Modified: Thu Dec 5 09:46:23 1996
// by: Joelle CHAUVET
// Indice de boucle pour par1sol,par2sol,pararg1,pararg2
// (PRO6126)
// Modified: Mon May 11 10:42:16 1998
// Author: Joelle CHAUVET
// Permutation pnttg1sol<->pnttg2sol oubliee dans certains cas
// (CTS20080)
#include <GccAna_Circ2d2TanRad.ixx>
#include <ElCLib.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Lin2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <Standard_NegativeValue.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <Precision.hxx>
// circulaire tangent a deux cercles et de rayon donne
//====================================================
//========================================================================
// On initialise WellDone a false. +
// On recupere le cercle C1 et le cercle C2. +
// On sort en erreur dans les cas ou la construction est impossible. +
// On distingue les cas limites pour les triater separement. +
// On fait la parallele a C1 dans le bon sens. +
// On fait la parallele a C2 dans le bon sens. +
// On intersecte les paralleles ==> point de centre de la solution. +
// On cree la solution qu on ajoute aux solutions deja trouvees. +
// On remplit les champs. +
//========================================================================
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())) {
GccEnt_BadQualifier::Raise();
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) { Standard_NegativeValue::Raise(); }
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();
// il faudra permuter les points de tangence resultats
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();
// il faudra permuter les points de tangence resultats
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();
// il faudra permuter les points de tangence resultats
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();
// il faudra permuter les point de tangence resultats
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()-(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();
// il faudra permuter les points de tangence resultats
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;
}
}
}
}
// permutation des points de tangence resultats si necessaire
if (invers) {
gp_Pnt2d Psav;
for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
Psav = pnttg1sol(i);
pnttg1sol(i) = pnttg2sol(i);
pnttg2sol(i) = Psav;
}
}
// calcul des parametres des points de tangence
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) { StdFail_NotDone::Raise(); }
if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
return cirsol(Index);
}
void GccAna_Circ2d2TanRad::
WhichQualifier(const Standard_Integer Index ,
GccEnt_Position& Qualif1 ,
GccEnt_Position& Qualif2 ) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
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) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
if (TheSame1(Index) == 0) {
ParSol = par1sol(Index);
ParArg = pararg1(Index);
PntSol = gp_Pnt2d(pnttg1sol(Index));
}
else { StdFail_NotDone::Raise(); }
}
}
void GccAna_Circ2d2TanRad::
Tangency2 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
if (TheSame2(Index) == 0) {
ParSol = par2sol(Index);
ParArg = pararg2(Index);
PntSol = gp_Pnt2d(pnttg2sol(Index));
}
else { StdFail_NotDone::Raise(); }
}
}
Standard_Boolean GccAna_Circ2d2TanRad::
IsTheSame1 (const Standard_Integer Index) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
if (TheSame1(Index) == 0) { return Standard_False; }
return Standard_True;
}
Standard_Boolean GccAna_Circ2d2TanRad::
IsTheSame2 (const Standard_Integer Index) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
if (TheSame2(Index) == 0) { return Standard_False; }
return Standard_True;
}

View File

@@ -0,0 +1,478 @@
// File: GccAna_Circ2d2TanRad_1.cxx
// Created: Tue Sep 24 09:09:48 1991
// Author: Remi GILET
// <reg@topsn2>
#include <GccAna_Circ2d2TanRad.jxx>
#include <ElCLib.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Lin2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Standard_NegativeValue.hxx>
#include <GccEnt_BadQualifier.hxx>
// circulaire tangent a un cercle et une ligne et de rayon donne
//==============================================================
//========================================================================
// On initialise WellDone a false. +
// On recupere le cercle C1 et la droite L2. +
// On sort en erreur dans les cas ou la construction est impossible. +
// On fait la parallele a C1 dans le bon sens. +
// On fait la parallele a L2 dans le bon sens. +
// On intersecte les paralleles ==> point de centre de la solution. +
// On cree la solution qu on ajoute aux solutions deja trouvees. +
// On remplit les champs. +
//========================================================================
GccAna_Circ2d2TanRad::
GccAna_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1 ,
const GccEnt_QualifiedLin& 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.);
NbrSol = 0;
WellDone = Standard_False;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() || Qualified2.IsOutside() ||
Qualified2.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Integer i ;
for ( i = 1 ; i <= 8 ; i++) { TheSame2(i) = 0; }
Standard_Integer ncote1=0;
Standard_Integer ncote2=0;
Standard_Integer nbsol = 0;
Standard_Real cote = 0.0;
Standard_Real ccote = 0.0;
TColStd_Array1OfReal cote1(1,3);
TColStd_Array1OfReal cote2(1,2);
gp_Circ2d C1 = Qualified1.Qualified();
gp_Lin2d L2 = Qualified2.Qualified();
Standard_Real xdir = (L2.Direction()).X();
Standard_Real ydir = (L2.Direction()).Y();
gp_Dir2d normL2(-ydir,xdir);
Standard_Real lxloc = (L2.Location()).X();
Standard_Real lyloc = (L2.Location()).Y();
Standard_Real cxloc = (C1.Location()).X();
Standard_Real cyloc = (C1.Location()).Y();
Standard_Real R1 = C1.Radius();
gp_Pnt2d center1(cxloc,cyloc);
gp_Pnt2d origin2(lxloc,lyloc);
Standard_Real dist = Radius*2.0 + R1;
Standard_Real distance = L2.Distance(center1);
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else {
if ( distance-dist >Tol) { WellDone = Standard_True; }
else if (Qualified1.IsEnclosed()) {
// =================================
if (Qualified2.IsEnclosed()) {
// ============================
if (distance-R1 > Tol) { WellDone = Standard_True; }
else if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
(Radius*2.0-R1+distance > Tol)) ||
((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
(Radius*2.0-R1-distance > Tol))||
(Radius-R1 > Tol)) { WellDone = Standard_True; }
else {
if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
(Radius*2.0>R1-distance)) || (Abs(distance-R1)<Tol) ||
((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
(Radius*2.0 > (R1+distance+Tol)))) {
cote = 1.0;
nbsol = 3;
ccote = 1.0;
}
else {
ncote1 = 1;
ncote2 = 1;
cote1(1) = R1-Radius;
cote2(1) = 1.0;
nbsol = 1;
}
}
}
else if (Qualified2.IsOutside()) {
// ================================
if (distance > R1+Tol) { WellDone = Standard_True; }
else if ((((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)) > 0.0) &&
(Radius*2.0-R1+distance > Tol)) ||
(((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)) < 0.0) &&
(Radius*2.0-R1-distance > Tol)) ||
(Radius-R1 >Tol)) { WellDone = Standard_True; }
else {
if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) > 0.0) &&
(Radius*2.0 > R1-distance)) || (Abs(R1-Radius) < Tol) ||
((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) < 0.0) &&
(Radius*2.0>(R1+distance))) || (Abs(distance-R1)<Tol)) {
cote = -1.0;
nbsol = 3;
ccote = 1.0;
}
else {
ncote1 = 1;
ncote2 = 1;
cote1(1) = R1-Radius;
cote2(1) = -1.0;
nbsol = 1;
}
}
}
else if (Qualified2.IsUnqualified()) {
// ====================================
if ((distance-R1>Tol) || (Radius*2.0-R1-distance>Tol) ||
(Radius-R1 > Tol)) { WellDone = Standard_True; }
else if (distance > R1) {
if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) > 0.0)) {
cote = 1.0;
}
else {
cote = -1.0;
nbsol = 3;
}
nbsol = 3;
ccote = 1;
}
else {
ncote1 = 1;
ncote2 = 2;
cote1(1) = R1-Radius;
cote2(1) = 1.0;
cote2(2) = -1.0;
nbsol = 1;
}
}
if (nbsol == 3) {
}
}
else if (Qualified1.IsEnclosing()) {
// ==================================
if (Qualified2.IsEnclosed()) {
// =================================
if ((distance<R1-Tol)||(Radius<R1-Tol)||(Radius*2<distance+R1-Tol) ||
(Tol<R1-Radius)||(-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0)){
WellDone = Standard_True;
}
else if ((distance<R1) || (Radius<R1) || (Radius*2.0<distance+R1)) {
cote = 1.0;
ccote =1.0;
nbsol = 3;
}
else {
ncote1 = 1;
ncote2 = 1;
cote1(1) = Radius-R1;
cote2(1) = 1.0;
nbsol = 1;
}
}
else if (Qualified2.IsOutside()) {
// ================================
if ((Tol<R1-distance) || (Tol<distance+R1-Radius*2.0) ||
(Tol<R1-Radius)||(-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0)){
WellDone = Standard_True;
}
else if ((distance<R1) || (Radius*2.0<distance+R1) || (Radius<R1)) {
cote = -1.0;
ccote = -1.0;
nbsol = 3;
}
else {
ncote1 = 1;
ncote2 = 1;
cote1(1) = Radius-R1;
cote2(1) = -1.0;
nbsol = 1;
}
}
else if (Qualified2.IsUnqualified()) {
// ====================================
if ((distance<R1-Tol) || (Radius*2.0<distance+R1-Tol) ||
(Radius < R1-Tol)) { WellDone = Standard_True; }
else if ((distance < R1) || (Radius*2.0 < distance+R1)) {
if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc) > 0.0)) {
cote = 1.0;
ccote = 1.0;
nbsol = 3;
}
else {
ccote = -1.0;
cote = -1.0;
nbsol = 3;
}
}
else {
ncote1 = 1;
ncote2 = 2;
cote1(1) = Radius-R1;
cote2(1) = 1.0;
cote2(2) = -1.0;
nbsol = 1;
}
}
}
else if ((Qualified1.IsOutside()) && (Qualified2.IsEnclosed())) {
// ===============================================================
if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
(distance>R1+Tol)) || (distance > R1+Radius*2.0+Tol)) {
WellDone = Standard_True;
}
else {
if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
(distance>R1)) {
cote = 1.0;
nbsol = 2;
}
else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
(distance>R1+2.0*Radius)) {
cote = -1.0;
nbsol = 2;
}
else {
ncote1 = 1;
ncote2 = 1;
cote1(1) = Radius+R1;
cote2(1) = 1.0;
nbsol = 1;
}
}
}
else if ((Qualified1.IsOutside()) && (Qualified2.IsOutside())) {
// ==============================================================
if (((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
(distance>R1+Tol)) || (distance > R1+Radius*2.0+Tol)) {
WellDone = Standard_True;
}
else {
if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) && (distance>R1)) {
cote = -1.0;
nbsol = 2;
}
else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
(distance>R1+2.0*Radius)) {
cote = 1.0;
nbsol = 2;
}
else {
ncote1 = 1;
ncote2 = 1;
cote1(1) = Radius+R1;
cote2(1) = -1.0;
nbsol = 1;
}
}
}
else if ((Qualified1.IsOutside()) && (Qualified2.IsUnqualified())) {
// ==================================================================
if (distance > Radius*2.0+R1+Tol) { WellDone = Standard_True; }
else if (distance > Radius*2.0+R1) {
if (-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) { cote = 1.0; }
else { cote = -1.0; }
nbsol = 4;
}
else {
ncote1 = 1;
ncote2 = 2;
cote1(1) = Radius+R1;
cote2(1) = 1.0;
cote2(2) = -1.0;
nbsol = 1;
}
}
else if ((Qualified1.IsUnqualified()) && (Qualified2.IsEnclosed())) {
// ===================================================================
if ((distance>R1+Radius*2.0+Tol) ||
((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
(distance > R1+Tol))){ WellDone = Standard_True; }
else {
if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) && (distance > R1)){
cote = 1.0;
nbsol = 2;
}
else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
(distance>R1+2.0*Radius)) {
cote = -1.0;
nbsol = 2;
}
else {
ncote1 = 2;
ncote2 = 1;
cote1(1) = Abs(Radius-R1);
cote1(2) = Radius+R1;
cote2(1) = 1.0;
nbsol = 1;
}
}
}
else if ((Qualified1.IsUnqualified()) && (Qualified2.IsOutside())) {
// ==================================================================
if ((distance>R1+Radius*2.0+Tol) ||
((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) &&
(distance > R1+Tol))){ WellDone = Standard_True; }
else {
if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0) && (distance > R1)){
cote = -1.0;
nbsol = 2;
}
else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) &&
(distance>R1+2.0*Radius)) {
cote = 1.0;
nbsol = 2;
}
else {
ncote1 = 2;
ncote2 = 1;
cote1(1) = Abs(Radius-R1);
cote1(2) = Radius+R1;
cote2(1) = -1.0;
nbsol = 1;
}
}
}
else if ((Qualified1.IsUnqualified()) && (Qualified2.IsUnqualified())) {
// ======================================================================
if (distance>R1+Radius*2.0+Tol) { WellDone = Standard_True; }
else if (distance>R1+Radius*2.0) {
if (-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0) { cote = -1.0; }
else { cote = 1.0; }
nbsol = 4;
}
else {
ncote1 = 2;
ncote2 = 2;
cote1(1) = Abs(Radius-R1);
cote1(2) = Radius+R1;
cote2(1) = 1.0;
cote2(2) = -1.0;
nbsol = 1;
}
}
if (nbsol == 1) {
for (Standard_Integer jcote1 = 1 ; jcote1 <= ncote1 ; jcote1++) {
for (Standard_Integer jcote2 = 1 ; jcote2 <= ncote2 ; jcote2++) {
if (cote1(jcote1)<Tol) continue;
gp_Circ2d cirint(gp_Ax2d(center1,dirx),cote1(jcote1));
gp_Lin2d linint(gp_Pnt2d(lxloc-cote2(jcote2)*ydir*Radius,
lyloc+cote2(jcote2)*xdir*Radius),L2.Direction());
IntAna2d_AnaIntersection Intp(linint,cirint);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (i = 1 ; i <= Intp.NbPoints() ; i++) {
NbrSol++;
gp_Pnt2d Center(Intp.Point(i).Value());
gp_Ax2d axe(Center,dirx);
cirsol(NbrSol) = gp_Circ2d(axe,Radius);
// ======================================
#ifdef DEB
gp_Dir2d dc1(center1.XY()-Center.XY());
#endif
gp_Dir2d dc2(origin2.XY()-Center.XY());
Standard_Real distcc1 = Center.Distance(center1);
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 (dc2.Dot(normL2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
TheSame1(NbrSol) = 0;
if ((Radius < R1) && Center.Distance(center1) <= R1) {
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*(gp_Dir2d(
Center.XY()-center1.XY()).XY()));
}
else {
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*(gp_Dir2d(
Center.XY()-center1.XY()).XY()));
}
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+
cote2(jcote2)*Radius*gp_XY(ydir,-xdir));
}
}
WellDone = Standard_True;
}
}
}
}
else if (nbsol == 2) {
gp_Pnt2d Cen(center1.XY()+cote*(R1+Radius)*gp_XY(-ydir,xdir));
gp_Ax2d axe(Cen,dirx);
cirsol(1) = gp_Circ2d(axe,Radius);
// =================================
WellDone = Standard_True;
NbrSol = 1;
TheSame1(1) = 0;
qualifier1(1) = Qualified1.Qualifier();;
qualifier2(1) = Qualified2.Qualifier();
pnttg1sol(1)=gp_Pnt2d(Cen.XY()+cote*Radius*gp_XY(ydir,-xdir));
pnttg2sol(1)=gp_Pnt2d(Cen.XY()+Radius*gp_XY(ydir,-xdir));
}
else if (nbsol == 3) {
WellDone = Standard_True;
NbrSol = 1;
gp_Pnt2d Cen(center1.XY()+cote*(R1-Radius)*gp_XY(ydir,-xdir));
gp_Ax2d axe(Cen,dirx);
cirsol(1) = gp_Circ2d(axe,Radius);
// =================================
qualifier1(1) = Qualified1.Qualifier();
qualifier2(1) = Qualified2.Qualifier();
pnttg2sol(1) = gp_Pnt2d(Cen.XY()+cote*Radius*gp_XY(ydir,-xdir));
if (Abs(R1-Radius) > 0.0) {
pnttg1sol(1) = gp_Pnt2d(Cen.XY()+ccote*Radius*gp_XY(ydir,-xdir));
}
else { TheSame1(1) = 1; }
}
else if (nbsol == 4) {
gp_Pnt2d Cent(center1.XY()+cote*(R1+Radius)*gp_XY(-ydir,xdir));
gp_Ax2d axe(Cent,dirx);
cirsol(1) = gp_Circ2d(axe,Radius);
// =================================
qualifier1(1) = Qualified1.Qualifier();
qualifier2(1) = Qualified2.Qualifier();
WellDone = Standard_True;
NbrSol = 1;
TheSame1(1) = 0;
pnttg1sol(1)=gp_Pnt2d(Cent.XY()+cote*Radius*gp_XY(ydir,-xdir));
pnttg2sol(1)=gp_Pnt2d(Cent.XY()+cote*Radius*gp_XY(-ydir,xdir));
}
}
for (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));
pararg2(i)=ElCLib::Parameter(L2,pnttg2sol(i));
}
}

View File

@@ -0,0 +1,235 @@
// File: GccAna_Circ2d2TanRad_2.cxx
// Created: Tue Sep 24 09:12:49 1991
// Author: Remi GILET
// <reg@topsn2>
#include <GccAna_Circ2d2TanRad.jxx>
#include <gp_Circ2d.hxx>
#include <ElCLib.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Lin2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <Standard_NegativeValue.hxx>
#include <GccEnt_BadQualifier.hxx>
// circulaire tangent a un cercle et un point et de rayon donne
//=============================================================
//========================================================================
// On initialise WellDone a false. +
// On recupere le cercle C1. +
// On sort en erreur dans les cas ou la construction est impossible. +
// On fait la parallele a C1 dans le bon sens. +
// On fait le cercle centre en Point1 de rayon Radius. +
// On intersecte la parallele et le cercle. +
// ==> Le point de centre de la solution. +
// On cree la solution qu on ajoute aux solutions deja trouvees. +
// On remplit les champs. +
//========================================================================
GccAna_Circ2d2TanRad::
GccAna_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1 ,
const gp_Pnt2d& Point2 ,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
qualifier1(1,4) ,
qualifier2(1,4),
TheSame1(1,4) ,
TheSame2(1,4) ,
cirsol(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4)
{
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
NbrSol = 0;
WellDone = Standard_False;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Integer i ;
for ( i = 1 ; i <= 4 ; i++) {
TheSame1(i) = 0;
TheSame2(i) = 0;
}
Standard_Real deport = 0.;
Standard_Integer signe = 0;
Standard_Integer nbsol = 0;
gp_Circ2d C1 = Qualified1.Qualified();
TColgp_Array1OfCirc2d C(1,4);
Standard_Real R1 = C1.Radius();
Standard_Real distance = (C1.Location()).Distance(Point2);
Standard_Real dispc1 = C1.Distance(Point2);
gp_Dir2d dir1(Point2.XY()-(C1.Location().XY()));
gp_Pnt2d center1(C1.Location());
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else {
if ( dispc1-Radius*2.0 > Tol) { WellDone = Standard_True; }
else if (Qualified1.IsEnclosed()) {
// =================================
if ((distance-R1>Tol)||(Radius-R1>Tol)) { WellDone = Standard_True; }
else {
if (Abs(distance-R1) < Tol) {
nbsol = -1;
deport = R1-Radius;
signe = 1;
}
else {
C(1) = gp_Circ2d(C1.XAxis(),Abs(Radius-R1));
C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
nbsol = 1;
}
}
}
else if (Qualified1.IsEnclosing()) {
// ==================================
if ((Tol<R1-distance)||(Tol<R1-Radius)) { WellDone = Standard_True; }
else {
if (Abs(distance-R1) < Tol) {
nbsol = -1;
deport = R1-Radius;
signe = 1;
}
else {
C(1) = gp_Circ2d(C1.XAxis(),Abs(Radius-R1));
C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
nbsol = 1;
}
}
}
else if (Qualified1.IsOutside()) {
// ================================
if (Tol < R1-distance) { WellDone = Standard_True; }
else if ((Abs(distance-R1) < Tol) || (Abs(dispc1-Radius*2.0) < Tol)) {
nbsol = -1;
deport = R1+Radius;
signe = -1;
}
else {
C(1) = gp_Circ2d(C1.XAxis(),Radius+R1);
C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
nbsol = 1;
}
}
else if (Qualified1.IsUnqualified()) {
// ====================================
if (Abs(dispc1-Radius*2.0) < Tol) {
WellDone = Standard_True;
gp_Pnt2d Center(center1.XY()+(distance-Radius)*dir1.XY());
cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// ==================================================
if (Abs(Center.Distance(center1)-R1) < Tol) {
qualifier1(1) = GccEnt_enclosed;
}
else { qualifier1(1) = GccEnt_outside; }
qualifier2(1) = GccEnt_noqualifier;
pnttg1sol(1) = gp_Pnt2d(Center.XY()-Radius*dir1.XY());
pnttg2sol(1) = Point2;
WellDone = Standard_True;
NbrSol = 1;
}
else if ((Abs(R1-Radius)<Tol) && (Abs(distance-R1)<Tol)){
cirsol(1) = gp_Circ2d(C1);
// =========================
qualifier1(1) = GccEnt_unqualified;
qualifier2(1) = GccEnt_noqualifier;
TheSame1(1) = 1;
pnttg2sol(1) = Point2;
WellDone = Standard_True;
NbrSol = 1;
C(1) = gp_Circ2d(C1.XAxis(),Radius+R1);
C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
nbsol = 1;
}
else {
C(1) = gp_Circ2d(C1.XAxis(),Abs(Radius-R1));
C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
C(3) = gp_Circ2d(C1.XAxis(),Radius+R1);
C(4) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
nbsol = 2;
}
}
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 (i = 1 ; i <= Intp.NbPoints() ; i++) {
NbrSol++;
gp_Pnt2d Center(Intp.Point(i).Value());
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
Standard_Real distcc1 = center1.Distance(Center);
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; }
qualifier2(NbrSol) = GccEnt_noqualifier;
dir1 = gp_Dir2d(Center.XY()-center1.XY());
#ifdef DEB
gp_Dir2d dir2(Center.XY()-Point2.XY());
#endif
if ((Center.Distance(center1) > C1.Radius()) &&
(Radius < Center.Distance(center1)+C1.Radius())) {
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1.XY());
}
else if ((Center.Distance(center1) < C1.Radius()) &&
(Radius < C1.Radius())) {
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dir1.XY());
}
else {
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1.XY());
}
pnttg2sol(NbrSol) = Point2;
}
}
WellDone = Standard_True;
}
}
}
else if (nbsol < 0) {
gp_Pnt2d Center(center1.XY()+deport*dir1.XY());
cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// ==================================================
qualifier1(1) = Qualified1.Qualifier();
qualifier2(1) = GccEnt_noqualifier;
if (Abs(deport) <= Tol && Abs(Radius-R1) <= Tol) {
TheSame1(1) = 1;
}
else {
pnttg1sol(1) = gp_Pnt2d(Center.XY()+signe*Radius*dir1.XY());
}
pnttg2sol(1) = Point2;
WellDone = Standard_True;
NbrSol = 1;
}
}
for (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));
pararg2(i) = 0.;
}
}

View File

@@ -0,0 +1,228 @@
// File: GccAna_Circ2d2TanRad_3.cxx
// Created: Tue Sep 24 09:14:08 1991
// Author: Remi GILET
// <reg@topsn2>
// Modified: Thu Jun 18 15:45:00 1998
// Author: Joelle CHAUVET
// PRO10310 : cas ou le point est sur la droite
#include <GccAna_Circ2d2TanRad.jxx>
#include <ElCLib.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Standard_NegativeValue.hxx>
#include <GccEnt_BadQualifier.hxx>
// circulaire tangent a une ligne et un point et de rayon donne
//=============================================================
//========================================================================
// On initialise WellDone a false. +
// On recupere la ligne L1. +
// On sort en erreur dans les cas ou la construction est impossible. +
// On fait la parallele a L1 dans le bon sens. +
// On fait le cercle centre en Point1 de rayon Radius. +
// On intersecte la parallele et le cercle. +
// ==> Le point de centre de la solution. +
// On cree la solution qu on ajoute aux solutions deja trouvees. +
// On remplit les champs. +
//========================================================================
GccAna_Circ2d2TanRad::
GccAna_Circ2d2TanRad (const GccEnt_QualifiedLin& Qualified1 ,
const gp_Pnt2d& Point2 ,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
qualifier1(1,2) ,
qualifier2(1,2),
TheSame1(1,2) ,
TheSame2(1,2) ,
cirsol(1,2) ,
pnttg1sol(1,2) ,
pnttg2sol(1,2) ,
par1sol(1,2) ,
par2sol(1,2) ,
pararg1(1,2) ,
pararg2(1,2)
{
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
NbrSol = 0;
WellDone = Standard_False;
if (!(Qualified1.IsEnclosed() || Qualified1.IsOutside() ||
Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Integer nbsol = 0;
Standard_Integer nbcote=0;
TColStd_Array1OfReal cote(1,2);
gp_Lin2d L1 = Qualified1.Qualified();
Standard_Real displ1 = L1.Distance(Point2);
Standard_Real xdir = (L1.Direction()).X();
Standard_Real ydir = (L1.Direction()).Y();
Standard_Real lxloc = (L1.Location()).X();
Standard_Real lyloc = (L1.Location()).Y();
gp_Pnt2d origin1(lxloc,lyloc);
gp_Dir2d normL1(-ydir,xdir);
Standard_Real cxloc = Point2.X();
Standard_Real cyloc = Point2.Y();
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else {
if ( displ1-Radius*2.0 > Tol) { WellDone = Standard_True; }
else if (Qualified1.IsEnclosed()) {
// =================================
if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0)) {
WellDone = Standard_True;
}
else {
if ( displ1-Radius*2.0 > 0.0) {
nbsol = 2;
NbrSol = 1;
nbcote = 1;
cote(1) = 1.0;
}
else {
nbsol = 1;
nbcote = 1;
cote(1) = 1.0;
}
}
}
else if (Qualified1.IsOutside()) {
// ================================
if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0)) {
WellDone = Standard_True;
}
else {
if ( displ1-Radius*2.0 > 0.0) {
nbsol = 2;
nbcote = 1;
cote(1) = -1.0;
}
else {
nbsol = 1;
nbcote = 1;
cote(1) = -1.0;
}
}
}
else if (Qualified1.IsUnqualified()) {
// ====================================
if ( displ1-Radius*2.0 > 0.0) {
if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)>0.0)) {
nbsol = 2;
nbcote = 1;
cote(1) = 1.0;
}
else if ((-ydir*(cxloc-lxloc)+xdir*(cyloc-lyloc)<0.0)) {
nbsol = 2;
nbcote = 1;
cote(1) = -1.0;
}
}
else {
nbsol = 1;
nbcote = 2;
cote(1) = 1.0;
cote(2) = -1.0;
}
}
if (nbsol == 1) {
if (displ1<1.e-10) {
// cas particulier ou Point2 est sur la ligne
// pas la peine de passer par les intersections
// on construit les deux solutions directement
for (Standard_Integer jcote = 1 ; jcote <= nbcote ; jcote++) {
NbrSol++;
gp_Pnt2d Center(cxloc-cote(jcote)*ydir*Radius,
cyloc+cote(jcote)*xdir*Radius);
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
qualifier2(NbrSol) = GccEnt_noqualifier;
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (cote(jcote) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else {
qualifier1(NbrSol) = GccEnt_enclosed;
}
TheSame1(NbrSol) = 0;
TheSame2(NbrSol) = 0;
pnttg1sol(NbrSol) = Point2;
pnttg2sol(NbrSol) = Point2;
}
WellDone = Standard_True;
}
else {
gp_Circ2d cirint(gp_Ax2d(Point2,dirx),Radius);
for (Standard_Integer jcote = 1 ; jcote <= nbcote ; jcote++) {
gp_Lin2d linint(gp_Pnt2d(lxloc-cote(jcote)*ydir*Radius,
lyloc+cote(jcote)*xdir*Radius),
L1.Direction());
IntAna2d_AnaIntersection Intp(linint,cirint);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol<2; i++) {
NbrSol++;
gp_Pnt2d Center(Intp.Point(i).Value());
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
gp_Dir2d dc1(origin1.XY()-Center.XY());
qualifier2(NbrSol) = GccEnt_noqualifier;
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc1.Dot(normL1) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
TheSame1(NbrSol) = 0;
TheSame2(NbrSol) = 0;
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+
cote(jcote)*Radius*gp_XY(ydir,-xdir));
pnttg2sol(NbrSol) = Point2;
}
}
WellDone = Standard_True;
}
}
}
}
else if (nbsol == 2) {
gp_Pnt2d Center(Point2.XY()+cote(1)*Radius*gp_XY(-ydir,xdir));
WellDone = Standard_True;
NbrSol = 1;
cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// ==================================================
qualifier2(1) = GccEnt_noqualifier;
TheSame1(1) = 0;
TheSame2(1) = 0;
pnttg1sol(1)=gp_Pnt2d(Center.XY()+cote(1)*Radius*gp_XY(ydir,-xdir));
pnttg2sol(1) = Point2;
}
}
for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
pararg1(i)=ElCLib::Parameter(L1,pnttg1sol(i));
par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
pararg2(i)=0.;
}
}

View File

@@ -0,0 +1,216 @@
// File: GccAna_Circ2d2TanRad_4.cxx
// Created: Tue Sep 24 09:15:20 1991
// Author: Remi GILET
// <reg@topsn2>
#include <GccAna_Circ2d2TanRad.jxx>
#include <ElCLib.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Standard_NegativeValue.hxx>
#include <gp.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <Precision.hxx>
// circulaire tangent a deux ligne de rayon donne
//===============================================
//========================================================================
// On initialise WellDone a false. +
// On recupere les deux lignes L1 et L2. +
// On sort en erreur dans les cas ou la construction est impossible. +
// On fait les paralleles a L1 et L2 dans le bon sens. +
// On intersecte les paralleles ==> Le point de centre de la solution. +
// On cree la solution qu on ajoute aux solutions deja trouvees. +
// On remplit les champs. +
//========================================================================
GccAna_Circ2d2TanRad::
GccAna_Circ2d2TanRad (const GccEnt_QualifiedLin& Qualified1 ,
const GccEnt_QualifiedLin& Qualified2 ,
const Standard_Real Radius ,
const Standard_Real
#ifdef DEB
Tolerance
#endif
):
qualifier1(1,4) ,
qualifier2(1,4),
TheSame1(1,4) ,
TheSame2(1,4) ,
cirsol(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4)
{
gp_Dir2d dirx(1.0,0.0);
#ifdef DEB
Standard_Real Tol = Abs(Tolerance);
#endif
TColStd_Array1OfReal cote1(1,2);
TColStd_Array1OfReal cote2(1,2);
Standard_Integer nbrcote1=0;
Standard_Integer nbrcote2=0;
NbrSol = 0;
WellDone = Standard_False;
if (!(Qualified1.IsEnclosed() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
gp_Lin2d L1 = Qualified1.Qualified();
gp_Lin2d L2 = Qualified2.Qualified();
Standard_Real x1dir = (L1.Direction()).X();
Standard_Real y1dir = (L1.Direction()).Y();
Standard_Real lx1loc = (L1.Location()).X();
Standard_Real ly1loc = (L1.Location()).Y();
Standard_Real x2dir = (L2.Direction()).X();
Standard_Real y2dir = (L2.Direction()).Y();
Standard_Real lx2loc = (L2.Location()).X();
Standard_Real ly2loc = (L2.Location()).Y();
gp_Pnt2d origin1(lx1loc,ly1loc);
gp_Pnt2d origin2(lx2loc,ly2loc);
gp_Dir2d normL1(x1dir,y1dir);
gp_Dir2d normL2(x2dir,y2dir);
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else {
if (L1.Direction().IsParallel(L2.Direction(),Precision::Angular())) {
WellDone = Standard_True;
}
else {
if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
// =======================================================
nbrcote1 = 1;
nbrcote2 = 1;
cote1(1) = 1.0;
cote2(1) = 1.0;
}
else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
// ==========================================================
nbrcote1 = 1;
nbrcote2 = 1;
cote1(1) = 1.0;
cote2(1) = -1.0;
}
else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
// ===========================================================
nbrcote1 = 1;
nbrcote2 = 1;
cote1(1) = -1.0;
cote2(1) = 1.0;
}
else if(Qualified1.IsOutside() && Qualified2.IsOutside()) {
// =========================================================
nbrcote1 = 1;
nbrcote2 = 1;
cote1(1) = -1.0;
cote2(1) = -1.0;
}
if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
// =========================================================
nbrcote1 = 1;
nbrcote2 = 2;
cote1(1) = 1.0;
cote2(1) = 1.0;
cote2(2) = -1.0;
}
if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
// =========================================================
nbrcote1 = 2;
nbrcote2 = 1;
cote1(1) = 1.0;
cote1(2) = -1.0;
cote2(1) = 1.0;
}
else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
// =============================================================
nbrcote1 = 1;
nbrcote2 = 2;
cote1(1) = -1.0;
cote2(1) = 1.0;
cote2(2) = -1.0;
}
if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
// ========================================================
nbrcote1 = 2;
nbrcote2 = 1;
cote1(1) = 1.0;
cote1(2) = -1.0;
cote2(1) = -1.0;
}
else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
// =================================================================
nbrcote1 = 2;
nbrcote2 = 2;
cote1(1) = 1.0;
cote1(2) = -1.0;
cote2(1) = 1.0;
cote2(2) = -1.0;
}
for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) {
gp_Lin2d linint1(gp_Pnt2d(lx1loc-cote1(jcote1)*y1dir*Radius,
ly1loc+cote1(jcote1)*x1dir*Radius),
L1.Direction());
gp_Lin2d linint2(gp_Pnt2d(lx2loc-cote2(jcote2)*y2dir*Radius,
ly2loc+cote2(jcote2)*x2dir*Radius),
L2.Direction());
IntAna2d_AnaIntersection Intp(linint1,linint2);
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);
// =======================================================
gp_Dir2d dc1(origin1.XY()-Center.XY());
gp_Dir2d dc2(origin2.XY()-Center.XY());
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc1.Dot(normL1) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (dc2.Dot(normL2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
TheSame1(NbrSol) = 0;
TheSame2(NbrSol) = 0;
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+
cote1(jcote1)*Radius*gp_XY(y1dir,-x1dir));
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+
cote2(jcote2)*Radius*gp_XY(y2dir,-x2dir));
}
}
WellDone = Standard_True;
}
}
}
}
}
for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
pararg1(i)=ElCLib::Parameter(L1,pnttg1sol(i));
par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
pararg2(i)=ElCLib::Parameter(L2,pnttg2sol(i));
}
}

View File

@@ -0,0 +1,95 @@
// File: GccAna_Circ2d2TanRad_5.cxx
// Created: Tue Sep 24 09:17:30 1991
// Author: Remi GILET
// <reg@topsn2>
#include <GccAna_Circ2d2TanRad.jxx>
#include <ElCLib.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Ax2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <Standard_NegativeValue.hxx>
#include <GccEnt_BadQualifier.hxx>
// Cercle passant par deux points de rayon donne.
// ==============================================
//=========================================================================
// Resolution de l equation du second degre indiquant que le centre du +
// cercle est equidistant des deux points. +
//=========================================================================
GccAna_Circ2d2TanRad::
GccAna_Circ2d2TanRad (const gp_Pnt2d& Point1 ,
const gp_Pnt2d& Point2 ,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
qualifier1(1,2) ,
qualifier2(1,2),
TheSame1(1,2) ,
TheSame2(1,2) ,
cirsol(1,2) ,
pnttg1sol(1,2) ,
pnttg2sol(1,2) ,
par1sol(1,2) ,
par2sol(1,2) ,
pararg1(1,2) ,
pararg2(1,2)
{
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
NbrSol = 0;
WellDone = Standard_False;
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else {
if (Point1.Distance(Point2)-Radius*2.0 > Tol) { WellDone = Standard_True; }
else {
if (Point1.Distance(Point2)-Radius*2.0 >0.0) {
WellDone = Standard_True;
NbrSol = 1;
gp_Ax2d axe(gp_Pnt2d(0.5*(Point1.XY()+Point2.XY())),dirx);
cirsol(1) = gp_Circ2d(axe,Radius);
// =================================
qualifier1(1) = GccEnt_noqualifier;
qualifier2(1) = GccEnt_noqualifier;
TheSame1(1) = 0;
TheSame2(1) = 0;
pnttg1sol(1) = Point1;
pnttg2sol(1) = Point2;
}
else {
gp_Circ2d C1(gp_Ax2d(Point1,dirx),Radius);
gp_Circ2d C2(gp_Ax2d(Point2,dirx),Radius);
IntAna2d_AnaIntersection Intp(C1,C2);
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);
// =======================================================
qualifier1(NbrSol) = GccEnt_noqualifier;
qualifier2(NbrSol) = GccEnt_noqualifier;
TheSame1(NbrSol) = 0;
TheSame2(NbrSol) = 0;
pnttg1sol(NbrSol) = Point1;
pnttg2sol(NbrSol) = Point2;
}
}
WellDone = Standard_True;
}
}
}
}
for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
pararg1(i) = 0.;
pararg2(i) = 0.;
par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
par2sol(i)=ElCLib::Parameter(cirsol(i),pnttg2sol(i));
}
}

359
src/GccAna/GccAna_Circ2d3Tan.cdl Executable file
View File

@@ -0,0 +1,359 @@
-- File: Circ2d3Tan.cdl
-- Created: Mon Mar 18 16:35:25 1991
-- Author: Remy GILET
-- <Reg@topsn3>
---Copyright: Matra Datavision 1991
class Circ2d3Tan
from GccAna
---Purpose: This class implements the algorithms used to
-- create 2d circles tangent to 3 points/lines/circles.
-- The arguments of all construction methods are :
-- - The three qualified elements for the
-- tangency constraints (QualifiedCirc, QualifiedLine,
-- Points).
-- - A real Tolerance.
-- Tolerance is only used in the limit cases.
-- For example :
-- We want to create a circle tangent to an UnqualifiedCirc
-- C1 and an UnqualifiedCirc C2 and an UnqualifiedCirc C3
-- with a tolerance Tolerance.
-- If we do not use Tolerance it is impossible to find
-- a solution in the following case : C2 is inside C1
-- and there is no intersection point between the two
-- circles, and C3 is completly outside C1.
-- With Tolerance we will find a solution if the
-- lowest distance between C1 and C2 is lower than or
-- equal Tolerance.
uses Pnt2d from gp,
Circ2d from gp,
QualifiedCirc from GccEnt,
QualifiedLin from GccEnt,
Array1OfReal from TColStd,
Array1OfInteger from TColStd,
Array1OfCirc2d from TColgp,
Array1OfPnt2d from TColgp,
Position from GccEnt,
Array1OfPosition from GccEnt
raises OutOfRange from Standard,
NotDone from StdFail,
BadQualifier from GccEnt
is
Create(Qualified1 : QualifiedCirc from GccEnt ;
Qualified2 : QualifiedCirc from GccEnt ;
Qualified3 : QualifiedCirc from GccEnt ;
Tolerance : Real from Standard) returns Circ2d3Tan
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to 3 circles.
-- ConstructionError is raised if there is a problem during
-- the computation.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedCirc from GccEnt ;
Qualified2 : QualifiedCirc from GccEnt ;
Qualified3 : QualifiedLin from GccEnt ;
Tolerance : Real from Standard) returns Circ2d3Tan
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to 2 circles and 1 line.
-- ConstructionError is raised if there is a problem during
-- the computation.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedCirc from GccEnt ;
Qualified2 : QualifiedLin from GccEnt ;
Qualified3 : QualifiedLin from GccEnt ;
Tolerance : Real from Standard) returns Circ2d3Tan
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to 1 circle and 2 lines.
-- ConstructionError is raised if there is a problem during
-- the computation.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedLin from GccEnt ;
Qualified2 : QualifiedLin from GccEnt ;
Qualified3 : QualifiedLin from GccEnt ;
Tolerance : Real from Standard) returns Circ2d3Tan
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to 3 lines.
-- ConstructionError is raised if there is a problem during
-- the computation.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedCirc from GccEnt ;
Qualified2 : QualifiedCirc from GccEnt ;
Point3 : Pnt2d from gp ;
Tolerance : Real from Standard) returns Circ2d3Tan
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to 2 circles and 1 Point.
-- ConstructionError is raised if there is a problem during
-- the computation.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedCirc from GccEnt ;
Qualified2 : QualifiedLin from GccEnt ;
Point3 : Pnt2d from gp ;
Tolerance : Real from Standard) returns Circ2d3Tan
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to a circle and a line and
-- 1 Point.
-- ConstructionError is raised if there is a problem during
-- the computation.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedLin from GccEnt ;
Qualified2 : QualifiedLin from GccEnt ;
Point3 : Pnt2d from gp ;
Tolerance : Real from Standard) returns Circ2d3Tan
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to 2 lines and 1 Point.
-- ConstructionError is raised if there is a problem during
-- the computation.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedCirc from GccEnt ;
Point2 : Pnt2d from gp ;
Point3 : Pnt2d from gp ;
Tolerance : Real from Standard) returns Circ2d3Tan
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to a circle and passing
-- thrue 2 Points.
-- ConstructionError is raised if there is a problem during
-- the computation.
raises BadQualifier from GccEnt;
Create(Qualified1 : QualifiedLin from GccEnt ;
Point2 : Pnt2d from gp ;
Point3 : Pnt2d from gp ;
Tolerance : Real from Standard) returns Circ2d3Tan
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to a line and passing
-- thrue 2 Points.
-- ConstructionError is raised if there is a problem during
-- the computation.
raises BadQualifier from GccEnt;
Create(Point1 : Pnt2d from gp ;
Point2 : Pnt2d from gp ;
Point3 : Pnt2d from gp ;
Tolerance : Real from Standard) returns Circ2d3Tan;
---Purpose: This method implements the algorithms used to
-- create 2d circles passing thrue 3 Points.
-- ConstructionError is raised if there is a problem during
-- the computation.
-- -- ....................................................................
IsDone(me) returns Boolean from Standard
is static;
---Purpose: This method returns True if the construction
-- algorithm succeeded.
-- Note: IsDone protects against a failure arising from a
-- more internal intersection algorithm, which has
-- reached its numeric limits.
NbSolutions(me) returns Integer from Standard
---Purpose: This method returns the number of solutions.
-- Raises NotDone if the construction algorithm didn't succeed.
raises NotDone
is static;
ThisSolution(me ; Index : Integer from Standard) returns Circ2d from gp
---Purpose: Returns the solution number Index and raises OutOfRange
-- exception if Index is greater than the number of
-- solutions.
-- Be careful: the Index is only a way to get all the
-- solutions, but is not associated to those outside the
-- context of the algorithm-object.
-- Raises OutOfRange if Index is greater than
-- the number of solutions.
-- It raises NotDone if the algorithm failed.
raises OutOfRange, NotDone
is static;
WhichQualifier(me ;
Index : Integer from Standard;
Qualif1 : out Position from GccEnt ;
Qualif2 : out Position from GccEnt ;
Qualif3 : out Position from GccEnt )
raises OutOfRange, NotDone
is static;
---Purpose: Returns the informations about the qualifiers of the
-- tangency
-- arguments concerning the solution number Index.
-- It returns the real qualifiers (the qualifiers given to the
-- constructor method in case of enclosed, enclosing and outside
-- and the qualifiers computedin case of unqualified).
Tangency1(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns informations about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point PntSol
-- on the solution curv.
-- ParArg is the intrinsic parameter of the point PntArg
-- on the argument curv. Raises OutOfRange if Index is greater than
-- the number of solutions.
-- It raises NotDone if the algorithm failed.
raises OutOfRange, NotDone
is static;
Tangency2(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns informations about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point PntSol
-- on the solution curv.
-- ParArg is the intrinsic parameter of the point Pntsol
-- on the argument curv. Raises OutOfRange if Index is greater than
-- the number of solutions.
-- It raises NotDone if the algorithm failed.
raises OutOfRange, NotDone
is static;
Tangency3(me ;
Index : Integer from Standard;
ParSol : out Real from Standard;
ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns informations about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point PntSol
-- on the solution curv.
-- ParArg is the intrinsic parameter of the point Pntsol
-- on the argument curv. Raises OutOfRange if Index is greater than
-- the number of solutions.
-- It raises NotDone if the algorithm failed.
raises OutOfRange, NotDone
is static;
IsTheSame1(me ;
Index : Integer from Standard) returns Boolean from Standard
---Purpose: Returns True if the solution number Index is equal to
-- the first argument. Raises OutOfRange if Index is greater than
-- the number of solutions.
-- It raises NotDone if the algorithm failed.
raises OutOfRange, NotDone
is static;
IsTheSame2(me ;
Index : Integer from Standard) returns Boolean from Standard
---Purpose: Returns True if the solution number Index is equal to
-- the second argument. Raises OutOfRange Index is greater than
-- the number of solutions.
-- It raises NotDone if the algorithm failed.
raises OutOfRange, NotDone
is static;
IsTheSame3(me ;
Index : Integer from Standard) returns Boolean from Standard
---Purpose: Returns True if the solution number Index is equal to
-- the third argument. Raises OutOfRange if Index is greater than
-- the number of solutions.
-- It raises NotDone if the algorithm failed.
raises OutOfRange, NotDone
is static;
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose: The number of solutions found.
cirsol : Array1OfCirc2d from TColgp;
-- The solutions.
qualifier1 : Array1OfPosition from GccEnt;
---Purpose: The qualifiers of the first argument.
qualifier2 : Array1OfPosition from GccEnt ;
---Purpose: The qualifiers of the second argument.
qualifier3 : Array1OfPosition from GccEnt;
---Purpose: The qualifiers of the third argument.
TheSame1 : Array1OfInteger from TColStd;
---Purpose: 1 if the solution and the first argument are the same
-- (2 circles).
-- If R1 is the radius of the first argument and Rsol the radius
-- of the solution and dist the distance between the two centers,
-- we consider the two circles are identical if R1+dist-Rsol is
-- less than Tolerance.
-- 0 in the other cases.
TheSame2 : Array1OfInteger from TColStd;
---Purpose: 1 if the solution and the second argument are the same
-- (2 circles).
-- If R2 is the radius of the second argument and Rsol the radius
-- of the solution and dist the distance between the two centers,
-- we consider the two circles are identical if R2+dist-Rsol is
-- less than Tolerance.
-- 0 in the other cases.
TheSame3 : Array1OfInteger from TColStd;
---Purpose: 1 if the solution and the third argument are the same
-- (2 circles).
-- If R3 is the radius of the third argument and Rsol the radius
-- of the solution and dist the distance between the two centers,
-- we consider the two circles are identical if R3+dist-Rsol is
-- less than Tolerance.
-- 0 in the other cases.
pnttg1sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the first
-- argument.
pnttg2sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the second
-- argument.
pnttg3sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the third
-- argument.
par1sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the solution.
par2sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the second argument on the solution.
par3sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the third argument on the solution.
pararg1 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the first argument.
pararg2 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the second argument on the second argument.
pararg3 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the third argument on the second argument.
end Circ2d3Tan;

927
src/GccAna/GccAna_Circ2d3Tan.cxx Executable file
View File

@@ -0,0 +1,927 @@
// File GccAna_Circ2d3Tan.cxx, REG 08/07/91
#include <GccAna_Circ2d3Tan.ixx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <IntAna2d_Conic.hxx>
#include <StdFail_NotDone.hxx>
#include <ElCLib.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <GccAna_Circ2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BCirc.hxx>
#include <GccInt_BLine.hxx>
#include <GccInt_BElips.hxx>
#include <GccInt_BHyper.hxx>
#include <Standard_OutOfRange.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <math_DirectPolynomialRoots.hxx>
//=========================================================================
// Creation d un cercle tangent a trois cercles. +
//=========================================================================
GccAna_Circ2d3Tan::
GccAna_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1,
const GccEnt_QualifiedCirc& Qualified2,
const GccEnt_QualifiedCirc& Qualified3,
const Standard_Real Tolerance ):
//=========================================================================
// Initialisation des champs. +
//=========================================================================
cirsol(1,16) ,
qualifier1(1,16),
qualifier2(1,16),
qualifier3(1,16),
TheSame1(1,16) ,
TheSame2(1,16) ,
TheSame3(1,16) ,
pnttg1sol(1,16),
pnttg2sol(1,16),
pnttg3sol(1,16),
par1sol(1,16) ,
par2sol(1,16) ,
par3sol(1,16) ,
pararg1(1,16) ,
pararg2(1,16) ,
pararg3(1,16)
{
gp_Dir2d dirx(1.0,0.0);
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()) ||
!(Qualified3.IsEnclosed() || Qualified3.IsEnclosing() ||
Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
//=========================================================================
// Traitement. +
//=========================================================================
gp_Circ2d Cir1 = Qualified1.Qualified();
gp_Circ2d Cir2 = Qualified2.Qualified();
gp_Circ2d Cir3 = Qualified3.Qualified();
Standard_Real R1 = Cir1.Radius();
Standard_Real R2 = Cir2.Radius();
Standard_Real R3 = Cir3.Radius();
gp_Pnt2d center1(Cir1.Location());
gp_Pnt2d center2(Cir2.Location());
gp_Pnt2d center3(Cir3.Location());
Standard_Real X1 = center1.X();
Standard_Real X2 = center2.X();
Standard_Real X3 = center3.X();
Standard_Real Y1 = center1.Y();
Standard_Real Y2 = center2.Y();
Standard_Real Y3 = center3.Y();
gp_XY dir2 = center1.XY() - center2.XY();
gp_XY dir3 = center1.XY() - center3.XY();
//////////
if ((Abs(R1 - R2) <= Tolerance && center1.IsEqual(center2, Tolerance)) ||
(Abs(R1 - R3) <= Tolerance && center1.IsEqual(center3, Tolerance)) ||
(Abs(R2 - R3) <= Tolerance && center2.IsEqual(center3, Tolerance)))
return;
else {
if (Abs(dir2^dir3) <= Tolerance) {
Standard_Real Dist1 = center1.Distance(center2);
Standard_Real Dist2 = center1.Distance(center3);
Standard_Real Dist3 = center2.Distance(center3);
if (Abs(Abs(R1 - R2) - Dist1) <= Tolerance) {
if (Abs(Abs(R1 - R3) - Dist2) <= Tolerance) {
if (Abs(Abs(R2 - R3) - Dist3) <= Tolerance)
return;
} else if (Abs(R1 + R3 - Dist2) <= Tolerance) {
if (Abs(R2 + R3 - Dist3) <= Tolerance)
return;
}
} else if (Abs(R1 + R2 - Dist1) <= Tolerance) {
if (Abs(Abs(R1 - R3) - Dist2) <= Tolerance &&
Abs(R2 + R3 - Dist3) <= Tolerance) {
} else {
if (Abs(Abs(R2 - R3) - Dist3) <= Tolerance &&
Abs(R1 + R3 - Dist2) <= Tolerance)
return;
}
}
}
}
/////////
TColStd_Array1OfReal A2(1, 8), B2(1, 8), C2(1, 8), D2(1, 8), E2(1, 8), F2(1, 8);
TColStd_Array1OfReal A3(1, 8), B3(1, 8), C3(1, 8), D3(1, 8), E3(1, 8), F3(1, 8);
TColStd_Array1OfReal Beta2(1, 8), Gamma2(1, 8), Delta2(1, 8);
TColStd_Array1OfReal Beta3(1, 8), Gamma3(1, 8), Delta3(1, 8);
Standard_Real a2, b2, c2, d2, e2, f2;
Standard_Real a3, b3, c3, d3, e3, f3;
Standard_Real A, B, C, D, E;
Standard_Boolean IsSame;
Standard_Boolean IsTouch;
Standard_Integer FirstIndex;
Standard_Integer i, j, k, l;
TColStd_Array1OfReal xSol(1, 64);
TColStd_Array1OfReal ySol(1, 64);
TColStd_Array1OfReal rSol(1, 16);
TColStd_Array1OfInteger FirstSol(1, 9);
TColStd_Array1OfReal xSol1(1, 32);
TColStd_Array1OfReal ySol1(1, 32);
TColStd_Array1OfReal rSol1(1, 32);
TColStd_Array1OfInteger FirstSol1(1, 9);
Standard_Real x, y, r;
Standard_Real m, n, t, s, v;
Standard_Real p, q;
Standard_Real Epsilon;
Standard_Integer CurSol;
//*********************************************************************************************
//*********************************************************************************************
// Actually we have to find solutions of eight systems of equations:
// _ _
// | (X - X1)2 + (Y - Y1)2 = (R - R1)2 | (X - X1)2 + (Y - Y1)2 = (R + R1)2
// 1) < (X - X2)2 + (Y - Y2)2 = (R - R2)2 2) < (X - X2)2 + (Y - Y2)2 = (R - R2)2
// \_(X - X3)2 + (Y - Y3)2 = (R - R3)2 \_(X - X3)2 + (Y - Y3)2 = (R - R3)2
// _ _
// | (X - X1)2 + (Y - Y1)2 = (R - R1)2 | (X - X1)2 + (Y - Y1)2 = (R - R1)2
// 3) < (X - X2)2 + (Y - Y2)2 = (R + R2)2 4) < (X - X2)2 + (Y - Y2)2 = (R - R2)2
// \_(X - X3)2 + (Y - Y3)2 = (R - R3)2 \_(X - X3)2 + (Y - Y3)2 = (R + R3)2
// _ _
// | (X - X1)2 + (Y - Y1)2 = (R + R1)2 | (X - X1)2 + (Y - Y1)2 = (R + R1)2
// 5) < (X - X2)2 + (Y - Y2)2 = (R + R2)2 6) < (X - X2)2 + (Y - Y2)2 = (R - R2)2
// \_(X - X3)2 + (Y - Y3)2 = (R - R3)2 \_(X - X3)2 + (Y - Y3)2 = (R + R3)2
// _ _
// | (X - X1)2 + (Y - Y1)2 = (R - R1)2 | (X - X1)2 + (Y - Y1)2 = (R + R1)2
// 7) < (X - X2)2 + (Y - Y2)2 = (R + R2)2 8) < (X - X2)2 + (Y - Y2)2 = (R + R2)2
// \_(X - X3)2 + (Y - Y3)2 = (R + R3)2 \_(X - X3)2 + (Y - Y3)2 = (R + R3)2
// each equation (X - Xi)2 + (Y - Yi)2 = (R +- Ri)2 means that the circle (X,Y,R) is tangent
// to the circle (Xi,Yi,Ri).
// The number of each system is very important. Further index i shows the numer of the system
// Further Beta, Gamma and Delta are coefficients of the equation:
// R +- Ri = Beta*X + Gamma*Y + Delta where i=2 or i=3
//*********************************************************************************************
//*********************************************************************************************
// Verification do two circles touch each other or not
// if at least one circle touches other one IsTouch become Standard_Standard_True
if (Abs((X1 - X2)*(X1 - X2) + (Y1 - Y2)*(Y1 - Y2) - (R1 - R2)*(R1 - R2)) <= Tolerance ||
Abs((X1 - X2)*(X1 - X2) + (Y1 - Y2)*(Y1 - Y2) - (R1 + R2)*(R1 + R2)) <= Tolerance ||
Abs((X1 - X3)*(X1 - X3) + (Y1 - Y3)*(Y1 - Y3) - (R1 - R3)*(R1 - R3)) <= Tolerance ||
Abs((X1 - X3)*(X1 - X3) + (Y1 - Y3)*(Y1 - Y3) - (R1 + R3)*(R1 + R3)) <= Tolerance ||
Abs((X2 - X3)*(X2 - X3) + (Y2 - Y3)*(Y2 - Y3) - (R2 - R3)*(R2 - R3)) <= Tolerance ||
Abs((X2 - X3)*(X2 - X3) + (Y2 - Y3)*(Y2 - Y3) - (R2 + R3)*(R2 + R3)) <= Tolerance)
IsTouch = Standard_True;
else
IsTouch = Standard_False;
// First step:
// We are searching for Beta, Gamma and Delta coefficients
// and also coefficients of the system of second order equations:
// _
// | a2*x*x +2*b2*x*y + c2*y*y +2*d2*x + 2*e2*y + f2 = 0
// <
// \_ a3*x*x +2*b3*x*y + c3*y*y +2*d3*x + 2*e3*y + f3 = 0 ,
// obtained by exclusion of R from source systems.
for (i = 1; i <= 8; i++) {
// _
// | (X - X1)2 + (Y - Y1)2 = (R +- R1)2
// <
// \_(X - X2)2 + (Y - Y2)2 = (R +- R2)2
if (i == 1 || i == 4 || i == 5 || i == 8) {
if (Abs(R1 - R2) > Tolerance) {
Beta2(i) = (X1 - X2)/(R1 - R2);
Gamma2(i) = (Y1 - Y2)/(R1 - R2);
Delta2(i) = (X2*X2 - X1*X1 + Y2*Y2 - Y1*Y1 + (R1 - R2)*(R1 - R2))/(2*(R1 - R2));
}
} else {
Beta2(i) = (X1 - X2)/(R1 + R2);
Gamma2(i) = (Y1 - Y2)/(R1 + R2);
Delta2(i) = (X2*X2 - X1*X1 + Y2*Y2 - Y1*Y1 + (R1 + R2)*(R1 + R2))/(2*(R1 + R2));
}
if ((i == 1 || i == 4 || i == 5 || i == 8) &&
(Abs(R1 - R2) <= Tolerance)) {
// If R1 = R2
A2(i) = 0.;
B2(i) = 0.;
C2(i) = 0.;
D2(i) = X2 - X1;
E2(i) = Y2 - Y1;
F2(i) = X1*X1 - X2*X2 + Y1*Y1 - Y2*Y2;
} else {
A2(i) = Beta2(i)*Beta2(i) - 1.;
B2(i) = Beta2(i)*Gamma2(i);
C2(i) = Gamma2(i)*Gamma2(i) - 1.;
D2(i) = Beta2(i)*Delta2(i) + X2;
E2(i) = Gamma2(i)*Delta2(i) + Y2;
F2(i) = Delta2(i)*Delta2(i) - X2*X2 - Y2*Y2;
}
// _
// | (X - X1)2 + (Y - Y1)2 = (R +- R1)2
// <
// \_(X - X3)2 + (Y - Y3)2 = (R +- R3)2
if (i == 1 || i == 3 || i == 6 || i == 8) {
if (Abs(R1 - R3) > Tolerance) {
Beta3(i) = (X1 - X3)/(R1 - R3);
Gamma3(i) = (Y1 - Y3)/(R1 - R3);
Delta3(i) = (X3*X3 - X1*X1 + Y3*Y3 - Y1*Y1 + (R1 - R3)*(R1 - R3))/(2*(R1 - R3));
}
} else {
Beta3(i) = (X1 - X3)/(R1 + R3);
Gamma3(i) = (Y1 - Y3)/(R1 + R3);
Delta3(i) = (X3*X3 - X1*X1 + Y3*Y3 - Y1*Y1 + (R1 + R3)*(R1 + R3))/(2*(R1 + R3));
}
if ((i == 1 || i == 3 || i == 6 || i == 8) &&
(Abs(R1 - R3) <= Tolerance)) {
A3(i) = 0.;
B3(i) = 0.;
C3(i) = 0.;
D3(i) = X3 - X1;
E3(i) = Y3 - Y1;
F3(i) = X1*X1 - X3*X3 + Y1*Y1 - Y3*Y3;
} else {
A3(i) = Beta3(i)*Beta3(i) - 1.;
B3(i) = Beta3(i)*Gamma3(i);
C3(i) = Gamma3(i)*Gamma3(i) - 1.;
D3(i) = Beta3(i)*Delta3(i) + X3;
E3(i) = Gamma3(i)*Delta3(i) + Y3;
F3(i) = Delta3(i)*Delta3(i) - X3*X3 - Y3*Y3;
}
}
// Second step:
// We are searching for the couple (X,Y) as a solution of the system:
// _
// | a2*x*x +2*b2*x*y + c2*y*y +2*d2*x + 2*e2*y + f2 = 0
// <
// \_ a3*x*x +2*b3*x*y + c3*y*y +2*d3*x + 2*e3*y + f3 = 0
CurSol = 1;
for (i = 1; i <= 8; i++) {
a2 = A2(i); a3 = A3(i);
b2 = B2(i); b3 = B3(i);
c2 = C2(i); c3 = C3(i);
d2 = D2(i); d3 = D3(i);
e2 = E2(i); e3 = E3(i);
f2 = F2(i); f3 = F3(i);
FirstSol(i) = CurSol;
// In some cases we know that some systems have no solution in any case due to qualifiers
if (((i == 2 || i == 5 || i == 6 || i == 8) &&
(Qualified1.IsEnclosed() || Qualified1.IsEnclosing())) ||
((i == 1 || i == 3 || i == 4 || i == 7) && Qualified1.IsOutside()))
continue;
if (((i == 3 || i == 5 || i == 7 || i == 8) &&
(Qualified2.IsEnclosed() || Qualified2.IsEnclosing())) ||
((i == 1 || i == 2 || i == 4 || i == 6) && Qualified2.IsOutside()))
continue;
if (((i == 4 || i == 6 || i == 7 || i == 8) &&
(Qualified3.IsEnclosed() || Qualified3.IsEnclosing())) ||
((i == 1 || i == 2 || i == 3 || i == 5) && Qualified3.IsOutside()))
continue;
// Check is Cir1 a solution of this system or not
// In that case equations are equal to each other
if (Abs(a2 - a3) <= Tolerance && Abs(b2 - b3) <= Tolerance && Abs(c2 - c3) <= Tolerance &&
Abs(d2 - d3) <= Tolerance && Abs(e2 - e3) <= Tolerance && Abs(f2 - f3) <= Tolerance) {
xSol(CurSol) = X1;
ySol(CurSol) = Y1;
CurSol++;
continue;
}
// 1) a2 = 0
if (Abs(a2) <= Tolerance) {
// 1.1) b2y + d2 = 0
// Searching for solution of the equation Ay2 + By + C = 0
A = c2; B = 2.*e2; C = f2;
math_DirectPolynomialRoots yRoots(A, B, C);
if (yRoots.IsDone() && !yRoots.InfiniteRoots())
for (k = 1; k <= yRoots.NbSolutions(); k++) {
// for each y solution:
y = yRoots.Value(k);
// Searching for solution of the equation Ax2 + Bx + C = 0
if (!(k == 2 && Abs(y - yRoots.Value(1)) <= 10*Tolerance) &&
Abs(b2*y + d2) <= b2*Tolerance) {
A = a3; B = 2*(b3*y + d3); C = c3*(y*y) + 2*e3*y + f3;
math_DirectPolynomialRoots xRoots(A, B, C);
if (xRoots.IsDone() && !xRoots.InfiniteRoots())
for (j = 1; j <= xRoots.NbSolutions(); j++) {
x = xRoots.Value(j);
if (!(j == 2 && Abs(x - xRoots.Value(1)) <= 10*Tolerance)) {
xSol(CurSol) = x;
ySol(CurSol) = y;
CurSol++;
}
}
}
}
// 1.2) b2y + d2 != 0
A = a3*c2*c2 - 4*b2*(b3*c2 - b2*c3);
B = 4*a3*c2*e2 - 4*b3*(c2*d2 + 2*b2*e2) + 4*b2*(2*c3*d2 - c2*d3 + 2*b2*e3);
C = 2*a3*(c2*f2 + 2*e2*e2) - 4*b3*(b2*f2 + 2*e2*d2) + 4*c3*d2*d2 - 4*d3*(c2*d2 + 2*b2*e2)
+ 16*b2*e3*d2 + 4*b2*b2*f3;
D = 4*a3*e2*f2 - 4*b3*d2*f2 - 4*d3*(b2*f2 + 2*d2*e2) + 8*d2*d2*e3 + 8*b2*d2*f3;
E = a3*f2*f2 - 4*d2*d3*f2 + 4*d2*d2*f3;
// Searching for solution of the equation Ay4 + By3 + Cy2 + Dy + E = 0
// Special case: one circle touches other
if (IsTouch) {
// Derivation of the equation Ay4 + By3 + Cy2 + Dy + E
math_DirectPolynomialRoots yRoots1(4*A, 3*B, 2*C, D);
if (yRoots1.IsDone() && !yRoots1.InfiniteRoots())
for (k = 1; k <= yRoots1.NbSolutions(); k++) {
y = yRoots1.Value(k);
// Check if this value is already catched
IsSame = Standard_False;
for (l = 1; l < k; l++)
if (Abs(y - yRoots1.Value(l)) <= 10*Tolerance) IsSame = Standard_True;
Epsilon = (Abs((Abs((Abs(4*A*y) + Abs(3*B))*y) + Abs(2*C))*y) + Abs(D));
if (Abs((((A*y + B)*y + C)*y + D)*y + E) <= Epsilon*Tolerance) {
if (!IsSame && Abs(b2*y + d2) > b2*Tolerance) {
x = -(c2*(y*y) + 2*e2*y + f2)/(2*(b2*y + d2));
xSol(CurSol) = x;
ySol(CurSol) = y;
CurSol++;
}
}
}
}
math_DirectPolynomialRoots yRoots1(A, B, C, D, E);
if (yRoots1.IsDone() && !yRoots1.InfiniteRoots())
for (k = 1; k <= yRoots1.NbSolutions(); k++) {
y = yRoots1.Value(k);
// Check if this value is already catched
IsSame = Standard_False;
FirstIndex = (i == 1) ? 1 : FirstSol(i);
for (l = FirstIndex; l < CurSol; l++)
if (Abs(y - ySol(l)) <= 10*Tolerance) IsSame = Standard_True;
if (!IsSame && Abs(b2*y + d2) > b2*Tolerance) {
x = -(c2*(y*y) + 2*e2*y + f2)/(2*(b2*y + d2));
xSol(CurSol) = x;
ySol(CurSol) = y;
CurSol++;
}
}
} else {
// 2) a2 != 0
// Coefficients of the equation (sy + v)Sqrt(p2 - q) = (my2 + ny + t)
m = 2*a3*b2*b2/(a2*a2) - 2*b2*b3/a2 - a3*c2/a2 + c3;
n = 4*a3*b2*d2/(a2*a2) - 2*b3*d2/a2 - 2*b2*d3/a2 - 2*a3*e2/a2 + 2*e3;
t = 2*a3*d2*d2/(a2*a2) - 2*d2*d3/a2 - a3*f2/a2 + f3;
s = 2*b3 - 2*a3*b2/a2;
v = 2*d3 - 2*d2*a3/a2;
//------------------------------------------
// If s = v = 0
if (Abs(s) <= Tolerance && Abs(v) <= Tolerance) {
math_DirectPolynomialRoots yRoots(m, n, t);
if (yRoots.IsDone() && !yRoots.InfiniteRoots())
for (k = 1; k <= yRoots.NbSolutions(); k++) {
// for each y solution:
y = yRoots.Value(k);
p = -(b2*y + d2)/a2;
q = (c2*(y*y) + 2*e2*y + f2)/a2;
Epsilon = 2.*(Abs((b2*b2 + Abs(a2*c2))*y) + Abs(b2*d2) + Abs(a2*e2))/(a2*a2);
if (!(k == 2 && Abs(y - yRoots.Value(1)) <= 10*Tolerance) &&
p*p - q >= -Epsilon*Tolerance) {
A = a2;
B = 2*(b2*y + d2);
C = c2*y*y + 2*e2*y + f2;
math_DirectPolynomialRoots xRoots(A, B, C);
if (xRoots.IsDone() && !xRoots.InfiniteRoots())
for (l = 1; l <= xRoots.NbSolutions(); l++) {
// for each x solution:
x = xRoots.Value(l);
if (!(l == 2 && Abs(x - xRoots.Value(1)) <= 10*Tolerance)) {
xSol(CurSol) = x;
ySol(CurSol) = y;
CurSol++;
}
}
}
}
} else {
//------------------------------------------
// If (s*y + v) != 0
A = s*s*(b2*b2 - a2*c2) - m*m*a2*a2;
B = 2*s*v*(b2*b2 - a2*c2) + 2*s*s*(b2*d2 - a2*e2) - 2*m*n*a2*a2;
C = v*v*(b2*b2 - a2*c2) + 4*s*v*(b2*d2 - a2*e2) + s*s*(d2*d2 - a2*f2) - a2*a2*(2*m*t + n*n);
D = 2*v*v*(b2*d2 - a2*e2) + 2*s*v*(d2*d2 - a2*f2) - 2*n*t*a2*a2;
E = v*v*(d2*d2 - a2*f2) - t*t*a2*a2;
// Searching for solution of the equation Ay4 + By3 + Cy2 + Dy + E = 0
// Special case: one circle touches other
if (IsTouch) {
// Derivation of the equation Ay4 + By3 + Cy2 + Dy + E
math_DirectPolynomialRoots yRoots1(4*A, 3*B, 2*C, D);
if (yRoots1.IsDone() && !yRoots1.InfiniteRoots())
for (k = 1; k <= yRoots1.NbSolutions(); k++) {
y = yRoots1.Value(k);
p = -(b2*y + d2)/a2;
q = (c2*(y*y) + 2*e2*y + f2)/a2;
// Check if this value is already catched
IsSame = Standard_False;
FirstIndex = (i == 1) ? 1 : FirstSol(i);
for (l = FirstIndex; l < CurSol; l++)
if (Abs(y - ySol(l)) <= 10*Tolerance) IsSame = Standard_True;
Epsilon = (Abs((Abs((Abs(4*A*y) + Abs(3*B))*y) + Abs(2*C))*y) + Abs(D));
if (Abs((((A*y + B)*y + C)*y + D)*y + E) <= Epsilon*Tolerance) {
Epsilon = 2.*(Abs((b2*b2 + Abs(a2*c2))*y) + Abs(b2*d2) + Abs(a2*e2))/(a2*a2);
if (!IsSame && p*p - q >= -Epsilon*Tolerance) {
A = a2;
B = 2*(b2*y + d2);
C = c2*y*y + 2*e2*y + f2;
math_DirectPolynomialRoots xRoots(A, B, C);
if (xRoots.IsDone() && !xRoots.InfiniteRoots())
for (l = 1; l <= xRoots.NbSolutions(); l++) {
// for each x solution:
x = xRoots.Value(l);
if (!(l == 2 && Abs(x - xRoots.Value(1)) <= 10*Tolerance)) {
xSol(CurSol) = x;
ySol(CurSol) = y;
CurSol++;
}
}
}
}
}
}
math_DirectPolynomialRoots yRoots(A, B, C, D, E);
if (yRoots.IsDone() && !yRoots.InfiniteRoots())
for (k = 1; k <= yRoots.NbSolutions(); k++) {
// for each y solution:
y = yRoots.Value(k);
p = -(b2*y + d2)/a2;
q = (c2*(y*y) + 2*e2*y + f2)/a2;
// Check if this value is already catched
IsSame = Standard_False;
for (l = 1; l < k; l++)
if (Abs(y - yRoots.Value(l)) <= 10*Tolerance) IsSame = Standard_True;
Epsilon = 2.*(Abs((b2*b2 + Abs(a2*c2))*y) + Abs(b2*d2) + Abs(a2*e2))/(a2*a2);
if (!IsSame && p*p - q >= -Epsilon*Tolerance) {
A = a2;
B = 2*(b2*y + d2);
C = c2*y*y + 2*e2*y + f2;
math_DirectPolynomialRoots xRoots(A, B, C);
if (xRoots.IsDone() && !xRoots.InfiniteRoots())
for (l = 1; l <= xRoots.NbSolutions(); l++) {
// for each x solution:
x = xRoots.Value(l);
if (!(l == 2 && Abs(x - xRoots.Value(1)) <= 10*Tolerance)) {
xSol(CurSol) = x;
ySol(CurSol) = y;
CurSol++;
}
}
}
}
}
}
}
FirstSol(9) = CurSol;
// Third step:
// Check of couples (X,Y) and searching for R. R must be great than 0
CurSol = 1;
for (i = 1; i <= 8; i++) {
FirstSol1(i) = CurSol;
for (j = FirstSol(i); j < FirstSol(i + 1); j++) {
x = xSol(j);
y = ySol(j);
// in some cases when R1 = R2 :
if ((i == 1 || i == 4 || i == 5 || i == 8) && (Abs(R1 - R2) <= Tolerance)) {
if (i == 1 || i == 4) {
r = R1 + Sqrt((x - X1)*(x - X1) + (y - Y1)*(y - Y1));
Epsilon = 10*(2*Abs(r - R2) + Abs(x - X2) + Abs(y - Y2));
if (Abs((r - R2)*(r - R2) - (x - X2)*(x - X2) - (y - Y2)*(y - Y2)) <=
Epsilon*Tolerance) {
xSol1(CurSol) = x;
ySol1(CurSol) = y;
rSol1(CurSol) = r;
CurSol++;
}
r = R1 - Sqrt((x - X1)*(x - X1) + (y - Y1)*(y - Y1));
Epsilon = 10*(2*Abs(r - R2) + Abs(x - X2) + Abs(y - Y2));
if ((r > Tolerance) &&
(Abs((r - R2)*(r - R2) - (x - X2)*(x - X2) - (y - Y2)*(y - Y2)) <=
Epsilon*Tolerance)) {
xSol1(CurSol) = x;
ySol1(CurSol) = y;
rSol1(CurSol) = r;
CurSol++;
}
} else {
// i == 5 || i == 8
r = - R1 + Sqrt((x - X1)*(x - X1) + (y - Y1)*(y - Y1));
if (r > Tolerance) {
xSol1(CurSol) = x;
ySol1(CurSol) = y;
rSol1(CurSol) = r;
CurSol++;
}
}
} else {
// Other cases
if (i == 1 || i == 4) {
r = R2 + Beta2(i)*x + Gamma2(i)*y + Delta2(i);
if (r > Tolerance) {
xSol1(CurSol) = x;
ySol1(CurSol) = y;
rSol1(CurSol) = r;
CurSol++;
}
}
if (i == 5 || i == 8) {
r = -R2 - Beta2(i)*x - Gamma2(i)*y - Delta2(i);
if (r > Tolerance) {
xSol1(CurSol) = x;
ySol1(CurSol) = y;
rSol1(CurSol) = r;
CurSol++;
}
}
if (i == 3 || i == 7) {
r = - R2 + Beta2(i)*x + Gamma2(i)*y + Delta2(i);
if (r > Tolerance) {
xSol1(CurSol) = x;
ySol1(CurSol) = y;
rSol1(CurSol) = r;
CurSol++;
}
}
if (i == 2 || i == 6) {
r = R2 - Beta2(i)*x - Gamma2(i)*y - Delta2(i);
if (r > Tolerance) {
xSol1(CurSol) = x;
ySol1(CurSol) = y;
rSol1(CurSol) = r;
CurSol++;
}
}
}
}
}
FirstSol1(9) = CurSol;
// Fourth step
// Check of triplets (X,Y,R).
CurSol = 1;
for (i = 1; i <= 8; i++) {
FirstSol(i) = CurSol;
for (j = FirstSol1(i); j < FirstSol1(i + 1); j++) {
x = xSol1(j);
y = ySol1(j);
r = rSol1(j);
// in some cases when R1 = R3 :
if ((i == 1 || i == 3 || i == 6 || i == 8) && Abs(R1 - R3) <= Tolerance) {
if (i == 1 || i == 3) {
Epsilon = 10*(2*Abs(r - R3) + Abs(x - X3) + Abs(y - Y3));
if (Abs((r - R3)*(r - R3) - (x - X3)*(x - X3) - (y - Y3)*(y - Y3)) <=
Epsilon*Tolerance) {
xSol(CurSol) = x;
ySol(CurSol) = y;
rSol(CurSol) = r;
CurSol++;
}
} else {
// i == 6 || i == 8
Epsilon = 10*(2*(r + R3) + Abs(x - X3) + Abs(y - Y3));
if (Abs((r + R3)*(r + R3) - (x - X3)*(x - X3) - (y - Y3)*(y - Y3)) <=
Epsilon*Tolerance) {
xSol(CurSol) = x;
ySol(CurSol) = y;
rSol(CurSol) = r;
CurSol++;
}
}
} else {
// Other cases
Epsilon = 10*(Abs(Beta3(i)) + Abs(Gamma3(i)) + 1.);
if (i == 1 || i == 3)
if (Abs(R3 + Beta3(i)*x + Gamma3(i)*y + Delta3(i) - r) <= Epsilon*Tolerance) {
xSol(CurSol) = x;
ySol(CurSol) = y;
rSol(CurSol) = r;
CurSol++;
}
if (i == 6 || i == 8)
if (Abs(R3 + Beta3(i)*x + Gamma3(i)*y + Delta3(i) + r) <= Epsilon*Tolerance) {
xSol(CurSol) = x;
ySol(CurSol) = y;
rSol(CurSol) = r;
CurSol++;
}
if (i == 4 || i == 7)
if (Abs(Beta3(i)*x + Gamma3(i)*y + Delta3(i) - r - R3) <= Epsilon*Tolerance) {
xSol(CurSol) = x;
ySol(CurSol) = y;
rSol(CurSol) = r;
CurSol++;
}
if (i == 2 || i == 5)
if (Abs(r - R3 + Beta3(i)*x + Gamma3(i)*y + Delta3(i)) <= Epsilon*Tolerance) {
xSol(CurSol) = x;
ySol(CurSol) = y;
rSol(CurSol) = r;
CurSol++;
}
}
}
}
FirstSol(9) = CurSol;
// Fifth step:
// We have found all solutions. We have to calculate some parameters for each one.
for (i = 1 ; i <= 8; i++) {
for (j = FirstSol(i); j < FirstSol(i + 1); j++) {
if ((Qualified1.IsEnclosed() && rSol(j) > R1) ||
(Qualified1.IsEnclosing() && rSol(j) < R1))
continue;
if ((Qualified2.IsEnclosed() && rSol(j) > R2) ||
(Qualified2.IsEnclosing() && rSol(j) < R2))
continue;
if ((Qualified3.IsEnclosed() && rSol(j) > R3) ||
(Qualified3.IsEnclosing() && rSol(j) < R3))
continue;
NbrSol++;
// RLE, avoid out of range
if (NbrSol > cirsol.Upper()) NbrSol = cirsol.Upper();
gp_Pnt2d Center = gp_Pnt2d(xSol(j), ySol(j));
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),rSol(j));
// ==========================================================
Standard_Real distcc1 = Center.Distance(center1);
if (!Qualified1.IsUnqualified())
qualifier1(NbrSol) = Qualified1.Qualifier();
else if (Abs(distcc1 + rSol(j) - R1) <= Tol)
qualifier1(NbrSol) = GccEnt_enclosed;
else if (Abs(distcc1 - R1 - rSol(j)) <= Tol)
qualifier1(NbrSol) = GccEnt_outside;
else qualifier1(NbrSol) = GccEnt_enclosing;
Standard_Real distcc2 = Center.Distance(center1);
if (!Qualified2.IsUnqualified())
qualifier2(NbrSol) = Qualified2.Qualifier();
else if (Abs(distcc2 + rSol(j) - R2) <= Tol)
qualifier2(NbrSol) = GccEnt_enclosed;
else if (Abs(distcc2 - R2 - rSol(j)) <= Tol)
qualifier2(NbrSol) = GccEnt_outside;
else qualifier2(NbrSol) = GccEnt_enclosing;
Standard_Real distcc3 = Center.Distance(center1);
if (!Qualified3.IsUnqualified())
qualifier3(NbrSol) = Qualified3.Qualifier();
else if (Abs(distcc3 + rSol(j) - R3) <= Tol)
qualifier3(NbrSol) = GccEnt_enclosed;
else if (Abs(distcc3 - R3 - rSol(j)) <= Tol)
qualifier3(NbrSol) = GccEnt_outside;
else qualifier3(NbrSol) = GccEnt_enclosing;
// ==========================================================
if (Center.Distance(Cir1.Location()) <= Tolerance)
TheSame1(NbrSol) = 1;
else {
TheSame1(NbrSol) = 0;
gp_Dir2d dc;
if ((i == 2 || i == 5 || i == 6 || i == 8) || rSol(j) > R1)
dc.SetXY(Cir1.Location().XY() - Center.XY());
else
dc.SetXY(Center.XY() - Cir1.Location().XY());
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY() + rSol(j)*dc.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(Cir1,pnttg1sol(NbrSol));
}
if (Center.Distance(Cir2.Location()) <= Tolerance)
TheSame2(NbrSol) = 1;
else {
TheSame2(NbrSol) = 0;
gp_Dir2d dc;
if ((i == 3 || i == 5 || i == 7 || i == 8) || rSol(j) > R2)
dc.SetXY(Cir2.Location().XY() - Center.XY());
else
dc.SetXY(Center.XY() - Cir2.Location().XY());
pnttg2sol(NbrSol)=gp_Pnt2d(Center.XY() + rSol(j)*dc.XY());
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(Cir2,pnttg2sol(NbrSol));
}
if (Center.Distance(Cir3.Location()) <= Tolerance)
TheSame3(NbrSol) = 1;
else {
TheSame3(NbrSol) = 0;
gp_Dir2d dc;
if ((i == 4 || i == 6 || i == 7 || i == 8) || rSol(j) > R3)
dc.SetXY(Cir3.Location().XY() - Center.XY());
else
dc.SetXY(Center.XY() - Cir3.Location().XY());
pnttg3sol(NbrSol)=gp_Pnt2d(Center.XY() + rSol(j)*dc.XY());
par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg3sol(NbrSol));
pararg3(NbrSol)=ElCLib::Parameter(Cir3,pnttg3sol(NbrSol));
}
}
}
WellDone = Standard_True;
}
//=========================================================================
Standard_Boolean GccAna_Circ2d3Tan::
IsDone () const {
return WellDone;
}
Standard_Integer GccAna_Circ2d3Tan::
NbSolutions () const {
return NbrSol;
}
gp_Circ2d GccAna_Circ2d3Tan::
ThisSolution (const Standard_Integer Index) const
{
if (!WellDone)
StdFail_NotDone::Raise();
if (Index <= 0 ||Index > NbrSol)
Standard_OutOfRange::Raise();
return cirsol(Index);
}
void GccAna_Circ2d3Tan::
WhichQualifier(const Standard_Integer Index ,
GccEnt_Position& Qualif1 ,
GccEnt_Position& Qualif2 ,
GccEnt_Position& Qualif3 ) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
Qualif1 = qualifier1(Index);
Qualif2 = qualifier2(Index);
Qualif3 = qualifier3(Index);
}
}
void GccAna_Circ2d3Tan::
Tangency1 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const {
if (!WellDone) {
StdFail_NotDone::Raise();
}
else if (Index <= 0 ||Index > NbrSol) {
Standard_OutOfRange::Raise();
}
else {
if (TheSame1(Index) == 0) {
ParSol = par1sol(Index);
ParArg = pararg1(Index);
PntSol = gp_Pnt2d(pnttg1sol(Index));
}
else { StdFail_NotDone::Raise(); }
}
}
void GccAna_Circ2d3Tan::
Tangency2 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
if (!WellDone) {
StdFail_NotDone::Raise();
}
else if (Index <= 0 ||Index > NbrSol) {
Standard_OutOfRange::Raise();
}
else {
if (TheSame2(Index) == 0) {
ParSol = par2sol(Index);
ParArg = pararg2(Index);
PntSol = gp_Pnt2d(pnttg2sol(Index));
}
else { StdFail_NotDone::Raise(); }
}
}
void GccAna_Circ2d3Tan::
Tangency3 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
if (!WellDone) {
StdFail_NotDone::Raise();
}
else if (Index <= 0 ||Index > NbrSol) {
Standard_OutOfRange::Raise();
}
else {
if (TheSame3(Index) == 0) {
ParSol = par3sol(Index);
ParArg = pararg3(Index);
PntSol = gp_Pnt2d(pnttg3sol(Index));
}
else { StdFail_NotDone::Raise(); }
}
}
Standard_Boolean GccAna_Circ2d3Tan::
IsTheSame1 (const Standard_Integer Index) const
{
if (!WellDone)
StdFail_NotDone::Raise();
if (Index <= 0 ||Index > NbrSol)
Standard_OutOfRange::Raise();
if (TheSame1(Index) == 0)
return Standard_False;
return Standard_True;
}
Standard_Boolean GccAna_Circ2d3Tan::
IsTheSame2 (const Standard_Integer Index) const
{
if (!WellDone)
StdFail_NotDone::Raise();
if (Index <= 0 ||Index > NbrSol)
Standard_OutOfRange::Raise();
if (TheSame2(Index) == 0)
return Standard_False;
return Standard_True;
}
Standard_Boolean GccAna_Circ2d3Tan::
IsTheSame3 (const Standard_Integer Index) const
{
if (!WellDone)
StdFail_NotDone::Raise();
if (Index <= 0 ||Index > NbrSol)
Standard_OutOfRange::Raise();
if (TheSame3(Index) == 0)
return Standard_False;
return Standard_True;
}

View File

@@ -0,0 +1,325 @@
// File GccAna_Circ2d3Tan_1.cxx, REG 08/07/91
#include <GccAna_Circ2d3Tan.jxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <ElCLib.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccAna_CircLin2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BLine.hxx>
#include <GccInt_BParab.hxx>
#include <IntAna2d_Conic.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <Precision.hxx>
//=========================================================================
// Creation d un cercle tangent a deux cercles et a une droite. +
//=========================================================================
GccAna_Circ2d3Tan::
GccAna_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1,
const GccEnt_QualifiedCirc& Qualified2,
const GccEnt_QualifiedLin& Qualified3,
const Standard_Real Tolerance ):
//=========================================================================
// Initialisation des champs. +
//=========================================================================
cirsol(1,16) ,
qualifier1(1,16) ,
qualifier2(1,16) ,
qualifier3(1,16),
TheSame1(1,16) ,
TheSame2(1,16) ,
TheSame3(1,16) ,
pnttg1sol(1,16) ,
pnttg2sol(1,16) ,
pnttg3sol(1,16) ,
par1sol(1,16) ,
par2sol(1,16) ,
par3sol(1,16) ,
pararg1(1,16) ,
pararg2(1,16) ,
pararg3(1,16)
{
gp_Dir2d dirx(1.0,0.0);
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()) ||
!(Qualified3.IsEnclosed() ||
Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
//=========================================================================
// Traitement. +
//=========================================================================
gp_Circ2d C1 = Qualified1.Qualified();
gp_Circ2d C2 = Qualified2.Qualified();
gp_Lin2d L3 = Qualified3.Qualified();
Standard_Real R1 = C1.Radius();
Standard_Real R2 = C2.Radius();
gp_Pnt2d center1(C1.Location());
#ifdef DEB
gp_Pnt2d center2(C2.Location());
#else
C2.Location() ;
#endif
gp_Pnt2d origin3(L3.Location());
gp_Dir2d dir3(L3.Direction());
gp_Dir2d normL3(-dir3.Y(),dir3.X());
TColStd_Array1OfReal Radius(1,2);
GccAna_CircLin2dBisec Bis1(C1,L3);
GccAna_CircLin2dBisec Bis2(C2,L3);
if (Bis1.IsDone() && Bis2.IsDone()) {
Standard_Integer nbsolution1 = Bis1.NbSolutions();
Standard_Integer nbsolution2 = Bis2.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution1; i++) {
Handle(GccInt_Bisec) Sol1 = Bis1.ThisSolution(i);
GccInt_IType typ1 = Sol1->ArcType();
IntAna2d_AnaIntersection Intp;
for (Standard_Integer k = 1 ; k <= nbsolution2; k++) {
Handle(GccInt_Bisec) Sol2 = Bis2.ThisSolution(k);
GccInt_IType typ2 = Sol2->ArcType();
if (typ1 == GccInt_Lin) {
if (typ2 == GccInt_Lin) {
Intp.Perform(Sol1->Line(),Sol2->Line());
}
else if (typ2 == GccInt_Par) {
Intp.Perform(Sol1->Line(),IntAna2d_Conic(Sol2->Parabola()));
}
}
else if (typ1 == GccInt_Par) {
if (typ2 == GccInt_Lin) {
Intp.Perform(Sol2->Line(),IntAna2d_Conic(Sol1->Parabola()));
}
else if (typ2 == GccInt_Par) {
Intp.Perform(Sol1->Parabola(),IntAna2d_Conic(Sol2->Parabola()));
}
}
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
Standard_Real Rradius=0;
gp_Pnt2d Center(Intp.Point(j).Value());
// pop : si les coordonnes sont trop grandes ( qu'est trop grand : avoir ) pas de creation
if (Center.X() > 1e10 ||
Center.Y() > 1e10 ) break;
Standard_Real dist1 = Center.Distance(C1.Location());
Standard_Real dist2 = Center.Distance(C2.Location());
Standard_Real dist3 = L3.Distance(Center);
// pop : si les coordonnes sont trop grandes ( qu'est trop grand : avoir ) pas de creation
if (dist3 > 1e10 ) break;
Standard_Integer nbsol1 = 0;
Standard_Integer nbsol2 = 0;
Standard_Integer nbsol3 = 0;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if (dist1-R1 < Tolerance) {
Radius(1) = Abs(R1-dist1);
nbsol1 = 1;
ok = Standard_True;
}
}
else if (Qualified1.IsOutside()) {
if (R1-dist1 < Tolerance) {
Radius(1) = Abs(R1-dist1);
nbsol1 = 1;
ok = Standard_True;
}
}
else if (Qualified1.IsEnclosing()) {
ok = Standard_True;
nbsol1 = 1;
Radius(1) = Abs(R1-dist1);
}
else if (Qualified1.IsUnqualified()) {
ok = Standard_True;
nbsol1 = 2;
Radius(1) = Abs(R1-dist1);
Radius(2) = R1+dist1;
}
if (Qualified2.IsEnclosed() && ok) {
if (dist2-R2 < Tolerance) {
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
Radius(1) = Abs(R2-dist2);
ok = Standard_True;
nbsol2 = 1;
}
}
}
}
else if (Qualified2.IsOutside() && ok) {
if (R2-dist2 < Tolerance) {
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
Radius(1) = Abs(R2-dist2);
ok = Standard_True;
nbsol2 = 1;
}
}
}
}
else if (Qualified2.IsEnclosing() && ok) {
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(Radius(ii)-R2-dist2) < Tol) {
Radius(1) = R2+dist2;
ok = Standard_True;
nbsol2 = 1;
}
}
}
else if (Qualified2.IsUnqualified() && ok) {
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
Rradius = Abs(R2-dist2);
ok = Standard_True;
nbsol2++;
}
else if (Abs(Radius(ii)-R2-dist2) < Tol) {
Rradius = R2+dist2;
ok = Standard_True;
nbsol2++;
}
}
if (nbsol2 == 1) {
Radius(1) = Rradius;
}
else if (nbsol2 == 2) {
Radius(1) = Abs(R2-dist2);
Radius(2) = R2+dist2;
}
}
if (Qualified3.IsEnclosed() && ok) {
if ((((L3.Location().X()-Center.X())*(-L3.Direction().Y()))+
((L3.Location().Y()-Center.Y())*(L3.Direction().X())))<=0){
ok = Standard_True;
nbsol3 = 1;
}
}
else if (Qualified2.IsOutside() && ok) {
if ((((L3.Location().X()-Center.X())*(-L3.Direction().Y()))+
((L3.Location().Y()-Center.Y())*(L3.Direction().X())))>=0){
ok = Standard_True;
nbsol3 = 1;
}
}
else if (Qualified2.IsUnqualified() && ok) {
ok = Standard_True;
nbsol3 = 1;
}
if (ok) {
for (Standard_Integer ind3 = 1 ; ind3 <= nbsol3 ; ind3++) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(ind3));
// ==========================================================
Standard_Real distcc1 = Center.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(ind3)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(ind3)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
Standard_Real distcc2 = Center.Distance(center1);
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (Abs(distcc2+Radius(ind3)-R2) < Tol) {
qualifier2(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc2-R2-Radius(ind3)) < Tol) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosing; }
gp_Dir2d dc3(origin3.XY()-Center.XY());
if (!Qualified3.IsUnqualified()) {
qualifier3(NbrSol) = Qualified3.Qualifier();
}
else if (dc3.Dot(normL3) > 0.0) {
qualifier3(NbrSol) = GccEnt_outside;
}
else { qualifier3(NbrSol) = GccEnt_enclosed; }
if (Center.Distance(C1.Location()) <= Tolerance &&
Abs(Radius(ind3)-R1) <= Tolerance) {
TheSame1(NbrSol) = 1;
}
else {
TheSame1(NbrSol) = 0;
gp_Dir2d dc(C1.Location().XY()-Center.XY());
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(ind3)*dc.XY());
// POP pour portection dans le cas ou cirsol(NbrSol).Location == pnttg1sol(NbrSol)
if (cirsol(NbrSol).Location().IsEqual(pnttg1sol(NbrSol),Precision::Confusion()))
par1sol(NbrSol)=1;
else
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
// POP pour portection dans le cas ou C1.Location == pnttg1sol(NbrSol)
if (C1.Location().IsEqual(pnttg1sol(NbrSol),Precision::Confusion()))
pararg1(NbrSol)=1;
else
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
if (Center.Distance(C2.Location()) <= Tolerance &&
Abs(Radius(ind3)-R2) <= Tolerance) {
TheSame2(NbrSol) = 1;
}
else {
TheSame2(NbrSol) = 0;
gp_Dir2d dc(C2.Location().XY()-Center.XY());
pnttg2sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(ind3)*dc.XY());
// POP pour portection dans le cas ou cirsol(NbrSol).Location == pnttg1sol(NbrSol)
if (cirsol(NbrSol).Location().IsEqual(pnttg1sol(NbrSol),Precision::Confusion()))
par1sol(NbrSol)=1;
else
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
// POP pour portection dans le cas ou C2.Location == pnttg2sol(NbrSol)
if (C2.Location().IsEqual(pnttg2sol(NbrSol),Precision::Confusion()))
pararg2(NbrSol)=1;
else
pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
}
TheSame3(NbrSol) = 0;
gp_Dir2d dc(L3.Location().XY()-Center.XY());
Standard_Real sign = dc.Dot(gp_Dir2d(-L3.Direction().Y(),
L3.Direction().X()));
dc = gp_Dir2d(sign*gp_XY(-L3.Direction().Y(),
L3.Direction().X()));
pnttg3sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(ind3)*dc.XY());
par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg3sol(NbrSol));
pararg3(NbrSol)=ElCLib::Parameter(L3,pnttg3sol(NbrSol));
}
}
}
}
WellDone = Standard_True;
}
}
}
}
}

View File

@@ -0,0 +1,265 @@
// File GccAna_Circ2d3Tan_2.cxx, REG 08/07/91
#include <GccAna_Circ2d3Tan.jxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <gp_Lin2d.hxx>
#include <ElCLib.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccAna_CircLin2dBisec.hxx>
#include <GccAna_Lin2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BLine.hxx>
#include <GccInt_BParab.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Creation d un cercle tangent a un cercle et a deux droites. +
//=========================================================================
GccAna_Circ2d3Tan::GccAna_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 ,
const GccEnt_QualifiedLin& Qualified2 ,
const GccEnt_QualifiedLin& Qualified3 ,
const Standard_Real Tolerance )
//=========================================================================
// Initialisation des champs. +
//=========================================================================
:cirsol(1,8) ,
qualifier1(1,8) ,
qualifier2(1,8) ,
qualifier3(1,8) ,
TheSame1(1,8) ,
TheSame2(1,8) ,
TheSame3(1,8) ,
pnttg1sol(1,8) ,
pnttg2sol(1,8) ,
pnttg3sol(1,8) ,
par1sol(1,8) ,
par2sol(1,8) ,
par3sol(1,8) ,
pararg1(1,8) ,
pararg2(1,8) ,
pararg3(1,8)
{
TheSame1.Init(0);
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified()) ||
!(Qualified3.IsEnclosed() ||
Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
//=========================================================================
// Traitement. +
//=========================================================================
gp_Circ2d C1 = Qualified1.Qualified();
gp_Lin2d L2 = Qualified2.Qualified();
gp_Lin2d L3 = Qualified3.Qualified();
Standard_Real R1 = C1.Radius();
gp_Pnt2d center1(C1.Location());
gp_Pnt2d origin2(L2.Location());
gp_Dir2d dir2(L2.Direction());
gp_Dir2d normL2(-dir2.Y(),dir2.X());
gp_Pnt2d origin3(L3.Location());
gp_Dir2d dir3(L3.Direction());
gp_Dir2d normL3(-dir3.Y(),dir3.X());
TColStd_Array1OfReal Radius(1,2);
GccAna_CircLin2dBisec Bis1(C1,L2);
GccAna_Lin2dBisec Bis2(L2,L3);
if (Bis1.IsDone() && Bis2.IsDone()) {
Standard_Integer nbsolution1 = Bis1.NbSolutions();
Standard_Integer nbsolution2 = Bis2.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution1; i++) {
Handle(GccInt_Bisec) Sol1 = Bis1.ThisSolution(i);
GccInt_IType typ1 = Sol1->ArcType();
IntAna2d_AnaIntersection Intp;
for (Standard_Integer k = 1 ; k <= nbsolution2; k++) {
if (typ1 == GccInt_Lin) {
Intp.Perform(Sol1->Line(),Bis2.ThisSolution(k));
}
else if (typ1 == GccInt_Par) {
Intp.Perform(Bis2.ThisSolution(k),IntAna2d_Conic(Sol1->Parabola()));
}
if (Intp.IsDone()) {
if ((!Intp.IsEmpty())&&(!Intp.ParallelElements())&&
(!Intp.IdenticalElements())) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = Center.Distance(center1);
Standard_Real dist2 = L2.Distance(Center);
Standard_Real dist3 = L3.Distance(Center);
Standard_Integer nbsol1 = 0;
Standard_Integer nbsol2 = 0;
Standard_Integer nbsol3 = 0;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if (dist1-R1 < Tolerance) {
Radius(1) = Abs(R1-dist1);
nbsol1 = 1;
ok = Standard_True;
}
}
else if (Qualified1.IsOutside()) {
if (R1-dist1 < Tolerance) {
Radius(1) = Abs(R1-dist1);
nbsol1 = 1;
ok = Standard_True;
}
}
else if (Qualified1.IsEnclosing()) {
ok = Standard_True;
nbsol1 = 1;
Radius(1) = Abs(R1-dist1);
}
else if (Qualified1.IsUnqualified()) {
ok = Standard_True;
nbsol1 = 2;
Radius(1) = Abs(R1-dist1);
Radius(2) = R1+dist1;
}
if (Qualified2.IsEnclosed() && ok) {
if ((((origin2.X()-Center.X())*(-dir2.Y()))+
((origin2.Y()-Center.Y())*(dir2.X())))<=0){
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(dist2-Radius(ii)) < Tol) {
ok = Standard_True;
nbsol2 = 1;
Radius(1) = Radius(ii);
}
}
}
}
else if (Qualified2.IsOutside() && ok) {
if ((((origin2.X()-Center.X())*(-dir2.Y()))+
((origin2.Y()-Center.Y())*(dir2.X())))>=0){
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(dist2-Radius(ii)) < Tol) {
ok = Standard_True;
nbsol2 = 1;
Radius(1) = Radius(ii);
}
}
}
}
else if (Qualified2.IsUnqualified() && ok) {
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(dist2-Radius(ii)) < Tol) {
ok = Standard_True;
nbsol2 = 1;
Radius(1) = Radius(ii);
}
}
}
if (Qualified3.IsEnclosed() && ok) {
if ((((origin3.X()-Center.X())*(-dir3.Y()))+
((origin3.Y()-Center.Y())*(dir3.X())))<=0){
if (Abs(dist3-Radius(1)) < Tol) {
ok = Standard_True;
nbsol3 = 1;
}
}
}
else if (Qualified3.IsOutside() && ok) {
if ((((origin3.X()-Center.X())*(-dir3.Y()))+
((origin3.Y()-Center.Y())*(dir3.X())))>=0){
if (Abs(dist3-Radius(1)) < Tol) {
ok = Standard_True;
nbsol3 = 1;
}
}
}
else if (Qualified3.IsUnqualified() && ok) {
if (Abs(dist3-Radius(1)) < Tol) {
ok = Standard_True;
nbsol3 = 1;
}
}
if (ok) {
for (k = 1 ; k <= nbsol3 ; k++) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
// ==========================================================
Standard_Real distcc1 = Center.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(k)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(k)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
gp_Dir2d dc2(origin2.XY()-Center.XY());
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (dc2.Dot(normL2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
gp_Dir2d dc3(origin3.XY()-Center.XY());
if (!Qualified3.IsUnqualified()) {
qualifier3(NbrSol) = Qualified3.Qualifier();
}
else if (dc3.Dot(normL3) > 0.0) {
qualifier3(NbrSol) = GccEnt_outside;
}
else { qualifier3(NbrSol) = GccEnt_enclosed; }
if (Center.Distance(center1) <= Tolerance &&
Abs(Radius(k)-R1) <= Tolerance) {
TheSame1(NbrSol) = 1;
}
else {
TheSame1(NbrSol) = 0;
gp_Dir2d dc(center1.XY()-Center.XY());
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
TheSame2(NbrSol) = 0;
TheSame3(NbrSol) = 0;
gp_Dir2d dc(origin2.XY()-Center.XY());
Standard_Real sign = dc.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
dc = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(k)*dc.XY());
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
dc = gp_Dir2d(origin3.XY()-Center.XY());
sign = dc.Dot(gp_Dir2d(-dir3.Y(),dir3.X()));
dc = gp_Dir2d(sign*gp_XY(-dir3.Y(),dir3.X()));
pnttg3sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(k)*dc.XY());
par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg3sol(NbrSol));
pararg3(NbrSol)=ElCLib::Parameter(L3,pnttg3sol(NbrSol));
}
}
}
}
WellDone = Standard_True;
}
}
}
}
}

View File

@@ -0,0 +1,482 @@
// File GccAna_Circ2d3Tan_3.cxx, REG 08/07/91
#include <ElCLib.hxx>
#include <GccAna_Circ2d3Tan.jxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccAna_Lin2dBisec.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Creation d un cercle tangent a trois droites. +
// On cree les Bissectrices a Qualified1 et Qualified2 et +
// les Bissectrices a Qualified1 et Qualified3. +
// On intersecte les bissectrices ainsi calculees ==> Points de centre. +
// On Choisit le point de centre qui correspond aux qualifieurs et on +
// construit la solution de rayon egal a la distance entre le point de +
// centre choisi et la droite Qualified1. +
//=========================================================================
GccAna_Circ2d3Tan::
GccAna_Circ2d3Tan (const GccEnt_QualifiedLin& Qualified1,
const GccEnt_QualifiedLin& Qualified2,
const GccEnt_QualifiedLin& Qualified3,
const Standard_Real
#ifdef DEB
Tolerance
#endif
):
//=========================================================================
// Initialisation des champs. +
//=========================================================================
cirsol(1,4) ,
qualifier1(1,4) ,
qualifier2(1,4) ,
qualifier3(1,4) ,
TheSame1(1,4) ,
TheSame2(1,4) ,
TheSame3(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
pnttg3sol(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
par3sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4) ,
pararg3(1,4)
{
TheSame1.Init(0);
TheSame2.Init(0);
TheSame3.Init(0);
gp_Dir2d dirx(1.0,0.0);
#ifdef DEB
Standard_Real Tol = Abs(Tolerance);
#endif
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified()) ||
!(Qualified3.IsEnclosed() ||
Qualified3.IsOutside() || Qualified3.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
//=========================================================================
// Traitement. +
//=========================================================================
gp_Lin2d L1(Qualified1.Qualified());
gp_Lin2d L2(Qualified2.Qualified());
gp_Lin2d L3(Qualified3.Qualified());
gp_Pnt2d origin1(L1.Location());
gp_Dir2d dir1(L1.Direction());
gp_Dir2d normL1(-dir1.Y(),dir1.X());
gp_Pnt2d origin2(L2.Location());
gp_Dir2d dir2(L2.Direction());
gp_Dir2d normL2(-dir2.Y(),dir2.X());
gp_Pnt2d origin3(L3.Location());
gp_Dir2d dir3(L3.Direction());
gp_Dir2d normL3(-dir3.Y(),dir3.X());
Standard_Real xloc1 = origin1.X();
Standard_Real xloc2 = origin2.X();
Standard_Real xloc3 = origin3.X();
Standard_Real yloc1 = origin1.Y();
Standard_Real yloc2 = origin2.Y();
Standard_Real yloc3 = origin3.Y();
Standard_Real xdir1 = dir1.X();
Standard_Real xdir2 = dir2.X();
Standard_Real xdir3 = dir3.X();
Standard_Real ydir1 = dir1.Y();
Standard_Real ydir2 = dir2.Y();
Standard_Real ydir3 = dir3.Y();
GccAna_Lin2dBisec Bisec1(L1,L2);
GccAna_Lin2dBisec Bisec2(L1,L3);
Standard_Integer ncote1=0;
Standard_Integer ncote2=0;
Standard_Integer ncote3=0;
TColStd_Array1OfReal cote1(1,2);
TColStd_Array1OfReal cote2(1,2);
TColStd_Array1OfReal cote3(1,2);
Standard_Integer nbsol = 0;
if (Bisec1.IsDone() && Bisec2.IsDone()) {
for (Standard_Integer i = 1 ; i <= Bisec1.NbSolutions() ; i++) {
for (Standard_Integer j = 1 ; j <= Bisec2.NbSolutions() ; j++) {
IntAna2d_AnaIntersection Intp(Bisec1.ThisSolution(i),
Bisec2.ThisSolution(j));
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer k = 1 ; k <= Intp.NbPoints() ; k++) {
nbsol++;
Standard_Real Radius = (L1.Distance(Intp.Point(k).Value())+
L2.Distance(Intp.Point(k).Value())+
L3.Distance(Intp.Point(k).Value()))/3.0;
gp_Pnt2d Center(Intp.Point(k).Value());
Standard_Real cx = Center.X();
Standard_Real cy = Center.Y();
cirsol(nbsol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// ======================================================
gp_Dir2d dc1(origin1.XY()-Center.XY());
if (!Qualified1.IsUnqualified()) {
qualifier1(nbsol) = Qualified1.Qualifier();
}
else if (dc1.Dot(normL1) > 0.0) {
qualifier1(nbsol) = GccEnt_outside;
}
else { qualifier1(nbsol) = GccEnt_enclosed; }
gp_Dir2d dc2(origin2.XY()-Center.XY());
if (!Qualified2.IsUnqualified()) {
qualifier2(nbsol) = Qualified2.Qualifier();
}
else if (dc2.Dot(normL2) > 0.0) {
qualifier2(nbsol) = GccEnt_outside;
}
else { qualifier2(nbsol) = GccEnt_enclosed; }
gp_Dir2d dc3(origin3.XY()-Center.XY());
if (!Qualified3.IsUnqualified()) {
qualifier3(nbsol) = Qualified3.Qualifier();
}
else if (dc3.Dot(normL3) > 0.0) {
qualifier3(nbsol) = GccEnt_outside;
}
else { qualifier3(nbsol) = GccEnt_enclosed; }
Standard_Real cross1=gp_Dir2d(-ydir1,xdir1)
.Dot(gp_Dir2d(xloc1-cx,yloc1-cy));
Standard_Real cross2=gp_Dir2d(-ydir2,xdir2)
.Dot(gp_Dir2d(xloc2-cx,yloc2-cy));
Standard_Real cross3=gp_Dir2d(-ydir3,xdir3)
.Dot(gp_Dir2d(xloc3-cx,yloc3-cy));
if (cross1 != 0.0) {
cross1 = cross1/Abs(cross1);
}
pnttg1sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+
cross1*Radius*gp_XY(-ydir1,xdir1));
if (cross2 != 0.0) {
cross2 = cross2/Abs(cross2);
}
pnttg2sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+
cross2*Radius*gp_XY(-ydir2,xdir2));
if (cross3 != 0.0) {
cross3 = cross3/Abs(cross3);
}
pnttg3sol(nbsol) = gp_Pnt2d(gp_XY(cx,cy)+
cross3*Radius*gp_XY(-ydir3,xdir3));
par1sol(nbsol)=ElCLib::Parameter(cirsol(nbsol),
pnttg1sol(nbsol));
pararg1(nbsol)=ElCLib::Parameter(L1,pnttg1sol(nbsol));
par2sol(nbsol)=ElCLib::Parameter(cirsol(nbsol),
pnttg2sol(nbsol));
pararg2(nbsol)=ElCLib::Parameter(L2,pnttg2sol(nbsol));
par3sol(nbsol)=ElCLib::Parameter(cirsol(nbsol),
pnttg3sol(nbsol));
pararg3(nbsol)=ElCLib::Parameter(L3,pnttg3sol(nbsol));
}
}
WellDone = Standard_True;
}
}
}
}
if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed() &&
// =========================================================
Qualified3.IsEnclosed()) {
// ========================
ncote1 = 1;
ncote2 = 1;
ncote3 = 1;
cote1(1) = 1.0;
cote2(1) = 1.0;
cote3(1) = 1.0;
}
else if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed() &&
// ==============================================================
Qualified3.IsOutside()) {
// =======================
ncote1 = 1;
ncote2 = 1;
ncote3 = 1;
cote1(1) = 1.0;
cote2(1) = 1.0;
cote3(1) = -1.0;
}
else if (Qualified1.IsEnclosed() && Qualified2.IsOutside() &&
// =============================================================
Qualified3.IsEnclosed()) {
// ========================
ncote1 = 1;
ncote2 = 1;
ncote3 = 1;
cote1(1) = 1.0;
cote2(1) = -1.0;
cote3(1) = 1.0;
}
else if (Qualified1.IsEnclosed() && Qualified2.IsOutside() &&
// =============================================================
Qualified3.IsOutside()) {
// =======================
ncote1 = 1;
ncote2 = 1;
ncote3 = 1;
cote1(1) = 1.0;
cote2(1) = -1.0;
cote3(1) = -1.0;
}
else if (Qualified1.IsOutside() && Qualified2.IsEnclosed() &&
// =============================================================
Qualified3.IsEnclosed()) {
// ========================
ncote1 = 1;
ncote2 = 1;
ncote3 = 1;
cote1(1) = -1.0;
cote2(1) = 1.0;
cote3(1) = 1.0;
}
else if (Qualified1.IsOutside() && Qualified2.IsEnclosed() &&
// =============================================================
Qualified3.IsOutside()) {
// =======================
ncote1 = 1;
ncote2 = 1;
ncote3 = 1;
cote1(1) = -1.0;
cote2(1) = 1.0;
cote3(1) = -1.0;
}
else if (Qualified1.IsOutside() && Qualified2.IsOutside() &&
// ============================================================
Qualified3.IsEnclosed()) {
// ========================
ncote1 = 1;
ncote2 = 1;
ncote3 = 1;
cote1(1) = -1.0;
cote2(1) = -1.0;
cote3(1) = 1.0;
}
else if (Qualified1.IsOutside() && Qualified2.IsOutside() &&
// ============================================================
Qualified3.IsOutside()) {
// =======================
ncote1 = 1;
ncote2 = 1;
ncote3 = 1;
cote1(1) = -1.0;
cote2(1) = -1.0;
cote3(1) = -1.0;
}
else {
if (Qualified1.IsUnqualified()) {
// ====================================
ncote1 = 2;
cote1(1) = 1.0;
cote1(2) = -1.0;
if (Qualified2.IsUnqualified()) {
// ===============================
ncote2 = 2;
cote2(1) = 1.0;
cote2(2) = -1.0;
if (Qualified3.IsUnqualified()) {
// ===============================
ncote3 = 2;
cote2(1) = 1.0;
cote2(2) = -1.0;
NbrSol = nbsol;
WellDone = Standard_True;
}
else if (Qualified3.IsEnclosed()) {
// ===============================
ncote3 = 1;
cote3(1) = 1.0;
}
else if (Qualified3.IsOutside()) {
// ================================
ncote3 = 1;
cote3(1) = -1.0;
}
}
else if (Qualified2.IsEnclosed()) {
// =================================
ncote2 = 1;
cote2(1) = 1.0;
if (Qualified3.IsUnqualified()) {
// ===============================
ncote3 = 2;
cote3(1) = 1.0;
cote3(1) = -1.0;
}
else if (Qualified3.IsEnclosed()) {
// =================================
ncote3 = 1;
cote3(1) = 1.0;
}
else if (Qualified3.IsOutside()) {
// ================================
ncote3 = 1;
cote3(1) = -1.0;
}
}
else if (Qualified2.IsOutside()) {
// ================================
ncote2 = 1;
cote2(1) = -1.0;
if (Qualified3.IsUnqualified()) {
// ===============================
ncote3 = 2;
cote3(1) = 1.0;
cote3(2) = -1.0;
}
else if (Qualified3.IsEnclosed()) {
// =================================
ncote3 = 1;
cote3(1) = 1.0;
}
else if (Qualified3.IsOutside()) {
// ================================
ncote3 = 1;
cote3(1) = -1.0;
}
}
}
else if (Qualified2.IsUnqualified()) {
// ===================================
ncote2 = 2;
cote2(1) = 1.0;
cote2(2) = -1.0;
if (Qualified1.IsEnclosed()) {
// ============================
ncote1 = 1;
cote1(1) = 1.0;
if (Qualified3.IsUnqualified()) {
// ===============================
ncote3 = 2;
cote3(1) = -1.0;
cote3(1) = -1.0;
}
else if (Qualified3.IsEnclosed()) {
// =================================
ncote3 = 1;
cote3(1) = 1.0;
}
else if (Qualified3.IsOutside()) {
// ================================
ncote3 = 1;
cote3(1) = -1.0;
}
}
else if (Qualified1.IsOutside()) {
// ================================
ncote1 = 1;
cote1(1) = 1.0;
if (Qualified3.IsUnqualified()) {
// ===============================
ncote3 = 2;
cote3(1) = 1.0;
cote3(2) = -1.0;
}
else if (Qualified3.IsEnclosed()) {
// =================================
ncote3 = 1;
cote3(1) = 1.0;
}
else if (Qualified3.IsOutside()) {
// ================================
ncote3 = 1;
cote3(1) = -1.0;
}
}
}
else if (Qualified3.IsUnqualified()) {
// ===================================
ncote3 = 2;
cote3(1) = 1.0;
cote3(2) = -1.0;
if (Qualified1.IsEnclosed()) {
// ============================
ncote1 = 1;
cote1(1) = 1.0;
if (Qualified2.IsEnclosed()) {
// ============================
ncote2 = 1;
cote2(1) = 1.0;
}
else if (Qualified2.IsOutside()) {
// ===============================
ncote2 = 1;
cote2(1) = -1.0;
}
}
else if (Qualified1.IsOutside()) {
// ================================
ncote1 = 1;
cote1(1) = -1.0;
if (Qualified2.IsEnclosed()) {
// ============================
ncote2 = 1;
cote2(1) = 1.0;
}
else if (Qualified2.IsOutside()) {
// ===============================
ncote2 = 1;
cote2(1) = -1.0;
}
}
}
}
if (NbrSol > 0) { return; }
for (Standard_Integer i = 1 ; i <= nbsol ; i++) {
for (Standard_Integer j1 = 1 ; j1 <= ncote1 ; j1++) {
for (Standard_Integer j2 = 1 ; j2 <= ncote2 ; j2++) {
for (Standard_Integer j3 = 1 ; j3 <= ncote3 ; j3++) {
if ((cote2(j2)*((cirsol(i).Location().X()-origin2.X())*
(-dir2.Y())+(cirsol(i).Location().Y()-
origin2.Y())*(dir2.X())) > 0.0) &&
(cote3(j3)*((cirsol(i).Location().X()-origin3.X())*
(-dir3.Y())+(cirsol(i).Location().Y()-
origin3.Y())*(dir3.X())) > 0.0) &&
(cote1(j1)*((cirsol(i).Location().X()-origin1.X())*
(-dir1.Y())+(cirsol(i).Location().Y()-
origin1.Y())*(dir1.X())) > 0.0)) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(cirsol(i));
// =====================================
Standard_Real Radius = cirsol(NbrSol).Radius();
gp_Pnt2d Center(cirsol(NbrSol).Location());
gp_Dir2d dc(origin1.XY()-Center.XY());
Standard_Real sign = dc.Dot(gp_Dir2d(-dir1.Y(),dir1.X()));
dc = gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X()));
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY());
dc = gp_Dir2d(origin2.XY()-Center.XY());
sign = dc.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
dc = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY());
dc = gp_Dir2d(origin3.XY()-Center.XY());
sign = dc.Dot(gp_Dir2d(-dir3.Y(),dir3.X()));
dc = gp_Dir2d(sign*gp_XY(-dir3.Y(),dir3.X()));
pnttg3sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg3sol(NbrSol));
pararg3(NbrSol)=ElCLib::Parameter(L3,pnttg3sol(NbrSol));
}
}
}
}
}
}

View File

@@ -0,0 +1,360 @@
// File GccAna_Circ2d3Tan.cxx_4, REG 08/07/91
// cas de 2 cercles concentriques JCT 28/11/97
#include <ElCLib.hxx>
#include <GccAna_Circ2d3Tan.jxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccAna_Circ2dBisec.hxx>
#include <GccAna_CircPnt2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BCirc.hxx>
#include <GccInt_BLine.hxx>
#include <GccInt_BElips.hxx>
#include <GccInt_BHyper.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccEnt_BadQualifier.hxx>
static Standard_Integer MaxSol = 20;
//=========================================================================
// Creation d un cercle tangent a deux cercles et a un point. +
//=========================================================================
GccAna_Circ2d3Tan::
GccAna_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 ,
const GccEnt_QualifiedCirc& Qualified2 ,
const gp_Pnt2d& Point3 ,
const Standard_Real Tolerance ):
//=========================================================================
// Initialisation des champs. +
//=========================================================================
cirsol(1,MaxSol) ,
qualifier1(1,MaxSol) ,
qualifier2(1,MaxSol) ,
qualifier3(1,MaxSol) ,
TheSame1(1,MaxSol) ,
TheSame2(1,MaxSol) ,
TheSame3(1,MaxSol) ,
pnttg1sol(1,MaxSol) ,
pnttg2sol(1,MaxSol) ,
pnttg3sol(1,MaxSol) ,
par1sol(1,MaxSol) ,
par2sol(1,MaxSol) ,
par3sol(1,MaxSol) ,
pararg1(1,MaxSol) ,
pararg2(1,MaxSol) ,
pararg3(1,MaxSol)
{
gp_Dir2d dirx(1.0,0.0);
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())) {
GccEnt_BadQualifier::Raise();
return;
}
//=========================================================================
// Traitement. +
//=========================================================================
gp_Circ2d C1(Qualified1.Qualified());
gp_Circ2d C2(Qualified2.Qualified());
Standard_Real R1 = C1.Radius();
Standard_Real R2 = C2.Radius();
gp_Pnt2d center1(C1.Location());
gp_Pnt2d center2(C2.Location());
TColStd_Array1OfReal Radius(1,2);
GccAna_Circ2dBisec Bis1(C1,C2);
GccAna_CircPnt2dBisec Bis2(C1,Point3);
if (Bis1.IsDone() && Bis2.IsDone()) {
Standard_Integer nbsolution1 = Bis1.NbSolutions();
Standard_Integer nbsolution2 = Bis2.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution1; i++) {
Handle(GccInt_Bisec) Sol1 = Bis1.ThisSolution(i);
GccInt_IType typ1 = Sol1->ArcType();
IntAna2d_AnaIntersection Intp;
for (Standard_Integer k = 1 ; k <= nbsolution2; k++) {
Handle(GccInt_Bisec) Sol2 = Bis2.ThisSolution(k);
GccInt_IType typ2 = Sol2->ArcType();
if (typ1 == GccInt_Cir) {
if (typ2 == GccInt_Cir) {
Intp.Perform(Sol1->Circle(),Sol2->Circle());
}
else if (typ2 == GccInt_Lin) {
Intp.Perform(Sol2->Line(),Sol1->Circle());
}
else if (typ2 == GccInt_Hpr) {
Intp.Perform(Sol1->Circle(),IntAna2d_Conic(Sol2->Hyperbola()));
}
else if (typ2 == GccInt_Ell) {
Intp.Perform(Sol1->Circle(),IntAna2d_Conic(Sol2->Ellipse()));
}
}
else if (typ1 == GccInt_Ell) {
if (typ2 == GccInt_Cir) {
Intp.Perform(Sol2->Circle(),IntAna2d_Conic(Sol1->Ellipse()));
}
else if (typ2 == GccInt_Lin) {
Intp.Perform(Sol2->Line(),IntAna2d_Conic(Sol1->Ellipse()));
}
else if (typ2 == GccInt_Hpr) {
Intp.Perform(Sol1->Ellipse(),IntAna2d_Conic(Sol2->Hyperbola()));
}
else if (typ2 == GccInt_Ell) {
Intp.Perform(Sol1->Ellipse(),IntAna2d_Conic(Sol2->Ellipse()));
}
}
else if (typ1 == GccInt_Lin) {
if (typ2 == GccInt_Cir) {
Intp.Perform(Sol1->Line(),Sol2->Circle());
}
else if (typ2 == GccInt_Lin) {
Intp.Perform(Sol1->Line(),Sol2->Line());
}
else if (typ2 == GccInt_Hpr) {
Intp.Perform(Sol1->Line(),IntAna2d_Conic(Sol2->Hyperbola()));
}
else if (typ2 == GccInt_Ell) {
Intp.Perform(Sol1->Line(),IntAna2d_Conic(Sol2->Ellipse()));
}
}
else if (typ1 == GccInt_Hpr) {
if (typ2 == GccInt_Cir) {
Intp.Perform(Sol2->Circle(),IntAna2d_Conic(Sol1->Hyperbola()));
}
else if (typ2 == GccInt_Lin) {
Intp.Perform(Sol2->Line(),IntAna2d_Conic(Sol1->Hyperbola()));
}
else if (typ2 == GccInt_Hpr) {
Intp.Perform(Sol2->Hyperbola(),IntAna2d_Conic(Sol1->Hyperbola()));
}
else if (typ2 == GccInt_Ell) {
Intp.Perform(Sol2->Ellipse(),IntAna2d_Conic(Sol1->Hyperbola()));
}
}
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
Standard_Real Rradius=0;
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = Center.Distance(center1);
Standard_Real dist2 = Center.Distance(center2);
Standard_Real dist3 = Center.Distance(Point3);
Standard_Integer nbsol1 = 0;
Standard_Integer nbsol2 = 0;
Standard_Integer nbsol3 = 0;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if (dist1-R1 < Tolerance) {
Radius(1) = Abs(R1-dist1);
nbsol1 = 1;
ok = Standard_True;
}
}
else if (Qualified1.IsOutside()) {
if (R1-dist1 < Tolerance) {
Radius(1) = Abs(R1-dist1);
nbsol1 = 1;
ok = Standard_True;
}
}
else if (Qualified1.IsEnclosing()) {
ok = Standard_True;
nbsol1 = 1;
Radius(1) = R1+dist1;
}
else if (Qualified1.IsUnqualified()) {
ok = Standard_True;
nbsol1 = 2;
Radius(1) = Abs(R1-dist1);
Radius(2) = R1+dist1;
}
if (Qualified2.IsEnclosed() && ok) {
if (dist2-R2 < Tolerance) {
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
Radius(1) = Abs(R2-dist2);
ok = Standard_True;
nbsol2 = 1;
}
}
}
}
else if (Qualified2.IsOutside() && ok) {
if (R2-dist2 < Tolerance) {
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
Radius(1) = Abs(R2-dist2);
ok = Standard_True;
nbsol2 = 1;
}
}
}
}
else if (Qualified2.IsEnclosing() && ok) {
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(Radius(ii)-R2-dist2) < Tol) {
Radius(1) = R2+dist2;
ok = Standard_True;
nbsol2 = 1;
}
}
}
else if (Qualified2.IsUnqualified() && ok) {
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
Rradius = Abs(R2-dist2);
ok = Standard_True;
nbsol2++;
}
else if (Abs(Radius(ii)-R2-dist2) < Tol) {
Rradius = R2+dist2;
ok = Standard_True;
nbsol2++;
}
}
if (nbsol2 == 1) {
Radius(1) = Rradius;
}
else if (nbsol2 == 2) {
Radius(1) = Abs(R2-dist2);
Radius(2) = R2+dist2;
}
}
for (Standard_Integer ii = 1 ; ii <= nbsol2 ; ii++) {
if (Abs(dist3-Radius(ii)) <= Tol) {
nbsol3++;
ok = Standard_True;
}
}
if (ok) {
for (Standard_Integer k1 = 1 ; k1 <= nbsol3 ; k1++) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k1));
// ==========================================================
Standard_Real distcc1 = Center.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(k1)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(k1)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
// Standard_Real distcc2 = Center.Distance(center1);
Standard_Real distcc2 = Center.Distance(center2);
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (Abs(distcc2+Radius(k1)-R2) < Tol) {
qualifier2(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc2-R2-Radius(k1)) < Tol) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosing; }
qualifier3(NbrSol) = GccEnt_noqualifier;
if (Center.Distance(center1) <= Tolerance &&
Abs(Radius(k1)-R1) <= Tolerance) {
TheSame1(NbrSol) = 1;
}
else {
TheSame1(NbrSol) = 0;
gp_Dir2d dc(center1.XY()-Center.XY());
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k1)*dc.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,
pnttg1sol(NbrSol));
}
if (Center.Distance(center2) <= Tolerance &&
Abs(Radius(k1)-R2) <= Tolerance) {
TheSame2(NbrSol) = 1;
}
else {
TheSame2(NbrSol) = 0;
gp_Dir2d dc(center2.XY()-Center.XY());
// cas des cercles concentriques :
// le 2eme point de tangence est de l'autre cote du cercle solution
Standard_Real alpha = 1.;
if (center1.Distance(center2)<=Tolerance) alpha = -1;
pnttg2sol(NbrSol)=gp_Pnt2d(Center.XY()+alpha*Radius(k1)*dc.XY());
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
}
TheSame3(NbrSol) = 0;
pnttg3sol(NbrSol) = Point3;
par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg3sol(NbrSol));
pararg3(NbrSol) = 0.;
WellDone = Standard_True;
if (NbrSol==MaxSol) break;
}
}
}
}
WellDone = Standard_True;
if (NbrSol==MaxSol) break;
}
if (NbrSol==MaxSol) break;
}
if (NbrSol==MaxSol) break;
}
}
// Debug grossier pour que le point soit sur les cercles solutions.
Standard_Integer kk ;
for ( kk = 1; kk <= NbrSol; kk++) {
gp_Circ2d CC = cirsol(kk);
Standard_Real NR = CC.Location().Distance(Point3);
if (Abs(NR - CC.Radius()) > Tol) {
cirsol(kk).SetRadius(NR);
}
}
// Debug grossier pour eliminer solution multiple.
// ca arrive dans le cas d intersection ligne hyperbole.
Standard_Real Tol2 = Tol*Tol;
for (kk = 1; kk <NbrSol; kk++) {
gp_Pnt2d PK = cirsol(kk).Location();
for (Standard_Integer ll = kk+1 ; ll <= NbrSol; ll++) {
gp_Pnt2d PL = cirsol(ll).Location();
if (PK.SquareDistance(PL) < Tol2) {
for (Standard_Integer mm = ll+1 ; mm <= NbrSol; mm++) {
cirsol(mm - 1) = cirsol (mm);
pnttg1sol(mm-1) = pnttg1sol(mm);
pnttg2sol(mm-1) = pnttg2sol(mm);
pnttg3sol(mm-1) = pnttg3sol(mm);
par1sol(mm-1) = par1sol(mm);
par2sol(mm-1) = par2sol(mm);
par3sol(mm-1) = par3sol(mm);
pararg1(mm-1) = pararg1(mm);
pararg2(mm-1) = pararg2(mm);
pararg3(mm-1) = pararg3(mm);
qualifier1(mm-1) = qualifier1(mm);
qualifier2(mm-1) = qualifier2(mm);
qualifier3(mm-1) = qualifier3(mm);
}
NbrSol--;
}
}
}
}

View File

@@ -0,0 +1,249 @@
// File GccAna_Circ2d3Tan.cxx_5, REG 08/07/91
// init. de MinRad et MaxRad (PRO15604), JCT 09/10/98
#include <GccAna_Circ2d3Tan.jxx>
#include <ElCLib.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccAna_CircLin2dBisec.hxx>
#include <GccAna_LinPnt2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BLine.hxx>
#include <GccInt_BParab.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Creation d un cercle tangent a un cercle, une droite et un point. +
//=========================================================================
GccAna_Circ2d3Tan::
GccAna_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 ,
const GccEnt_QualifiedLin& Qualified2 ,
const gp_Pnt2d& Point3 ,
const Standard_Real Tolerance ):
//=========================================================================
// Initialisation des champs. +
//=========================================================================
cirsol(1,4) ,
qualifier1(1,4) ,
qualifier2(1,4) ,
qualifier3(1,4) ,
TheSame1(1,4) ,
TheSame2(1,4) ,
TheSame3(1,4) ,
pnttg1sol(1,4) ,
pnttg2sol(1,4) ,
pnttg3sol(1,4) ,
par1sol(1,4) ,
par2sol(1,4) ,
par3sol(1,4) ,
pararg1(1,4) ,
pararg2(1,4) ,
pararg3(1,4)
{
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
Standard_Real MaxRad = 1e10, MinRad = 1e-6;
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
//=========================================================================
// Traitement. +
//=========================================================================
gp_Circ2d C1(Qualified1.Qualified());
gp_Lin2d L2(Qualified2.Qualified());
Standard_Real R1 = C1.Radius();
gp_Pnt2d center1(C1.Location());
gp_Pnt2d origin2(L2.Location());
gp_Dir2d dir2(L2.Direction());
gp_Dir2d normL2(-dir2.Y(),dir2.X());
TColStd_Array1OfReal Radius(1,2);
GccAna_CircLin2dBisec Bis1(C1,L2);
GccAna_LinPnt2dBisec Bis2(L2,Point3);
if (Bis1.IsDone() && Bis2.IsDone()) {
Standard_Integer nbsolution1 = Bis1.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution1; i++) {
Handle(GccInt_Bisec) Sol1 = Bis1.ThisSolution(i);
Handle(GccInt_Bisec) Sol2 = Bis2.ThisSolution();
GccInt_IType typ1 = Sol1->ArcType();
GccInt_IType typ2 = Sol2->ArcType();
IntAna2d_AnaIntersection Intp;
if (typ1 == GccInt_Lin) {
if (typ2 == GccInt_Lin) {
Intp.Perform(Sol1->Line(),Sol2->Line());
}
else if (typ2 == GccInt_Par) {
Intp.Perform(Sol1->Line(),IntAna2d_Conic(Sol2->Parabola()));
}
}
else if (typ1 == GccInt_Par) {
if (typ2 == GccInt_Lin) {
Intp.Perform(Sol2->Line(),IntAna2d_Conic(Sol1->Parabola()));
}
else if (typ2 == GccInt_Par) {
Intp.Perform(Sol1->Parabola(),IntAna2d_Conic(Sol2->Parabola()));
}
}
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = Center.Distance(C1.Location());
Standard_Real dist2 = L2.Distance(Center);
Standard_Real dist3 = Center.Distance(Point3);
Standard_Integer nbsol1 = 0;
Standard_Integer nbsol2 = 0;
Standard_Integer nbsol3 = 0;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if (dist1-R1 < Tolerance) {
Radius(1) = Abs(R1-dist1);
nbsol1 = 1;
ok = Standard_True;
}
}
else if (Qualified1.IsOutside()) {
if (R1-dist1 < Tolerance) {
Radius(1) = Abs(R1-dist1);
nbsol1 = 1;
ok = Standard_True;
}
}
else if (Qualified1.IsEnclosing()) {
ok = Standard_True;
nbsol1 = 1;
Radius(1) = Abs(R1-dist1);
}
else if (Qualified1.IsUnqualified()) {
ok = Standard_True;
nbsol1 = 2;
Radius(1) = Abs(R1-dist1);
Radius(2) = R1+dist1;
}
if (Qualified2.IsEnclosed() && ok) {
if ((((L2.Location().X()-Center.X())*(-L2.Direction().Y()))+
((L2.Location().Y()-Center.Y())*(L2.Direction().X())))<=0){
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(dist2-Radius(ii)) < Tol) {
ok = Standard_True;
nbsol2 = 1;
Radius(1) = Radius(ii);
}
}
}
}
else if (Qualified2.IsOutside() && ok) {
if ((((L2.Location().X()-Center.X())*(-L2.Direction().Y()))+
((L2.Location().Y()-Center.Y())*(L2.Direction().X())))>=0){
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(dist2-Radius(ii)) < Tol) {
ok = Standard_True;
nbsol2 = 1;
Radius(1) = Radius(ii);
}
}
}
}
else if (Qualified2.IsUnqualified() && ok) {
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
if (Abs(dist2-Radius(ii)) < Tol) {
ok = Standard_True;
nbsol2 = 1;
Radius(1) = Radius(ii);
}
}
}
if (Abs(dist3-Radius(1)) <= Tol && ok) {
ok = Standard_True;
nbsol3 = 1;
}
if (ok) {
for (Standard_Integer k = 1 ; k <= nbsol3 ; k++) {
if (NbrSol==4)
break;
// pop : si le rayon est trop grand ( qu'est trop grand : avoir ) pas de creation
if (Radius(k) > MaxRad) break;
if (Abs(Radius(k)) < MinRad) break;
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
// ==========================================================
Standard_Real distcc1 = Center.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(k)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(k)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
gp_Dir2d dc2(origin2.XY()-Center.XY());
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (dc2.Dot(normL2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
qualifier3(NbrSol) = GccEnt_noqualifier;
if (Center.Distance(C1.Location()) <= Tolerance &&
Abs(Radius(k)-R1) <= Tolerance) {
TheSame1(NbrSol) = 1;
}
else {
TheSame1(NbrSol) = 0;
// modified by NIZHNY-EAP Mon Nov 1 13:48:21 1999 ___BEGIN___
// gp_Dir2d dc(C1.Location().XY()-Center.XY());
gp_Dir2d dc(Center.XY()-C1.Location().XY());
// modified by NIZHNY-EAP Mon Nov 1 13:48:55 1999 ___END___
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
TheSame2(NbrSol) = 0;
TheSame3(NbrSol) = 0;
gp_Dir2d dc(L2.Location().XY()-Center.XY());
Standard_Real sign = dc.Dot(gp_Dir2d(-L2.Direction().Y(),
L2.Direction().X()));
dc = gp_Dir2d(sign*gp_XY(-L2.Direction().Y(),
L2.Direction().X()));
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(k)*dc.XY());
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
pnttg3sol(NbrSol) = Point3;
par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg3sol(NbrSol));
pararg3(NbrSol) = 0.;
}
}
}
}
WellDone = Standard_True;
}
if (NbrSol==4)
break;
}
}
}

View File

@@ -0,0 +1,199 @@
// File GccAna_Circ2d3Tan.cxx_6, REG 08/07/91
#include <GccAna_Circ2d3Tan.jxx>
#include <ElCLib.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <GccAna_LinPnt2dBisec.hxx>
#include <GccAna_Lin2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BLine.hxx>
#include <GccInt_BParab.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Creation d un cercle tangent a deux droites et a un point. +
//=========================================================================
GccAna_Circ2d3Tan::
GccAna_Circ2d3Tan (const GccEnt_QualifiedLin& Qualified1 ,
const GccEnt_QualifiedLin& Qualified2 ,
const gp_Pnt2d& Point3 ,
const Standard_Real Tolerance ):
cirsol(1,2) ,
qualifier1(1,2) ,
qualifier2(1,2) ,
qualifier3(1,2) ,
TheSame1(1,2) ,
TheSame2(1,2) ,
TheSame3(1,2) ,
pnttg1sol(1,2) ,
pnttg2sol(1,2) ,
pnttg3sol(1,2) ,
par1sol(1,2) ,
par2sol(1,2) ,
par3sol(1,2) ,
pararg1(1,2) ,
pararg2(1,2) ,
pararg3(1,2)
{
gp_Dir2d dirx(1.0,0.0);
WellDone = Standard_False;
Standard_Real Tol = Abs(Tolerance);
NbrSol = 0;
if (!(Qualified1.IsEnclosed() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
!(Qualified2.IsEnclosed() ||
Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
pnttg3sol.Init(Point3);
//=========================================================================
// Traitement. +
//=========================================================================
gp_Lin2d L1 = Qualified1.Qualified();
gp_Lin2d L2 = Qualified2.Qualified();
gp_Pnt2d origin1(L1.Location());
gp_Dir2d dir1(L1.Direction());
gp_Dir2d normL1(-dir1.Y(),dir1.X());
gp_Pnt2d origin2(L2.Location());
gp_Dir2d dir2(L2.Direction());
gp_Dir2d normL2(-dir2.Y(),dir2.X());
GccAna_Lin2dBisec Bis1(L1,L2);
GccAna_LinPnt2dBisec Bis2(L1,Point3);
if (Bis1.IsDone() && Bis2.IsDone()) {
Standard_Integer nbsolution1 = Bis1.NbSolutions();
Handle(GccInt_Bisec) Sol2 = Bis2.ThisSolution();
for (Standard_Integer i = 1 ; i <= nbsolution1; i++) {
#ifdef DEB
gp_Lin2d Sol1(Bis1.ThisSolution(i));
#else
Bis1.ThisSolution(i) ;
#endif
GccInt_IType typ2 = Sol2->ArcType();
IntAna2d_AnaIntersection Intp;
if (typ2 == GccInt_Lin) {
Intp.Perform(Bis1.ThisSolution(i),Sol2->Line());
}
else if (typ2 == GccInt_Par) {
Intp.Perform(Bis1.ThisSolution(i),IntAna2d_Conic(Sol2->Parabola()));
}
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = L1.Distance(Center);
Standard_Real dist2 = L2.Distance(Center);
Standard_Real dist3 = Center.Distance(Point3);
Standard_Real Radius=0;
Standard_Integer nbsol1 = 0;
Standard_Integer nbsol2 = 0;
Standard_Integer nbsol3 = 0;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if ((((origin1.X()-Center.X())*(-dir1.Y()))+
((origin1.Y()-Center.Y())*(dir1.X())))<=0){
ok = Standard_True;
nbsol1 = 1;
Radius = dist1;
}
}
else if (Qualified1.IsOutside()) {
if ((((origin1.X()-Center.X())*(-dir1.Y()))+
((origin1.Y()-Center.Y())*(dir1.X())))>=0){
ok = Standard_True;
nbsol1 = 1;
Radius = dist1;
}
}
else if (Qualified1.IsUnqualified()) {
ok = Standard_True;
nbsol1 = 1;
Radius = dist1;
}
if (Qualified2.IsEnclosed()) {
if ((((origin2.X()-Center.X())*(-dir2.Y()))+
((origin2.Y()-Center.Y())*(dir2.X())))<=0){
if (Abs(dist2-Radius) < Tol) { nbsol2 = 1; }
else { ok = Standard_False; }
}
}
else if (Qualified2.IsOutside() && ok) {
if ((((origin2.X()-Center.X())*(-dir2.Y()))+
((origin2.Y()-Center.Y())*(dir2.X())))>=0){
if (Abs(dist2-Radius) < Tol) { nbsol2 = 1; }
else { ok = Standard_False; }
}
}
else if (Qualified2.IsUnqualified() && ok) {
if (Abs(dist2-Radius) < Tol) { nbsol2 = 1; }
else { ok = Standard_False; }
}
if (ok) {
if (Abs(dist3-Radius) < Tol) { nbsol3 = 1; }
else { ok = Standard_False; }
}
if (ok) {
for (Standard_Integer k = 1 ; k <= nbsol3 ; k++) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
gp_Dir2d dc1(origin1.XY()-Center.XY());
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc1.Dot(normL1) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
gp_Dir2d dc2(origin2.XY()-Center.XY());
if (!Qualified2.IsUnqualified()) {
qualifier2(NbrSol) = Qualified2.Qualifier();
}
else if (dc2.Dot(normL2) > 0.0) {
qualifier2(NbrSol) = GccEnt_outside;
}
else { qualifier2(NbrSol) = GccEnt_enclosed; }
qualifier3(NbrSol) = GccEnt_noqualifier;
TheSame1(NbrSol) = 0;
gp_Dir2d dc(origin1.XY()-Center.XY());
Standard_Real sign = dc.Dot(gp_Dir2d(-dir1.Y(),dir1.X()));
dc = gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X()));
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
TheSame2(NbrSol) = 0;
dc = gp_Dir2d(origin2.XY()-Center.XY());
sign = dc.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
dc = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY());
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
TheSame3(NbrSol) = 0;
par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg3sol(NbrSol));
pararg3(NbrSol) = 0.;
}
}
}
}
WellDone = Standard_True;
}
}
}
}

View File

@@ -0,0 +1,198 @@
// File GccAna_Circ2d3Tan.cxx_7, REG 08/07/91
#include <GccAna_Circ2d3Tan.jxx>
#include <ElCLib.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <GccAna_CircPnt2dBisec.hxx>
#include <GccAna_Pnt2dBisec.hxx>
#include <GccInt_IType.hxx>
#include <GccInt_BCirc.hxx>
#include <GccInt_BLine.hxx>
#include <GccInt_BElips.hxx>
#include <GccInt_BHyper.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <Precision.hxx>
//=========================================================================
// Creation d un cercle tangent a un cercle et a deux points. +
//=========================================================================
GccAna_Circ2d3Tan::
GccAna_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 ,
const gp_Pnt2d& Point2 ,
const gp_Pnt2d& Point3 ,
const Standard_Real Tolerance ):
cirsol(1,2) ,
qualifier1(1,2) ,
qualifier2(1,2) ,
qualifier3(1,2) ,
TheSame1(1,2) ,
TheSame2(1,2) ,
TheSame3(1,2) ,
pnttg1sol(1,2) ,
pnttg2sol(1,2) ,
pnttg3sol(1,2) ,
par1sol(1,2) ,
par2sol(1,2) ,
par3sol(1,2) ,
pararg1(1,2) ,
pararg2(1,2) ,
pararg3(1,2)
{
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
//=========================================================================
// Traitement. +
//=========================================================================
gp_Circ2d C1 = Qualified1.Qualified();
Standard_Real R1 = C1.Radius();
gp_Pnt2d center1(C1.Location());
TColStd_Array1OfReal Radius(1,2);
if (Point2.IsEqual(Point3,Precision::Confusion())) {
WellDone = Standard_False;
return ;
}
GccAna_Pnt2dBisec Bis1(Point2,Point3);
GccAna_CircPnt2dBisec Bis2(C1,Point2);
if (Bis1.IsDone() && Bis2.IsDone()) {
Standard_Integer nbsolution2 = Bis2.NbSolutions();
for (Standard_Integer i = 1 ; i <= nbsolution2; i++) {
Handle(GccInt_Bisec) Sol2 = Bis2.ThisSolution(i);
GccInt_IType typ2 = Sol2->ArcType();
gp_Lin2d Sol1(Bis1.ThisSolution());
IntAna2d_AnaIntersection Intp;
if (typ2 == GccInt_Cir) {
Intp.Perform(Sol1,Sol2->Circle());
}
else if (typ2 == GccInt_Lin) {
Intp.Perform(Sol1,Sol2->Line());
}
else if (typ2 == GccInt_Hpr) {
Intp.Perform(Sol1,IntAna2d_Conic(Sol2->Hyperbola()));
}
else if (typ2 == GccInt_Ell) {
Intp.Perform(Sol1,IntAna2d_Conic(Sol2->Ellipse()));
}
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = Center.Distance(center1);
Standard_Real dist2 = Center.Distance(Point2);
Standard_Real dist3 = Center.Distance(Point3);
Standard_Integer nbsol1 = 0;
// Standard_Integer nbsol2 = 0;
Standard_Integer nbsol3 = 0;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if (dist1-R1 < Tolerance) {
Radius(1) = Abs(R1-dist1);
nbsol1 = 1;
ok = Standard_True;
}
}
else if (Qualified1.IsOutside()) {
if (R1-dist1 < Tolerance) {
Radius(1) = Abs(R1-dist1);
nbsol1 = 1;
ok = Standard_True;
}
}
else if (Qualified1.IsEnclosing()) {
ok = Standard_True;
nbsol1 = 1;
Radius(1) = R1+dist1;
}
else if (Qualified1.IsUnqualified()) {
ok = Standard_True;
nbsol1 = 2;
Radius(1) = Abs(R1-dist1);
Radius(2) = R1+dist1;
}
if (ok) {
ok = Standard_False;
for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
//pop if (Abs(dist2-Radius(ii))<=Tol && Abs(dist2-Radius(ii))<=Tol){
if (Abs(dist2-Radius(ii))<=Tol && Abs(dist3-Radius(ii))<=Tol){
nbsol3 = ii;
ok = Standard_True;
}
}
}
if (ok) {
// for (Standard_Integer k = 1 ; k <= nbsol3 ; k++) {
if (NbrSol>=2) break;
NbrSol++;
// cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(nbsol3));
// ==========================================================
Standard_Real distcc1 = Center.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius(nbsol3)-R1) < Tol) {
qualifier1(NbrSol) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius(nbsol3)) < Tol) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosing; }
qualifier2(NbrSol) = GccEnt_noqualifier;
qualifier3(NbrSol) = GccEnt_noqualifier;
if (Center.Distance(center1) <= Tolerance &&
Abs(Radius(nbsol3)-R1) <= Tolerance) {
TheSame1(NbrSol) = 1;
}
else {
TheSame1(NbrSol) = 0;
gp_Dir2d dc(center1.XY()-Center.XY());
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(nbsol3)*dc.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
TheSame2(NbrSol) = 0;
pnttg2sol(NbrSol) = Point2;
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol)=0.;
TheSame3(NbrSol) = 0;
pnttg3sol(NbrSol) = Point3;
par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg3sol(NbrSol));
pararg3(NbrSol) = 0.;
//}
}
}
}
WellDone = Standard_True;
}
}
}
}

View File

@@ -0,0 +1,176 @@
// File GccAna_Circ2d3Tan.cxx, REG 08/07/91
#include <GccAna_Circ2d3Tan.jxx>
#include <ElCLib.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <GccAna_LinPnt2dBisec.hxx>
#include <GccAna_Lin2dBisec.hxx>
#include <GccAna_Pnt2dBisec.hxx>
#include <GccInt_Bisec.hxx>
#include <GccInt_IType.hxx>
#include <IntAna2d_Conic.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <Precision.hxx>
//=========================================================================
// Creation d un cercle tangent a une droite et a deux points. +
//=========================================================================
GccAna_Circ2d3Tan::
GccAna_Circ2d3Tan (const GccEnt_QualifiedLin& Qualified1,
const gp_Pnt2d& Point2 ,
const gp_Pnt2d& Point3 ,
const Standard_Real Tolerance ):
cirsol(1,2) ,
qualifier1(1,2) ,
qualifier2(1,2) ,
qualifier3(1,2) ,
TheSame1(1,2) ,
TheSame2(1,2) ,
TheSame3(1,2) ,
pnttg1sol(1,2) ,
pnttg2sol(1,2) ,
pnttg3sol(1,2) ,
par1sol(1,2) ,
par2sol(1,2) ,
par3sol(1,2) ,
pararg1(1,2) ,
pararg2(1,2) ,
pararg3(1,2)
{
WellDone = Standard_False;
Standard_Real Tol = Abs(Tolerance);
gp_Dir2d dirx(1.0,0.0);
NbrSol = 0;
if (!(Qualified1.IsEnclosed() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
//=========================================================================
// Traitement. +
//=========================================================================
gp_Lin2d L1 = Qualified1.Qualified();
gp_Pnt2d origin1(L1.Location());
gp_Dir2d dir1(L1.Direction());
gp_Dir2d normL1(-dir1.Y(),dir1.X());
if (Point2.IsEqual(Point3,Precision::Confusion())) {
WellDone = Standard_False;
return ;
}
GccAna_Pnt2dBisec Bis1(Point2,Point3);
GccAna_LinPnt2dBisec Bis2(L1,Point2);
if (Bis1.IsDone() && Bis2.IsDone()) {
gp_Lin2d linint1(Bis1.ThisSolution());
Handle(GccInt_Bisec) Sol2 = Bis2.ThisSolution();
GccInt_IType typ2 = Sol2->ArcType();
#ifdef DEB
gp_Lin2d linintb(Bis1.ThisSolution());
#else
Bis1.ThisSolution() ;
#endif
IntAna2d_AnaIntersection Intp;
if (typ2 == GccInt_Lin) {
gp_Lin2d linint2(Sol2->Line());
Intp.Perform (linint1,linint2);
}
else if (typ2 == GccInt_Par) {
Intp.Perform (linint1,IntAna2d_Conic(Sol2->Parabola()));
}
if (Intp.IsDone()) {
if ((!Intp.IsEmpty())&&(!Intp.ParallelElements())&&
(!Intp.IdenticalElements())) {
for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
gp_Pnt2d Center(Intp.Point(j).Value());
Standard_Real dist1 = L1.Distance(Center);
Standard_Real dist2 = Center.Distance(Point2);
#ifdef DEB
Standard_Real dist3 = Center.Distance(Point3);
#else
Center.Distance(Point3);
#endif
Standard_Real Radius=0;
Standard_Integer nbsol1 = 0;
// Standard_Integer nbsol2 = 0;
Standard_Integer nbsol3 = 0;
Standard_Boolean ok = Standard_False;
if (Qualified1.IsEnclosed()) {
if ((((origin1.X()-Center.X())*(-dir1.Y()))+
((origin1.Y()-Center.Y())*(dir1.X())))<=0){
ok = Standard_True;
nbsol1 = 1;
Radius = dist1;
}
}
else if (Qualified1.IsOutside()) {
if ((((origin1.X()-Center.X())*(-dir1.Y()))+
((origin1.Y()-Center.Y())*(dir1.X())))>=0){
ok = Standard_True;
nbsol1 = 1;
Radius = dist1;
}
}
else if (Qualified1.IsUnqualified()) {
ok = Standard_True;
nbsol1 = 1;
Radius = dist1;
}
if (ok) {
if (Abs(dist2-Radius)<=Tol && Abs(dist2-Radius)<=Tol) {
nbsol3 = 1;
}
else { ok = Standard_False; }
}
if (ok) {
for (Standard_Integer k = 1 ; k <= nbsol3 ; k++) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
gp_Dir2d dc1(origin1.XY()-Center.XY());
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc1.Dot(normL1) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
qualifier2(NbrSol) = GccEnt_noqualifier;
qualifier3(NbrSol) = GccEnt_noqualifier;
TheSame1(NbrSol) = 0;
gp_Dir2d dc(origin1.XY()-Center.XY());
Standard_Real sign = dc.Dot(gp_Dir2d(-dir1.Y(),dir1.X()));
dc = gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X()));
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
TheSame2(NbrSol) = 0;
pnttg2sol(NbrSol) = Point2;
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg2sol(NbrSol));
pararg2(NbrSol) = 0.;
TheSame3(NbrSol) = 0;
pnttg3sol(NbrSol) = Point3;
par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg3sol(NbrSol));
pararg3(NbrSol) = 0.;
}
}
}
}
WellDone = Standard_True;
}
}
}

View File

@@ -0,0 +1,144 @@
// File GccAna_Circ2d3Tan.cxx_9, REG 08/07/91
#include <GccAna_Circ2d3Tan.jxx>
#include <ElCLib.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <GccAna_Lin2dBisec.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Creation d un cercle passant par trois points. +
// Trois cas de figures : +
// 1/ Les trois points sont confondus. +
// ----------------------------------- +
// Le resultat est le cercle centre en Point1 de rayon zero. +
// 2/ Deux des trois points sont confondus. +
// ---------------------------------------- +
// On cree la mediatrice a deux points non confondus ainsi que la +
// droite passant par ces deux points. +
// La solution a pour centre l intersection de ces deux droite et +
// pour rayon la distance entre ce centre et l un des trois points. +
// 3/ Les trois points sont distinct. +
// ---------------------------------- +
//
//=========================================================================
GccAna_Circ2d3Tan::
GccAna_Circ2d3Tan (const gp_Pnt2d& Point1 ,
const gp_Pnt2d& Point2 ,
const gp_Pnt2d& Point3 ,
const Standard_Real Tolerance ):
//=========================================================================
// Initialisation des champs. +
//=========================================================================
cirsol(1,1) ,
qualifier1(1,1) ,
qualifier2(1,1) ,
qualifier3(1,1) ,
TheSame1(1,1) ,
TheSame2(1,1) ,
TheSame3(1,1) ,
pnttg1sol(1,1) ,
pnttg2sol(1,1) ,
pnttg3sol(1,1) ,
par1sol(1,1) ,
par2sol(1,1) ,
par3sol(1,1) ,
pararg1(1,1) ,
pararg2(1,1) ,
pararg3(1,1)
{
gp_Dir2d dirx(1.0,0.0);
WellDone = Standard_False;
NbrSol = 0;
//=========================================================================
// Traitement. +
//=========================================================================
Standard_Real dist1 = Point1.Distance(Point2);
Standard_Real dist2 = Point1.Distance(Point3);
Standard_Real dist3 = Point2.Distance(Point3);
qualifier1(1) = GccEnt_noqualifier;
qualifier2(1) = GccEnt_noqualifier;
qualifier3(1) = GccEnt_noqualifier;
if ((dist1 < Tolerance) && (dist2 < Tolerance) && (dist3 < Tolerance)) {
NbrSol++;
WellDone = Standard_True;
cirsol(1) = gp_Circ2d(gp_Ax2d(Point1,dirx),0.0);
// ===============================================
TheSame1(1) = 0;
TheSame2(1) = 0;
TheSame3(1) = 0;
pnttg1sol(1) = Point1;
pnttg2sol(1) = Point2;
pnttg3sol(1) = Point3;
par1sol(1) =0.0;
par2sol(1) =0.0;
par3sol(1) =0.0;
pararg1(1) =0.0;
pararg2(1) =0.0;
pararg3(1) =0.0;
}
else {
gp_Lin2d L1;
gp_Lin2d L2;
if (dist1 >= Tolerance) {
L1 = gp_Lin2d(gp_Pnt2d((Point1.XY()+Point2.XY())/2.0),
gp_Dir2d(Point1.Y()-Point2.Y(),Point2.X()-Point1.X()));
}
if (dist2 >= Tolerance) {
L2 = gp_Lin2d(gp_Pnt2d((Point1.XY()+Point3.XY())/2.0),
gp_Dir2d(Point1.Y()-Point3.Y(),Point3.X()-Point1.X()));
}
if (dist2 <= Tolerance) {
L2 = gp_Lin2d(Point1,
gp_Dir2d(Point1.Y()-Point2.Y(),Point2.X()-Point1.X()));
}
else if (dist1 <= Tolerance) {
L1 = gp_Lin2d(Point1,
gp_Dir2d(Point1.Y()-Point3.Y(),Point3.X()-Point1.X()));
}
else if (dist3 <= Tolerance) {
L2 = gp_Lin2d(Point1,
gp_Dir2d(Point1.Y()-Point2.Y(),Point2.X()-Point1.X()));
}
IntAna2d_AnaIntersection Intp(L1,L2);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Intp.Point(i).Value(),dirx),
// ===============================================================
Point1.Distance(Intp.Point(i).Value()));
// =======================================
TheSame1(NbrSol) = 0;
TheSame2(NbrSol) = 0;
TheSame3(NbrSol) = 0;
pnttg1sol(NbrSol) = Point1;
pnttg2sol(NbrSol) = Point2;
pnttg3sol(NbrSol) = Point3;
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg3sol(NbrSol));
pararg1(NbrSol) =0.0;
pararg2(NbrSol) =0.0;
pararg3(NbrSol) =0.0;
}
}
WellDone = Standard_True;
}
}
}

View File

@@ -0,0 +1,84 @@
-- File: Circ2dBisec.cdl
-- Created: Wed Apr 3 11:29:37 1991
-- Author: Remi GILET
-- <reg@topsn2>
---Copyright: Matra Datavision 1991
class Circ2dBisec
from GccAna
---Purpose: This class describes functions for building bisecting curves between two 2D circles.
-- A bisecting curve between two circles is a curve such
-- that each of its points is at the same distance from the
-- two circles. It can be an ellipse, hyperbola, circle or line,
-- depending on the relative position of the two circles.
-- The algorithm computes all the elementary curves which
-- are solutions. There is no solution if the two circles are coincident.
-- A Circ2dBisec object provides a framework for:
-- - defining the construction of the bisecting curves,
-- - implementing the construction algorithm, and consulting the result.
uses Circ2d from gp,
Bisec from GccInt
raises OutOfRange from Standard,
NotDone from StdFail
is
Create(Circ1,Circ2 : Circ2d from gp) returns Circ2dBisec;
---Purpose: Constructs bisecting curves between the two circles Circ1 and Circ2.
IsDone(me) returns Boolean from Standard
is static;
---Purpose: This method returns True if the construction algorithm succeeded.
NbSolutions(me) returns Integer from Standard
---Purpose: This method returns the number of solutions.
-- Raises NotDone if the construction algorithm didn't succeed.
raises NotDone
is static;
ThisSolution(me ;
Index : Integer from Standard) returns Bisec from GccInt
---Purpose: Returns the solution number Index
-- Raises OutOfRange exception if Index is greater than
-- the number of solutions.
-- It raises NotDone if the construction algorithm
-- didn't succeed.
raises OutOfRange, NotDone
is static;
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose: The number of possible solutions.
intersection : Integer from Standard;
---Purpose: c is the circle which has the lowest radius among Circ1 and
-- Circ2, and C is the other one.
-- intersection = 0 if c is completly inside C.
-- intersection = 1 if c is tangent to C and c is inside C.
-- intersection = 2 if c intersects C.
-- intersection = 3 if c is tangent to C and c is outside C.
-- intersection = 4 if c is completly outside C.
sameradius : Boolean from Standard;
---Purpose: sameradius is true is Circ1 has the same radius as Circ2.
circle1 : Circ2d from gp;
---Purpose: The first argument used for ThisSolution. It is the circle
-- which has the greatest radius or Circ1 if Circ1 and Circ2
-- has the same radius.
circle2 : Circ2d from gp;
---Purpose: The second argument used for ThisSolution. It is the other
-- circle.
end Circ2dBisec;

332
src/GccAna/GccAna_Circ2dBisec.cxx Executable file
View File

@@ -0,0 +1,332 @@
// File: GccAna_Circ2dBisec.cxx
// Created: Mon Oct 7 16:17:54 1991
// Author: Remi GILET
// <reg@phobox>
//=========================================================================
// CREATION DE LA BISSECTICE ENTRE DEUX CERCLES. +
//=========================================================================
#include <GccAna_Circ2dBisec.ixx>
#include <gp_XY.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Hypr2d.hxx>
#include <gp.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_OutOfRange.hxx>
#include <GccInt_BParab.hxx>
#include <GccInt_BLine.hxx>
#include <GccInt_BElips.hxx>
#include <GccInt_BCirc.hxx>
#include <GccInt_BHyper.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <StdFail_NotDone.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <Precision.hxx>
//=========================================================================
GccAna_Circ2dBisec::
GccAna_Circ2dBisec (const gp_Circ2d& Circ1 ,
const gp_Circ2d& Circ2 ) {
//=========================================================================
// Initialisation des champs : +
// - circle1 (Cercle : premier argument.) +
// - circle2 (Ligne : deuxieme argument.) +
// - intersection (Entier indiquant la position du plus petit +
// des deux cercles par rapport a l autre.) +
// - sameradius (Booleen indiquant si les deux cercles ont +
// meme rayon ou non.) +
// - NbrSol (Entier indiquant le nombre de solutions.) +
// - WellDone (Booleen indiquant le succes ou non de l algo.). +
//=========================================================================
WellDone = Standard_False;
Standard_Real Tol=Precision::Confusion();
Standard_Real R1 = Circ1.Radius();
Standard_Real R2 = Circ2.Radius();
if (Abs(R1-R2) <= Tol) { sameradius = Standard_True; }
else { sameradius = Standard_False; }
if (R1 < R2) {
circle1 = gp_Circ2d(Circ2);
circle2 = gp_Circ2d(Circ1);
R1 = circle1.Radius();
R2 = circle2.Radius();
}
else {
circle1 = gp_Circ2d(Circ1);
circle2 = gp_Circ2d(Circ2);
}
Standard_Real dist = circle2.Location().Distance(circle1.Location());
if (R1-dist-R2 > Tol) {
intersection = 0;
NbrSol = 2;
WellDone = Standard_True;
}
else if (Abs(R1-dist-R2) <= Tol) {
intersection = 1;
if (sameradius) {
NbrSol = 0;
WellDone = Standard_True;
}
else {
NbrSol = 2;
WellDone = Standard_True;
}
}
else if ((dist+R2-R1 > Tol) && (R1-dist+R2 > Tol)) {
intersection = 2;
if (sameradius) {
NbrSol = 2;
WellDone = Standard_True;
}
else {
NbrSol = 3;
WellDone = Standard_True;
}
}
else if (Abs(R1-dist+R2) <= Tol) {
intersection = 3;
if (sameradius) {
NbrSol = 2;
WellDone = Standard_True;
}
else {
NbrSol = 3;
WellDone = Standard_True;
}
}
else {
intersection = 4;
if (sameradius) {
NbrSol = 3;
WellDone = Standard_True;
}
else {
NbrSol = 4;
WellDone = Standard_True;
}
}
}
//=========================================================================
// Traitement. +
// On recupere les coordonees des centres des cercles circle1 et circle2 +
// (xcencir1, ycencir1, xcencir2, ycencir2). +
// On recupere aussi les rayons des deux cercles R1 et R2. +
//=========================================================================
Handle(GccInt_Bisec) GccAna_Circ2dBisec::
ThisSolution (const Standard_Integer Index) const {
Standard_Real Tol = 1.e-14;
Handle(GccInt_Bisec) bissol;
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 || Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
Standard_Real xcencir1 = circle1.Location().X();
Standard_Real ycencir1 = circle1.Location().Y();
Standard_Real xcencir2 = circle2.Location().X();
Standard_Real ycencir2 = circle2.Location().Y();
Standard_Real dist = circle1.Location().Distance(circle2.Location());
gp_Pnt2d pcen((xcencir1+xcencir2)/2.0,(ycencir1+ycencir2)/2.0);
gp_Dir2d dircen,medcen;
if (dist > Tol) {
dircen.SetCoord(xcencir2-xcencir1,ycencir2-ycencir1);
medcen.SetCoord(ycencir2-ycencir1,xcencir1-xcencir2);
}
gp_Dir2d dirx(1.0,0.0);
gp_Ax2d acenx(pcen,dirx);
gp_Ax2d acencen(pcen,dircen);
Standard_Real R1 = circle1.Radius();
Standard_Real R2 = circle2.Radius();
if ((NbrSol == 1) && (intersection == 0)) {
Standard_Real R;
if (Index == 1)
R = (R1+R2)/2.0;
else
R = (R1-R2)/2.0;
gp_Circ2d C(acenx,R);
bissol = new GccInt_BCirc(C);
// =============================
}
else if ((NbrSol == 2) && (intersection == 1)) {
if (Index == 1) {
gp_Elips2d E(acencen,
(R1+R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.+R1*R2/2.));
bissol = new GccInt_BElips(E);
// =============================
}
else if (Index == 2) {
gp_Lin2d L(circle1.Location(),
dircen);
bissol = new GccInt_BLine(L);
// =============================
}
}
else if ((NbrSol == 2) && (intersection == 0)) {
if (Index == 1) {
if (Abs(xcencir2-xcencir1)<Tol && Abs(ycencir2-ycencir1)< Tol) {
gp_Circ2d C(acenx,(R1+R2)/2.0);
bissol = new GccInt_BCirc(C);
// =============================
}
else {
gp_Elips2d E(acencen,
(R1+R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.+R1*R2/2.));
bissol = new GccInt_BElips(E);
// ==============================
}
}
else if (Index == 2) {
if (Abs(xcencir2-xcencir1)< Tol && Abs(ycencir2-ycencir1)< Tol) {
gp_Circ2d C(acencen,(R1-R2)/2.);
bissol = new GccInt_BCirc(C);
// =============================
}
else {
gp_Elips2d E(acencen,
(R1-R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.-R1*R2/2.));
bissol = new GccInt_BElips(E);
// ==============================
}
}
}
else if (intersection == 2) {
if (sameradius) {
if (Index == 1) {
gp_Lin2d L(pcen,medcen);
bissol = new GccInt_BLine(L);
// =============================
}
else if (Index == 2) {
gp_Elips2d E(acencen,
R1,Sqrt(R1*R1-dist*dist/4.0));
bissol = new GccInt_BElips(E);
// ==============================
}
}
else {
if (Index == 1) {
gp_Hypr2d H1;
H1 = gp_Hypr2d(acencen,
(R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
bissol = new GccInt_BHyper(H1);
// ===============================
}
else if (Index == 2) {
gp_Hypr2d H1(acencen,
(R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
bissol = new GccInt_BHyper(H1.OtherBranch());
// ===============================
}
else if (Index == 3) {
gp_Elips2d E(acencen,
(R1+R2)/2.0,Sqrt((R1*R1+R2*R2-dist*dist)/4.+R1*R2/2.));
bissol = new GccInt_BElips(E);
// ==============================
}
}
}
else if (intersection == 3) {
if (sameradius) {
if (Index == 1) {
gp_Lin2d L(pcen, dircen);
bissol = new GccInt_BLine(L);
// =============================
}
else if (Index == 2) {
gp_Lin2d L(pcen, medcen);
bissol = new GccInt_BLine(L);
// =============================
}
}
else {
if (Index == 1) {
gp_Lin2d L(pcen, dircen);
bissol = new GccInt_BLine(L);
// =============================
}
else if (Index == 2) {
gp_Hypr2d H1(acencen,
(R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
bissol = new GccInt_BHyper(H1);
// ===============================
}
else if (Index == 3) {
gp_Hypr2d H1(acencen,
(R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
bissol = new GccInt_BHyper(H1.OtherBranch());
// ===============================
}
}
}
else if (intersection == 4) {
if (sameradius) {
if (Index == 1) {
gp_Lin2d L(pcen,medcen);
bissol = new GccInt_BLine(L);
// =============================
}
else if (Index == 2) {
gp_Hypr2d H1(acencen,R1,Sqrt(dist*dist-4*R1*R1)/2.0);
bissol = new GccInt_BHyper(H1);
// ===============================
}
else if (Index == 3) {
gp_Hypr2d H1(acencen,R1,Sqrt(dist*dist-4*R1*R1)/2.0);
bissol = new GccInt_BHyper(H1.OtherBranch());
// ===============================
}
}
else {
if (Index == 1) {
gp_Hypr2d H1(acencen,
(R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
bissol = new GccInt_BHyper(H1);
// ===============================
}
else if (Index == 2) {
gp_Hypr2d H1(acencen,
(R1-R2)/2.0,Sqrt(dist*dist-(R1-R2)*(R1-R2))/2.0);
bissol = new GccInt_BHyper(H1.OtherBranch());
// ===============================
}
else if (Index == 3) {
gp_Hypr2d H1(acencen,
(R1+R2)/2.0,Sqrt(dist*dist-(R1+R2)*(R1+R2))/2.0);
bissol = new GccInt_BHyper(H1);
// ===============================
}
else if (Index == 4) {
gp_Hypr2d H1(acencen,
(R1+R2)/2.0,Sqrt(dist*dist-(R1+R2)*(R1+R2))/2.0);
bissol = new GccInt_BHyper(H1.OtherBranch());
// ===============================
}
}
}
}
return bissol;
}
//=========================================================================
Standard_Boolean GccAna_Circ2dBisec::
IsDone () const { return WellDone; }
Standard_Integer GccAna_Circ2dBisec::NbSolutions () const
{
if (!WellDone) StdFail_NotDone::Raise();
return NbrSol;
}

View File

@@ -0,0 +1,186 @@
-- File: Circ2dTanCen.cdl
-- Created: Mon Mar 18 16:08:05 1991
-- Author: Remi GILET
-- <reg@topsn3>
---Copyright: Matra Datavision 1991
class Circ2dTanCen
from GccAna
---Purpose: This class implements the algorithms used to
-- create 2d circles tangent to an entity and
-- centered on a point.
-- The arguments of all construction methods are :
-- - The qualified element for the tangency constrains
-- (QualifiedCirc, Line, Point).
-- - The center point Pcenter.
-- - A real Tolerance.
-- Tolerance is only used in the limits cases.
-- For example :
-- We want to create a circle tangent to an EnclosedCirc C1
-- with a tolerance Tolerance.
-- If we did not used Tolerance it is impossible to
-- find a solution in the the following case : Pcenter is
-- outside C1.
-- With Tolerance we will give a solution if the distance
-- between C1 and Pcenter is lower than or equal Tolerance.
uses Pnt2d from gp,
Lin2d from gp,
Circ2d from gp,
QualifiedCirc from GccEnt,
Array1OfReal from TColStd,
Array1OfInteger from TColStd,
Array1OfCirc2d from TColgp,
Array1OfPnt2d from TColgp,
Position from GccEnt,
Array1OfPosition from GccEnt
raises NegativeValue from Standard,
OutOfRange from Standard,
NotDone from StdFail,
BadQualifier from GccEnt
is
Create( Qualified1 : QualifiedCirc from GccEnt ;
Pcenter : Pnt2d from gp ;
Tolerance : Real from Standard) returns Circ2dTanCen
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to a circle and
-- centered on a point.
raises BadQualifier from GccEnt;
Create( Linetan : Lin2d from gp ;
Pcenter : Pnt2d from gp ) returns Circ2dTanCen;
---Purpose: This method implements the algorithms used to
-- create 2d circles tangent to a line and
-- centered on a point.
Create( Point1 : Pnt2d from gp ;
Pcenter : Pnt2d from gp ) returns Circ2dTanCen;
---Purpose: This method implements the algorithms used to
-- create 2d circles passing thrue a point and
-- centered on a point.
-- Tolerance is a tolerance criterion used by the algorithm
-- to find a solution when, mathematically, the problem
-- posed does not have a solution, but where there is
-- numeric uncertainty attached to the arguments.
-- In these algorithms Tolerance is only used in very
-- specific cases where the center of the solution is very
-- close to the circle to which it is tangential, and where the
-- solution is therefore a very small circle.
-- Exceptions
-- GccEnt_BadQualifier if a qualifier is inconsistent with
-- the argument it qualifies (for example, enclosing for a line).
IsDone(me) returns Boolean from Standard
is static;
---Purpose: This method returns True if the construction
-- algorithm succeeded.
-- Note: IsDone protects against a failure arising from a
-- more internal intersection algorithm, which has reached
-- its numeric limits.
NbSolutions(me) returns Integer from Standard
---Purpose: Returns the number of circles, representing solutions
-- computed by this algorithm and raises NotDone
-- exception if the algorithm didn't succeed.
raises NotDone
is static;
ThisSolution(me ;
Index : Integer from Standard ) returns Circ2d from gp
---Purpose: Returns the circle, representing the solution number Index and raises OutOfRange
-- exception if Index is greater than the number of solutions.
-- Be carefull: the Index is only a way to get all the
-- solutions, but is not associated to theses outside the
-- context of the algorithm-object.
-- Raises NotDone if the construction algorithm didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions or less than zer
raises OutOfRange, NotDone
is static;
WhichQualifier(me ;
Index : Integer from Standard;
Qualif1 : out Position from GccEnt )
raises OutOfRange, NotDone
is static;
---Purpose: Returns the qualifier Qualif1 of the tangency argument
-- for the solution of index Index computed by this algorithm.
-- The returned qualifier is:
-- - that specified at the start of construction when the
-- solutions are defined as enclosed, enclosing or
-- It returns the real qualifiers (the qualifiers given to the
-- constructor method in case of enclosed, enclosing and outside
-- and the qualifiers computedin case of unqualified).
Tangency1(me ;
Index : Integer from Standard;
ParSol : out Real from Standard;
ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns informations about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point PntSol
-- on the solution curv.
-- ParArg is the intrinsic parameter of the point PntArg
-- on the argument curv.
raises OutOfRange, NotDone
is static;
---Purpose: It raises NotDone if the construction algorithm
-- didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions or less than zero.
IsTheSame1(me ;
Index : Integer from Standard ) returns Boolean from Standard
---Purpose: Returns True if the solution number Index is equal to
-- the first argument.
raises OutOfRange, NotDone
is static;
---Purpose: It raises NotDone if the construction algorithm
-- didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions or less than zero.
fields
WellDone : Boolean from Standard;
-- True if the algorithm succeeded.
NbrSol : Integer from Standard;
-- The number of possible solutions. We have to decide about the
-- status of the multiple solutions...
cirsol : Array1OfCirc2d from TColgp;
---Purpose : The solutions.
qualifier1 : Array1OfPosition from GccEnt;
-- The qualifiers of the first argument.
TheSame1 : Array1OfInteger from TColStd;
-- 1 if the solution and the first argument are the same (2 circles).
-- if R1 is the radius of the first argument and Rsol the radius
-- of the solution and dist the distance between the two centers,
-- we concider the two circles are identical if R1+dist-Rsol is
-- less than Tolerance.
-- 0 in the other cases.
pnttg1sol : Array1OfPnt2d from TColgp;
-- The tangency point between the solution and the first argument on
-- the solution.
par1sol : Array1OfReal from TColStd;
-- The parameter of the tangency point between the solution and the
-- first argument on the solution.
pararg1 : Array1OfReal from TColStd;
-- The parameter of the tangency point between the solution and the first
-- argument on the first argument.
end Circ2dTanCen;

View File

@@ -0,0 +1,291 @@
// File GccAna_Circ2dTanCen.cxx, REG 08/07/91
//========================================================================
// Creation d'un cercle tangent a un element et centre en un point +
//========================================================================
#include <GccAna_Circ2dTanCen.ixx>
#include <ElCLib.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Lin2d.hxx>
#include <gp.hxx>
#include <gp_Dir2d.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
#include <GccEnt_BadQualifier.hxx>
//========================================================================
// Creation d'un cercle tangent a un cercle centre en un point. +
// - On calcule la distance entre le centre du cercle et le point de +
// centre : dist +
// - On verifie que cette distance est compatible avec le qualifieur +
// du cercle. +
// Si oui le rayon de la solution sera : +
// C1.Radius()-dist si le qualifieur est Enclosed. +
// C1.Radius()+dist si le qualifieur est Enclosing. +
// dist-C1.Radius() si le qualifieur est Outside. +
// un melange de ces valeurs si le qualifieur est Unqualified. +
//========================================================================
GccAna_Circ2dTanCen::
GccAna_Circ2dTanCen (const GccEnt_QualifiedCirc& Qualified1,
const gp_Pnt2d& Pcenter ,
const Standard_Real Tolerance ):
//========================================================================
// Initialisation des champs. +
//========================================================================
cirsol(1,2) ,
qualifier1(1,2) ,
TheSame1(1,2) ,
pnttg1sol(1,2),
par1sol(1,2),
pararg1(1,2)
{
NbrSol = 0;
Standard_Real Radius = 0.0;
WellDone = Standard_False;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
gp_Circ2d C1 = Qualified1.Qualified();
Standard_Real R1 = C1.Radius();
gp_Pnt2d center1(C1.Location());
Standard_Real dist;
Standard_Integer signe = 0;
Standard_Integer signe1 = 0;
if (!Qualified1.IsUnqualified()) {
dist = Pcenter.Distance(center1);
if (Qualified1.IsEnclosed()) {
// ============================
if (dist-R1 <= Tol) {
Radius = Abs(R1-dist);
signe = 1;
}
else { WellDone = Standard_True; }
}
else if (Qualified1.IsEnclosing()) {
// =================================
Radius = R1+dist;
signe = -1;
}
else if (Qualified1.IsOutside()) {
// ===============================
if (dist < R1-Tol) { WellDone = Standard_True; }
else {
Radius = Abs(R1-dist);
signe = -1;
}
}
if (signe != 0) {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),Radius);
// ========================================================
qualifier1(NbrSol) = Qualified1.Qualifier();
if (dist <= gp::Resolution()) { TheSame1(NbrSol) = 1; }
else {
TheSame1(NbrSol) = 0;
gp_Dir2d d(Pcenter.X()-center1.X(),Pcenter.Y()-center1.Y());
pnttg1sol(NbrSol) = gp_Pnt2d(Pcenter.XY()+signe*Radius*d.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
WellDone = Standard_True;
}
}
else {
// ====
dist = Pcenter.Distance(center1);
if (dist >= gp::Resolution()) {
signe = 1;
for (Standard_Integer i = 1; i <= 2 ; i++) {
signe = -signe;
if (R1-dist <= 0.) {
signe1 = -1;
}
else {
signe1 = -signe;
}
Radius = Abs(R1+signe*dist);
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),Radius);
// ========================================================
Standard_Real distcc1 = Pcenter.Distance(center1);
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; }
TheSame1(NbrSol) = 0;
WellDone = Standard_True;
gp_Dir2d d(Pcenter.X()-center1.X(),Pcenter.Y()-center1.Y());
pnttg1sol(NbrSol) = gp_Pnt2d(Pcenter.XY()+signe1*Radius*d.XY());
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
}
}
else {
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(C1);
// ==============================
qualifier1(1) = Qualified1.Qualifier();
TheSame1(NbrSol) = 1;
WellDone = Standard_True;
}
}
}
//=========================================================================
// Cercle tangent a une ligne Linetan et centre en un point Pcenter. +
// On calcule la distance du point a la ligne ==> Rayon. +
// On cree le cercle de centre Pcenter de rayon Rayon. +
//=========================================================================
GccAna_Circ2dTanCen::
GccAna_Circ2dTanCen (const gp_Lin2d& Linetan ,
const gp_Pnt2d& Pcenter ):
//=========================================================================
// Initialisation des champs. +
//=========================================================================
cirsol(1,1) ,
qualifier1(1,1),
TheSame1(1,1) ,
pnttg1sol(1,1),
par1sol(1,1),
pararg1(1,1)
{
gp_Dir2d dirx(1.0,0.0);
Standard_Real rayon = Linetan.Distance(Pcenter);
cirsol(1) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),rayon);
// ==================================================
qualifier1(1) = GccEnt_noqualifier;
TheSame1(1) = 0;
Standard_Real xloc = Linetan.Location().X();
Standard_Real yloc = Linetan.Location().Y();
Standard_Real xdir = Linetan.Direction().X();
Standard_Real ydir = Linetan.Direction().Y();
if (gp_Dir2d(xloc-Pcenter.X(),yloc-Pcenter.Y())
.Dot(gp_Dir2d(-ydir,xdir)) > 0.0) {
pnttg1sol(1) = gp_Pnt2d(Pcenter.XY()+rayon*gp_XY(-ydir,xdir));
par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
pararg1(1)=ElCLib::Parameter(Linetan,pnttg1sol(1));
}
else {
pnttg1sol(1) = gp_Pnt2d(Pcenter.XY()+rayon*gp_XY(ydir,-xdir));
par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
pararg1(1)=ElCLib::Parameter(Linetan,pnttg1sol(1));
}
NbrSol = 1;
WellDone = Standard_True;
}
//=========================================================================
// Cercle tangent a un point Point1 et centre en un point Pcenter. +
// On calcule la distance de Pcenter a Point1 ==> Rayon. +
// On cree le cercle de centre Pcenter de rayon Rayon. +
//=========================================================================
GccAna_Circ2dTanCen::
GccAna_Circ2dTanCen (const gp_Pnt2d& Point1 ,
const gp_Pnt2d& Pcenter ):
//=========================================================================
// Initialisation des champs. +
//=========================================================================
cirsol(1,1) ,
qualifier1(1,1),
TheSame1(1,1) ,
pnttg1sol(1,1),
par1sol(1,1) ,
pararg1(1,1)
{
gp_Dir2d dirx(1.0,0.0);
Standard_Real rayon = Point1.Distance(Pcenter);
cirsol(1) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),rayon);
// =================================================
qualifier1(1) = GccEnt_noqualifier;
TheSame1(1) = 0;
pnttg1sol(1) = Point1;
par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
pararg1(1) = 0.0;
NbrSol = 1;
WellDone = Standard_True;
}
//=========================================================================
Standard_Boolean GccAna_Circ2dTanCen::
IsDone () const { return WellDone; }
Standard_Integer GccAna_Circ2dTanCen::
NbSolutions () const { return NbrSol; }
gp_Circ2d GccAna_Circ2dTanCen::
ThisSolution (const Standard_Integer Index) const
{
if (Index > NbrSol || Index <= 0) { Standard_OutOfRange::Raise(); }
return cirsol(Index);
}
void GccAna_Circ2dTanCen::
WhichQualifier(const Standard_Integer Index ,
GccEnt_Position& Qualif1 ) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
Qualif1 = qualifier1(Index);
}
}
void GccAna_Circ2dTanCen::
Tangency1 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
if (TheSame1(Index) == 0) {
PntSol = gp_Pnt2d(pnttg1sol(Index));
ParSol = par1sol(Index);
ParArg = pararg1(Index);
}
else { StdFail_NotDone::Raise(); }
}
}
Standard_Boolean GccAna_Circ2dTanCen::
IsTheSame1 (const Standard_Integer Index) const
{
if (!WellDone)
StdFail_NotDone::Raise();
if (Index <= 0 ||Index > NbrSol)
Standard_OutOfRange::Raise();
if (TheSame1(Index) == 0)
return Standard_False;
return Standard_True;
}

View File

@@ -0,0 +1,263 @@
-- File: Circ2dTanOnRad.cdl
-- Created: Fri Mar 22 11:45:45 1991
-- Author: Philippe DAUTRY
-- <fid@phobox>
---Copyright: Matra Datavision 1991
class Circ2dTanOnRad
from GccAna
---Purpose: This class implements the algorithms used to
-- create a 2d circle tangent to a 2d entity,
-- centered on a curv and with a given radius.
-- The arguments of all construction methods are :
-- - The qualified element for the tangency constrains
-- (QualifiedCirc, QualifiedLin, Points).
-- - The Center element (circle, line).
-- - A real Tolerance.
-- Tolerance is only used in the limits cases.
-- For example :
-- We want to create a circle tangent to an OutsideCirc C1
-- centered on a line OnLine with a radius Radius and with
-- a tolerance Tolerance.
-- If we did not use Tolerance it is impossible to
-- find a solution in the the following case : OnLine is
-- outside C1. There is no intersection point between C1
-- and OnLine. The distance between the line and the
-- circle is greater than Radius.
-- With Tolerance we will give a solution if the
-- distance between C1 and OnLine is lower than or
-- equal Tolerance.
--inherits Storable from Standard
uses Pnt2d from gp,
Lin2d from gp,
Circ2d from gp,
QualifiedCirc from GccEnt,
QualifiedLin from GccEnt,
Array1OfReal from TColStd,
Array1OfInteger from TColStd,
Array1OfCirc2d from TColgp,
Array1OfPnt2d from TColgp,
Position from GccEnt,
Array1OfPosition from GccEnt
raises NegativeValue from Standard,
OutOfRange from Standard,
NotDone from StdFail,
BadQualifier from GccEnt
is
---Category: On a line ................................................
Create(Qualified1 : QualifiedCirc from GccEnt ;
OnLine : Lin2d from gp ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2dTanOnRad
---Purpose: This methods implements the algorithms used to create
-- 2d Circles tangent to a circle and centered on a 2d Line
-- with a given radius.
-- Tolerance is used to find solution in every limit cases.
-- For example Tolerance is used in the case of EnclosedCirc when
-- Radius-R1+dist is greater Tolerance (dist is the distance
-- between the line and the location of the circ, R1 is the
-- radius of the circ) because there is no solution.
raises NegativeValue, BadQualifier;
---Purpose: raises NegativeValue in case of NegativeRadius.
Create(Qualified1 : QualifiedLin from GccEnt ;
OnLine : Lin2d from gp ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2dTanOnRad
---Purpose: This methods implements the algorithms used to create
-- 2d Circles tangent to a 2d Line and centered on a 2d Line
-- with a given radius.
-- Tolerance is used to find solution in every limit cases.
raises NegativeValue, BadQualifier;
---Purpose: raises NegativeValue in case of NegativeRadius.
Create(Point1 : Pnt2d from gp ;
OnLine : Lin2d from gp ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2dTanOnRad
---Purpose: This methods implements the algorithms used to create
-- 2d Circles passing through a 2d Point and centered on a
-- 2d Line with a given radius.
-- Tolerance is used to find solution in every limit cases.
raises NegativeValue;
-- raises NegativeValue in case of NegativeRadius.
---Category: On a circle ................................................
Create(Qualified1 : QualifiedCirc from GccEnt ;
OnCirc : Circ2d from gp ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2dTanOnRad
---Purpose: This methods implements the algorithms used to create
-- 2d Circles tangent to a circle and centered on a 2d Circle
-- with a given radius.
-- Tolerance is used to find solution in every limit cases.
raises NegativeValue, BadQualifier;
---Purpose: raises NegativeValue in case of NegativeRadius.
Create(Qualified1 : QualifiedLin from GccEnt ;
OnCirc : Circ2d from gp ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2dTanOnRad
---Purpose: This methods implements the algorithms used to create
-- 2d Circles tangent to a 2d Line and centered on a 2d Line
-- with a given radius.
-- Tolerance is used to find solution in every limit cases.
raises NegativeValue, BadQualifier;
---Purpose: raises NegativeValue in case of NegativeRadius.
Create(Point1 : Pnt2d from gp ;
OnCirc : Circ2d from gp ;
Radius : Real from Standard;
Tolerance : Real from Standard) returns Circ2dTanOnRad
---Purpose: This methods implements the algorithms used to create
-- 2d Circles passing through a 2d Point and centered on a
-- 2d Line with a given radius.
-- Tolerance is used to find solution in every limit cases.
raises NegativeValue;
---Purpose: raises NegativeValue in case of NegativeRadius.
-- -- ....................................................................
IsDone(me) returns Boolean from Standard
is static;
---Purpose: Returns true if the construction algorithm does not fail
-- (even if it finds no solution).
-- Note: IsDone protects against a failure arising from a
-- more internal intersection algorithm, which has
-- reached its numeric limits.
NbSolutions(me) returns Integer from Standard
---Purpose: This method returns the number of circles, representing solutions.
-- Raises NotDone if the construction algorithm didn't succeed.
raises NotDone
is static;
ThisSolution(me ;
Index : Integer from Standard) returns Circ2d from gp
---Purpose: Returns the solution number Index and raises OutOfRange
-- exception if Index is greater than the number of solutions.
-- Be careful: the Index is only a way to get all the
-- solutions, but is not associated to theses outside the
-- context of the algorithm-object.
-- Raises NotDone if the construction algorithm didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions
raises OutOfRange, NotDone
is static;
WhichQualifier(me ;
Index : Integer from Standard;
Qualif1 : out Position from GccEnt )
raises OutOfRange, NotDone
is static;
---Purpose: Returns the qualifier Qualif1 of the tangency argument
-- for the solution of index Index computed by this algorithm.
-- The returned qualifier is:
-- - that specified at the start of construction when the
-- solutions are defined as enclosed, enclosing or
-- outside with respect to the argument, or
-- - that computed during construction (i.e. enclosed,
-- enclosing or outside) when the solutions are defined
-- as unqualified with respect to the argument, or
-- - GccEnt_noqualifier if the tangency argument is a point.
-- Exceptions
-- Standard_OutOfRange if Index is less than zero or
-- greater than the number of solutions computed by this algorithm.
-- StdFail_NotDone if the construction fails.
Tangency1(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns informations about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point on the
-- solution curv.
-- ParArg is the intrinsic parameter of the point on the
-- argument curv.
-- PntSol is the tangency point on the solution curv.
-- PntArg is the tangency point on the argument curv.
-- Raises NotDone if the construction algorithm didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
CenterOn3 (me ;
Index : Integer from Standard;
ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns informations about the center (on the curv)
-- of the result.
-- ParArg is the intrinsic parameter of the point on
-- the argument curv.
-- PntSol is the center point of the solution curv.
-- Raises NotDone if the construction algorithm didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
IsTheSame1(me ;
Index : Integer from Standard) returns Boolean from Standard
---Purpose: Returns True if the solution number Index is equal to
-- the first argument and False in the other cases.
-- Raises NotDone if the construction algorithm didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose: The number of possible solutions. We have to decide about the
-- status of the multiple solutions...
cirsol : Array1OfCirc2d from TColgp;
---Purpose : The solutions.
qualifier1 : Array1OfPosition from GccEnt;
-- The qualifiers of the first argument.
TheSame1 : Array1OfInteger from TColStd;
---Purpose: 1 if the solution and the first argument are the same in the
-- tolerance of Tolerance.
-- 0 in the other cases.
pnttg1sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the first
-- argument on the solution.
pntcen3 : Array1OfPnt2d from TColgp;
---Purpose: The center point of the solution on the first argument.
par1sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on thesolution.
pararg1 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the first argument.
parcen3 : Array1OfReal from TColStd;
---Purpose: The parameter of the center point of the solution on the
-- second argument.
end Circ2dTanOnRad;

View File

@@ -0,0 +1,318 @@
// file GccAna_Circ2dTanOnRad.cxx, REG 08/07/91
// PRO12736 : bug quand OnLine // Ox, JCT 20/03/98
//========================================================================
// circulaire tangent a un element de type : - Cercle. +
// - Ligne. +
// - Point. +
// centre sur un deuxieme element de type : - Cercle. +
// - Ligne. +
// de rayon donne : Radius. +
//========================================================================
#include <GccAna_Circ2dTanOnRad.ixx>
#include <ElCLib.hxx>
#include <math_DirectPolynomialRoots.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Standard_NegativeValue.hxx>
#include <gp_Dir2d.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
#include <GccEnt_BadQualifier.hxx>
typedef math_DirectPolynomialRoots Roots;
//=========================================================================
// Cercle tangent : a un cercle Qualified1 (C1). +
// centre : sur une droite OnLine. +
// de rayon : Radius. +
// +
// On initialise le tableau de solutions cirsol ainsi que tous les +
// champs. +
// On elimine en fonction du qualifieur les cas ne presentant pas de +
// solutions. +
// On resoud l equation du second degre indiquant que le point de centre +
// recherche (xc,yc) est a une distance Radius du cercle C1 et +
// sur la droite OnLine. +
// Les solutions sont representees par les cercles : +
// - de centre Pntcen(xc,yc) +
// - de rayon Radius. +
//=========================================================================
GccAna_Circ2dTanOnRad::
GccAna_Circ2dTanOnRad (const GccEnt_QualifiedCirc& Qualified1,
const gp_Lin2d& OnLine ,
const Standard_Real Radius ,
const Standard_Real Tolerance ) :
cirsol(1,4) ,
qualifier1(1,4) ,
TheSame1(1,4) ,
pnttg1sol(1,4) ,
pntcen3(1,4) ,
par1sol(1,4) ,
pararg1(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
TColStd_Array1OfReal Coef(1,2);
gp_Circ2d C1 = Qualified1.Qualified();
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else {
Standard_Integer nbsol = 0;
Standard_Integer signe = 0;
gp_Pnt2d Center;
Standard_Real xc;
Standard_Real yc;
Standard_Real R1 = C1.Radius();
Standard_Real dist = OnLine.Distance(C1.Location());
Standard_Real xdir = (OnLine.Direction()).X();
Standard_Real ydir = (OnLine.Direction()).Y();
Standard_Real lxloc = (OnLine.Location()).X();
Standard_Real lyloc = (OnLine.Location()).Y();
gp_Pnt2d center1(C1.Location());
Standard_Real x1 = center1.X();
Standard_Real y1 = center1.Y();
Standard_Real xbid = 0.;
if (Qualified1.IsEnclosed()) {
// ============================
if (Tol < Radius-R1+dist) { WellDone = Standard_True; }
else {
if (Abs(Radius-R1+dist) < Tol) {
WellDone = Standard_True;
NbrSol = 1;
if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) {
Center = gp_Pnt2d(x1-ydir*dist,y1+xdir*dist);
}
else { Center = gp_Pnt2d(x1+ydir*dist,y1-xdir*dist); }
signe = 1;
}
else {
Coef(1) = (R1-Radius)*(R1-Radius);
nbsol = 1;
}
}
}
else if (Qualified1.IsEnclosing()) {
// ==================================
if (R1+dist-Radius > Tol) { WellDone = Standard_True; }
else {
if (R1+dist-Radius > 0.0) {
WellDone = Standard_True;
NbrSol = 1;
if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) {
Center = gp_Pnt2d(x1-ydir*dist,y1+xdir*dist);
}
else { Center = gp_Pnt2d(x1+ydir*dist,y1-xdir*dist); }
signe = -1;
}
else {
Coef(1) = (Radius-R1)*(Radius-R1);
nbsol = 1;
}
}
}
else {
// ====
if (dist-R1-Radius > Tol) { WellDone = Standard_False; }
else {
if (Abs(dist-R1-Radius) < Tol) {
WellDone = Standard_True;
NbrSol = 1;
if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) {
Center = gp_Pnt2d(x1-ydir*dist,y1+xdir*dist);
}
else { Center = gp_Pnt2d(x1+ydir*dist,y1-xdir*dist); }
signe = -1;
}
else {
if (Qualified1.IsOutside()) {
// ===========================
Coef(1) = (Radius+R1)*(Radius+R1);
nbsol = 1;
}
else {
// ====
Coef(1) = (Radius-R1)*(Radius-R1);
Coef(2) = (Radius+R1)*(Radius+R1);
nbsol = 2;
}
}
}
}
if (signe != 0) {
cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// ==================================================
Standard_Real distcc1 = Center.Distance(center1);
if (!Qualified1.IsUnqualified()) {
qualifier1(1) = Qualified1.Qualifier();
}
else if (Abs(distcc1+Radius-R1) < Tol) {
qualifier1(1) = GccEnt_enclosed;
}
else if (Abs(distcc1-R1-Radius) < Tol) {
qualifier1(1) = GccEnt_outside;
}
else { qualifier1(1) = GccEnt_enclosing; }
if (Abs(Radius-R1) <= Tol) { TheSame1(1) = 1; }
else {
gp_Dir2d dir1cen(Center.X()-x1,Center.Y()-y1);
pnttg1sol(1) = gp_Pnt2d(Center.XY()+signe*Radius*dir1cen.XY());
par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
pararg1(1)=ElCLib::Parameter(C1,pnttg1sol(1));
}
pntcen3(1) = cirsol(NbrSol).Location();
parcen3(1)=ElCLib::Parameter(OnLine,pntcen3(1));
}
else if (nbsol > 0) {
for (Standard_Integer j = 1 ; j <= nbsol ; j++) {
Standard_Real A,B,C;
OnLine.Coefficients(A,B,C);
Standard_Real D = A;
Standard_Real x0,y0;
if ( Abs(D) <= Tol ) {
A = B;
B = D;
xbid = x1;
x0 = y1;
y0 = x1;
}
else{
x0 = x1;
y0 = y1;
}
Roots Sol((B*B+A*A)/(A*A),
2.0*(B*C/(A*A)+(B/A)*x0-y0),
x0*x0+y0*y0+C*C/(A*A)-Coef(j)+2.0*C*x0/A);
if (Sol.IsDone()) {
for (Standard_Integer i = 1 ; i <= Sol.NbSolutions() ; i++) {
if ( Abs(D) > Tol ) {
yc = Sol.Value(i);
xc = -(B/A)*yc-C/A;
}
else {
xc = Sol.Value(i);
yc = -(B/A)*xc-C/A;
}
Center = gp_Pnt2d(xc,yc);
if (OnLine.Distance(Center)>Tol)
continue;
NbrSol++;
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
Standard_Real distcc1 = Center.Distance(center1);
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; }
gp_Dir2d dir1cen(Center.X()-x1,Center.Y()-y1);
if ((Radius > R1) || (Center.Distance(center1) > R1)) {
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dir1cen.XY());
}
else {
pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1cen.XY());
}
pntcen3(NbrSol) = cirsol(NbrSol).Location();
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
}
WellDone = Standard_True;
}
}
}
}
}
Standard_Boolean GccAna_Circ2dTanOnRad::
IsDone () const { return WellDone; }
Standard_Integer GccAna_Circ2dTanOnRad::
NbSolutions () const { return NbrSol; }
gp_Circ2d GccAna_Circ2dTanOnRad::ThisSolution (const Standard_Integer Index) const
{
if (Index > NbrSol || Index <= 0) {
Standard_OutOfRange::Raise();
}
return cirsol(Index);
}
void GccAna_Circ2dTanOnRad::
WhichQualifier(const Standard_Integer Index ,
GccEnt_Position& Qualif1 ) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
Qualif1 = qualifier1(Index);
}
}
void GccAna_Circ2dTanOnRad::
Tangency1 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
if (!WellDone) {
StdFail_NotDone::Raise();
}
else if (Index <= 0 ||Index > NbrSol) {
Standard_OutOfRange::Raise();
}
else {
ParSol = par1sol(Index);
ParArg = pararg1(Index);
PntSol = gp_Pnt2d(pnttg1sol(Index));
}
}
void GccAna_Circ2dTanOnRad::
CenterOn3 (const Standard_Integer Index,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
if (!WellDone) {
StdFail_NotDone::Raise();
}
else if (Index <= 0 ||Index > NbrSol) {
Standard_OutOfRange::Raise();
}
else {
ParArg = parcen3(Index);
PntSol = pnttg1sol(Index);
}
}
Standard_Boolean GccAna_Circ2dTanOnRad::IsTheSame1 (const Standard_Integer Index) const
{
if (!WellDone)
StdFail_NotDone::Raise();
if (Index <= 0 ||Index > NbrSol)
Standard_OutOfRange::Raise();
if (TheSame1(Index) == 0)
return Standard_False;
return Standard_True;
}

View File

@@ -0,0 +1,130 @@
// file GccAna_Circ2dTanOnRad_1.cxx, REG 08/07/91
#include <GccAna_Circ2dTanOnRad.jxx>
#include <ElCLib.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <Standard_NegativeValue.hxx>
#include <gp_Dir2d.hxx>
#include <Standard_OutOfRange.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Cercle tangent a une droite Qualified1 (L1) +
// centre sur une droite OnLine +
// de rayon Radius. +
// +
// On initialise le tableau de solutions cirsol ainsi que tous les +
// champs. +
// On elimine en fonction du qualifieur les cas ne presentant pas de +
// solutions. +
// On cree L1para : la parallele a L1 dans le sens voulu par le +
// qualifieur a une distance Radius. +
// Le point P d intersection entre L1para et OnLine donnera le point de +
// centre de la solution. +
// On cree les solutions cirsol de centre P et de rayon Radius. +
// On remplit les champs. +
//=========================================================================
GccAna_Circ2dTanOnRad::
GccAna_Circ2dTanOnRad (const GccEnt_QualifiedLin& Qualified1,
const gp_Lin2d& OnLine ,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
cirsol(1,2) ,
qualifier1(1,2) ,
TheSame1(1,2) ,
pnttg1sol(1,2) ,
pntcen3(1,2) ,
par1sol(1,2) ,
pararg1(1,2) ,
parcen3(1,2)
{
Standard_Real Tol =Abs(Tolerance);
gp_Dir2d dirx(1.0,0.0);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Integer nbsol = 0;
TColStd_Array1OfInteger eps(1,2);
gp_Lin2d L1 = Qualified1.Qualified();
gp_Pnt2d origin1(L1.Location());
gp_Dir2d dir1(L1.Direction());
gp_Dir2d normL1(-dir1.Y(),dir1.X());
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else if ((OnLine.Direction()).IsParallel(dir1,Tol)) {
WellDone = Standard_True;
}
else {
if (Qualified1.IsEnclosed()) {
// ============================
eps(1) = -1;
nbsol = 1;
}
else if (Qualified1.IsOutside()) {
// ================================
eps(1) = 1;
nbsol = 1;
}
else {
// ====
eps(1) = 1;
eps(2) = -1;
nbsol = 2;
}
Standard_Real dx1 = dir1.X();
Standard_Real dy1 = dir1.Y();
Standard_Real lx1 = origin1.X();
Standard_Real ly1 = origin1.Y();
for (Standard_Integer j = 1 ; j <= nbsol ; j++) {
gp_Lin2d L1para(gp_Pnt2d(lx1+eps(j)*Radius*dy1,ly1-eps(j)*Radius*dx1),
dir1);
IntAna2d_AnaIntersection Intp(OnLine,L1para);
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);
// =====================================================
gp_Dir2d dc1(origin1.XY()-Center.XY());
#ifdef DEB
Standard_Real sign = dc1.Dot(normL1);
#else
dc1.Dot(normL1);
#endif
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc1.Dot(normL1) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
TheSame1(NbrSol) = 0;
if (gp_Vec2d(Center,origin1).Dot(gp_Dir2d(-dy1,dx1))>0.0) {
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius*gp_XY(-dy1,dx1));
pntcen3(NbrSol) = cirsol(1).Location();
}
else {
pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()-Radius*gp_XY(-dy1,dx1));
pntcen3(NbrSol) = cirsol(1).Location();
}
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
}
}
WellDone = Standard_True;
}
}
}
}

View File

@@ -0,0 +1,152 @@
// file GccAna_Circ2dTanOnRad_2.cxx, REG 08/07/91
#include <GccAna_Circ2dTanOnRad.jxx>
#include <ElCLib.hxx>
#include <math_DirectPolynomialRoots.hxx>
#include <Standard_NegativeValue.hxx>
#include <Standard_OutOfRange.hxx>
#include <gp_Dir2d.hxx>
//=========================================================================
// typedef des objets manipules : +
//=========================================================================
typedef math_DirectPolynomialRoots Roots;
//=========================================================================
// Cercle tangent a un point Point1. +
// centre sur une droite OnLine. +
// de rayon Radius. +
// +
// On initialise le tableau de solutions cirsol ainsi que tous les +
// champs. +
// On elimine les cas ne presentant pas de solution. +
// On resoud l equation du second degre indiquant que le point de centre +
// recherche (xc,yc) est a une distance Radius du point Point1 et +
// sur la droite OnLine. +
// Les solutions sont representees par les cercles : +
// - de centre Pntcen(xc,yc) +
// - de rayon Radius. +
//=========================================================================
GccAna_Circ2dTanOnRad::
GccAna_Circ2dTanOnRad (const gp_Pnt2d& Point1 ,
const gp_Lin2d& OnLine ,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
cirsol(1,2) ,
qualifier1(1,2) ,
TheSame1(1,2) ,
pnttg1sol(1,2),
pntcen3(1,2) ,
par1sol(1,2) ,
pararg1(1,2) ,
parcen3(1,2)
{
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
WellDone = Standard_False;
NbrSol = 0;
Standard_Real dp1lin = OnLine.Distance(Point1);
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else {
if (dp1lin > Radius+Tol) { WellDone = Standard_True; }
Standard_Real xc;
Standard_Real yc;
Standard_Real x1 = Point1.X();
Standard_Real y1 = Point1.Y();
Standard_Real xbid = 0;
Standard_Real xdir = (OnLine.Direction()).X();
Standard_Real ydir = (OnLine.Direction()).Y();
Standard_Real lxloc = (OnLine.Location()).X();
Standard_Real lyloc = (OnLine.Location()).Y();
if (Abs(dp1lin-Radius) < Tol) {
WellDone = Standard_True;
NbrSol = 1;
if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) {
gp_Ax2d axe(gp_Pnt2d(x1-ydir*dp1lin,y1+xdir*dp1lin),dirx);
cirsol(NbrSol) = gp_Circ2d(axe,Radius);
// ======================================
qualifier1(NbrSol) = GccEnt_noqualifier;
}
else {
gp_Ax2d axe(gp_Pnt2d(x1+ydir*dp1lin,y1-xdir*dp1lin),dirx);
cirsol(NbrSol) = gp_Circ2d(axe,Radius);
// ======================================
qualifier1(NbrSol) = GccEnt_noqualifier;
}
TheSame1(NbrSol) = 0;
pnttg1sol(NbrSol) = Point1;
pntcen3(NbrSol) = cirsol(NbrSol).Location();
pararg1(NbrSol) = 0.0;
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
}
else if (dp1lin < Tol) {
pntcen3(1) = gp_Pnt2d(Point1.X()+Radius*xdir,Point1.Y()+Radius*ydir);
pntcen3(2) = gp_Pnt2d(Point1.X()-Radius*xdir,Point1.Y()-Radius*ydir);
pntcen3(1) = ElCLib::Value(ElCLib::Parameter(OnLine,pntcen3(1)),OnLine);
pntcen3(2) = ElCLib::Value(ElCLib::Parameter(OnLine,pntcen3(2)),OnLine);
gp_Ax2d axe(pntcen3(1),OnLine.Direction());
cirsol(1) = gp_Circ2d(axe,Radius);
axe = gp_Ax2d(pntcen3(2),OnLine.Direction());
cirsol(2) = gp_Circ2d(axe,Radius);
TheSame1(1) = 0;
pnttg1sol(1) = Point1;
pararg1(1) = 0.0;
par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
parcen3(1)=ElCLib::Parameter(OnLine,pntcen3(1));
TheSame1(2) = 0;
pnttg1sol(2) = Point1;
pararg1(2) = 0.0;
par1sol(2)=ElCLib::Parameter(cirsol(2),pnttg1sol(2));
parcen3(2)=ElCLib::Parameter(OnLine,pntcen3(2));
NbrSol = 2;
}
else {
Standard_Real A,B,C;
OnLine.Coefficients(A,B,C);
Standard_Real D = A;
if (A == 0.0) {
A = B;
B = D;
xbid = x1;
x1 = y1;
y1 = xbid;
}
if (A != 0.0) {
Roots Sol((B*B+A*A)/(A*A),
2.0*(B*C/(A*A)+(B/A)*x1-y1),
x1*x1+y1*y1+C*C/(A*A)-Radius*Radius+2.0*C*x1/A);
if (Sol.IsDone()) {
for (Standard_Integer i = 1 ; i <= Sol.NbSolutions() ; i++) {
if (D != 0.0) {
yc = Sol.Value(i);
xc = -(B/A)*yc-C/A;
}
else {
xc = Sol.Value(i);
yc = -(B/A)*xc-C/A;
}
NbrSol++;
gp_Pnt2d Center(xc,yc);
cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
// =======================================================
qualifier1(NbrSol) = GccEnt_noqualifier;
TheSame1(NbrSol) = 0;
pnttg1sol(NbrSol) = Point1;
pntcen3(NbrSol) = cirsol(NbrSol).Location();
pararg1(NbrSol) = 0.0;
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
}
WellDone = Standard_True;
}
}
}
}
}

View File

@@ -0,0 +1,237 @@
// file GccAna_Circ2dTanOnRad_3.cxx, REG 08/07/91
#include <GccAna_Circ2dTanOnRad.jxx>
#include <ElCLib.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <Standard_NegativeValue.hxx>
#include <Standard_OutOfRange.hxx>
#include <TColgp_Array1OfDir2d.hxx>
#include <gp_Dir2d.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Cercle tangent a un cercle Qualified1 (C1). +
// centre sur un cercle OnCirc. +
// de rayon Radius. +
// +
// On initialise le tableau de solutions cirsol ainsi que tous les +
// champs. +
// On elimine les cas ne presentant pas de solution. +
// On cree la (les) parallele(s) a C1 dans le (les) sens voulu(s). +
// On intersecte cette (ces) parallele(s) avec OnCirc et on obtient le +
// (les) point(s) de centre de la (des) solution(s) recherchee(s). +
// On cree cette (ces) solution(s) cirsol. +
//=========================================================================
GccAna_Circ2dTanOnRad::
GccAna_Circ2dTanOnRad (const GccEnt_QualifiedCirc& Qualified1,
const gp_Circ2d& OnCirc ,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
cirsol(1,4) ,
qualifier1(1,4) ,
TheSame1(1,4) ,
pnttg1sol(1,4),
pntcen3(1,4) ,
par1sol(1,4) ,
pararg1(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
Standard_Integer signe[5];
signe[0] = 0;
signe[1] = 0;
signe[2] = 0;
signe[3] = 0;
signe[4] = 0;
Standard_Real disparal[2];
Standard_Integer nparal = 0;
Standard_Integer sign = 0;
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
gp_Circ2d C1 = Qualified1.Qualified();
TColgp_Array1OfPnt2d Center(1,4);
TColgp_Array1OfDir2d dir1on(1,4);
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else {
Standard_Real R1 = C1.Radius();
Standard_Real R2 = OnCirc.Radius();
Standard_Real c1x = C1.Location().X();
Standard_Real c1y = C1.Location().Y();
gp_Pnt2d center1(c1x,c1y);
Standard_Real dist = OnCirc.Location().Distance(center1);
Standard_Real onx = OnCirc.Location().X();
Standard_Real ony = OnCirc.Location().Y();
if (Qualified1.IsEnclosed()) {
// ============================
if ((Radius-R1 > Tol) || (R1-dist-R2-Radius > Tol)) {
WellDone=Standard_True;
}
else {
if (Abs(Radius-R1) < Tol) {
if (OnCirc.Distance(center1) < Tol) {
cirsol(NbrSol) = C1;
// ==============
qualifier1(NbrSol) = Qualified1.Qualifier();
NbrSol = 1;
TheSame1(NbrSol) = 1;
pntcen3(NbrSol) = center1;
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen3(NbrSol));
WellDone = Standard_True;
}
else { WellDone = Standard_False; }
}
else if (Abs(R1-dist-R2-Radius) <= Tol) {
dir1on(1) = gp_Dir2d(c1x-onx,c1y-ony);
sign = -1;
}
else {
nparal = 1;
disparal[0] = Abs(R1-Radius);
}
}
}
else if (Qualified1.IsEnclosing()) {
// ==================================
if ((Tol<R1-Radius)||(Tol<R1+dist-R2-Radius)||(Radius-R1-dist-R2>Tol)) {
WellDone = Standard_True;
}
else {
if (Abs(Radius-R1) < Tol) {
if (OnCirc.Distance(center1) < Tol) {
cirsol(NbrSol) = C1;
// ==============
qualifier1(NbrSol) = Qualified1.Qualifier();
NbrSol = 1;
TheSame1(NbrSol) = 1;
pntcen3(NbrSol) = center1;
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen3(NbrSol));
WellDone = Standard_True;
}
else { WellDone = Standard_True; }
}
else if ((Abs(R1+dist-R2-Radius)<Tol)||(Abs(Radius-R1-dist-R2)<Tol)) {
dir1on(1) = gp_Dir2d(c1x-onx,c1y-ony);
if (Abs(R1+dist-R2-Radius) < Tol) { sign = 1; }
else { sign = -1; }
}
else {
nparal = 1;
disparal[0] = Abs(R1-Radius);
}
}
}
else if (Qualified1.IsOutside()) {
// ================================
if ((dist-R2-R1-Radius>Tol)||(Radius-dist-R2+R1>Tol)) {
WellDone=Standard_True;
}
else {
dir1on(1) = gp_Dir2d(c1x-onx,c1y-ony);
if (Abs(R1-dist-R2+Radius) < Tol) {
sign = -1;
}
else if (Abs(dist-R1-R2-Radius) < Tol) { sign = 1; }
else {
nparal = 1;
disparal[0] = Abs(R1+Radius);
}
}
}
else {
if ((dist-R2-R1-Radius>Tol)||(Radius-dist-R1-R2>Tol)) {
WellDone=Standard_True;
}
else if ((R1-dist-R2>Tol)&&(Tol<R1-R2-dist-Radius)) {
WellDone = Standard_True;
}
else {
dir1on(1) = gp_Dir2d(c1x-onx,c1y-ony);
if (Abs(dist-R1-R2-Radius) < Tol) {
sign = 1;
}
else if (dist+R1+R2-Radius < 0.0) { sign = -1; }
else if ((R1-dist+R2>0.0) && (R1-R2-dist-Radius>0.0)) { sign = -1; }
else {
nparal = 2;
disparal[0] = Abs(R1+Radius);
disparal[1] = Abs(R1-Radius);
}
}
}
for (Standard_Integer jj = 0 ; jj < nparal ; jj++) {
IntAna2d_AnaIntersection Intp(OnCirc,
gp_Circ2d(gp_Ax2d(center1,dirx),disparal[jj]));
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
NbrSol++;
Center(NbrSol) = gp_Pnt2d(Intp.Point(i).Value());
cirsol(NbrSol)=gp_Circ2d(gp_Ax2d(Center(NbrSol),dirx),Radius);
// =============================================================
Standard_Real distcc1 = Center(NbrSol).Distance(center1);
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; }
dir1on(NbrSol) = gp_Dir2d(c1x-Center(NbrSol).X(),
c1y-Center(NbrSol).Y());
if ((R1>Radius) && (Center(NbrSol).Distance (center1)<=R1)){
signe[NbrSol-1] = -1;
}
else {
signe[NbrSol-1] = 1;
}
}
}
WellDone = Standard_True;
}
}
if (sign != 0) {
Center(1) = gp_Pnt2d(OnCirc.Location().XY()+sign*R2*dir1on(1).XY());
cirsol(1) = gp_Circ2d(gp_Ax2d(Center(1),dirx),Radius);
// =====================================================
Standard_Real distcc1 = Center(1).Distance(center1);
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; }
NbrSol = 1;
signe[NbrSol-1] = 1;
WellDone = Standard_True;
}
Standard_Integer ii = 0;
while (signe[ii] != 0) {
pnttg1sol(ii+1) = gp_Pnt2d(Center(ii+1).XY()+
signe[ii]*Radius*dir1on(ii+1).XY());
pntcen3(ii+1) = cirsol(ii+1).Location();
pararg1(ii+1)=ElCLib::Parameter(C1,pnttg1sol(ii+1));
par1sol(ii+1)=ElCLib::Parameter(cirsol(ii+1),pnttg1sol(ii+1));
parcen3(ii+1)=ElCLib::Parameter(OnCirc,pntcen3(ii+1));
ii++;
}
}
}

View File

@@ -0,0 +1,141 @@
// file GccAna_Circ2dTanOnRad_4.cxx, REG 08/07/91
#include <GccAna_Circ2dTanOnRad.jxx>
#include <ElCLib.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <Standard_NegativeValue.hxx>
#include <Standard_OutOfRange.hxx>
#include <gp_Dir2d.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Cercle tangent a une droite Qualified1 (L1). +
// centre sur un cercle OnCirc. +
// de rayon Radius. +
// +
// On initialise le tableau de solutions cirsol ainsi que tous les +
// champs. +
// On elimine les cas ne presentant pas de solution. +
// On cree la (les) parallele(s) a L1 dans le (les) sens voulu(s). +
// On intersecte cette (ces) parallele(s) avec OnCirc et on obtient les +
// points de centre des solutions recherchees. +
// On cree ces solutions cirsol. +
//=========================================================================
GccAna_Circ2dTanOnRad::
GccAna_Circ2dTanOnRad (const GccEnt_QualifiedLin& Qualified1,
const gp_Circ2d& OnCirc ,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
//=========================================================================
// Initialisation des champs. +
//=========================================================================
cirsol(1,4) ,
qualifier1(1,4) ,
TheSame1(1,4) ,
pnttg1sol(1,4),
pntcen3(1,4) ,
par1sol(1,4) ,
pararg1(1,4) ,
parcen3(1,4)
{
TheSame1.Init(0);
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
//=========================================================================
// Initialisation de diverses variables. +
//=========================================================================
Standard_Integer nbsol = 0;
Standard_Integer sign = 0;
gp_Lin2d L1 = Qualified1.Qualified();
gp_Pnt2d origin1(L1.Location());
gp_Dir2d dir1(L1.Direction());
gp_Dir2d normL1(-dir1.Y(),dir1.X());
Standard_Real dist1 = L1.Distance(OnCirc.Location())-OnCirc.Radius();
Standard_Real dist2 = L1.Distance(OnCirc.Location())+OnCirc.Radius();
//=========================================================================
// Traitement. +
//=========================================================================
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else {
L1 = Qualified1.Qualified();
if ((dist1-Radius>Tol) || (Tol<Radius-dist2)) { WellDone=Standard_True; }
else {
// a modifier ulterieurement.
if (dist1-Radius > 0.0) { dist1 = Radius; }
else if (dist2-Radius < 0.0) { dist2 = Radius; }
if (Qualified1.IsEnclosed()) {
// ============================
nbsol = 1;
sign = -1;
}
else if (Qualified1.IsOutside()) {
// ================================
nbsol = 1;
sign = 1;
}
else {
// ====
nbsol = 2;
sign = 1;
}
for (Standard_Integer j = 1 ; j <= nbsol ;j++) {
sign = -sign;
gp_Lin2d L(gp_Pnt2d(origin1.X()-sign*Radius*dir1.Y(),
origin1.Y()+sign*Radius*dir1.X()),dir1);
IntAna2d_AnaIntersection Intp(L,OnCirc);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
NbrSol++;
gp_Pnt2d Center(Intp.Point(i).Value());
gp_Ax2d axe(Center,dirx);
cirsol(NbrSol) = gp_Circ2d(axe,Radius);
// ======================================
gp_Dir2d dc1(origin1.XY()-Center.XY());
sign = (Standard_Integer) dc1.Dot(normL1);
if (!Qualified1.IsUnqualified()) {
qualifier1(NbrSol) = Qualified1.Qualifier();
}
else if (dc1.Dot(normL1) > 0.0) {
qualifier1(NbrSol) = GccEnt_outside;
}
else { qualifier1(NbrSol) = GccEnt_enclosed; }
pntcen3(NbrSol) = cirsol(NbrSol).Location();
pnttg1sol(NbrSol) = gp_Pnt2d(pntcen3(NbrSol).XY()+
gp_XY(sign*Radius*dir1.Y(),
-sign*Radius*dir1.X()));
pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
pnttg1sol(NbrSol));
parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen3(NbrSol));
}
}
WellDone = Standard_True;
}
}
}
}
}

View File

@@ -0,0 +1,95 @@
// file GccAna_Circ2dTanOnRad_5.cxx, REG 08/07/91
#include <GccAna_Circ2dTanOnRad.jxx>
#include <ElCLib.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <Standard_NegativeValue.hxx>
#include <Standard_OutOfRange.hxx>
#include <gp_Dir2d.hxx>
//=========================================================================
// Cercle tangent a un point Point1. +
// centre sur un cercle OnCirc. +
// de rayon Radius. +
// +
// On initialise le tableau de solutions cirsol ainsi que tous les +
// champs. +
// On elimine les cas ne presentant pas de solution. +
// On cree le cercle centre en Point1 de rayon Radius. +
// On intersecte ce cercle avec OnCirc et on obtient les points de +
// centre des solutions recherchees. +
// On cree ces solutions cirsol. +
//=========================================================================
GccAna_Circ2dTanOnRad::
GccAna_Circ2dTanOnRad (const gp_Pnt2d& Point1 ,
const gp_Circ2d& OnCirc ,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
cirsol(1,2) ,
qualifier1(1,2) ,
TheSame1(1,2) ,
pnttg1sol(1,2),
pntcen3(1,2) ,
par1sol(1,2) ,
pararg1(1,2) ,
parcen3(1,2)
{
gp_Dir2d dirx(1.0,0.0);
Standard_Real Tol = Abs(Tolerance);
WellDone = Standard_False;
NbrSol = 0;
Standard_Real Roncirc = OnCirc.Radius();
Standard_Real dist1 = Point1.Distance(OnCirc.Location())-Roncirc;
Standard_Real dist2 = Point1.Distance(OnCirc.Location())+Roncirc;
if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
else if ((dist1-Radius > Tol) || (Tol < Radius-dist2)) {
WellDone = Standard_True;
}
else {
Standard_Integer signe = 0;
if (Abs(dist1-Radius) < Tol) { signe = 1; }
else if (Abs(dist2-Radius) < Tol) { signe = -1; }
if (signe != 0) {
gp_Ax2d axe(gp_Pnt2d(OnCirc.Location().XY()-Roncirc*
gp_Dir2d(OnCirc.Location().X()-signe*Point1.X(),
OnCirc.Location().Y()-signe*Point1.Y()).XY()),dirx);
cirsol(1) = gp_Circ2d(axe,Radius);
// ================================
qualifier1(1) = GccEnt_noqualifier;
TheSame1(1) = 0;
pnttg1sol(1) = Point1;
pntcen3(1) = cirsol(1).Location();
pararg1(1) = 0.0;
par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
parcen3(1) = ElCLib::Parameter(OnCirc,pntcen3(1));
WellDone = Standard_True;
NbrSol = 1;
}
else {
IntAna2d_AnaIntersection Intp(OnCirc,gp_Circ2d(gp_Ax2d(Point1,dirx),
Radius));
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);
// =======================================================
qualifier1(1) = GccEnt_noqualifier;
TheSame1(1) = 0;
pnttg1sol(1) = Point1;
pntcen3(1) = cirsol(1).Location();
par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
parcen3(1) = ElCLib::Parameter(OnCirc,pntcen3(1));
pararg1(1) = 0.0;
}
}
WellDone = Standard_True;
}
}
}
}

View File

@@ -0,0 +1,73 @@
-- File: CircLin2dBisec.cdl
-- Created: Wed Apr 3 11:29:37 1991
-- Author: Remi GILET
-- <reg@topsn2>
---Copyright: Matra Datavision 1991
class CircLin2dBisec
from GccAna
---Purpose: Describes functions for building bisecting curves between a 2D line and a 2D circle.
-- A bisecting curve between a circle and a line is a curve
-- such that each of its points is at the same distance from
-- the circle and the line. It can be a parabola or a line,
-- depending of the relative position of the line and the
-- circle. The algorithm computes all the elementary curves which are solutions.
-- A CircLin2dBisec object provides a framework for:
-- - defining the construction of the bisecting curves,
-- - implementing the construction algorithm, and
-- - consulting the result.
uses Lin2d from gp,
Circ2d from gp,
Bisec from GccInt
raises OutOfRange from Standard,
NotDone from StdFail
is
Create(Circle : Circ2d from gp;
Line : Lin2d from gp) returns CircLin2dBisec;
---Purpose: Constructs bisecting curves between the circle Circle and the line Line.
IsDone(me) returns Boolean from Standard
is static;
--- Purpose: Returns true (this construction algorithm never fails).
NbSolutions(me) returns Integer from Standard
raises NotDone
is static;
---Purpose:
-- Returns the number of curves, representing solutions computed by this algorithm.
ThisSolution(me ;
Index : Integer from Standard) returns Bisec from GccInt
raises OutOfRange, NotDone
is static;
---Purpose : Returns the solution number Index and raises OutOfRange
-- exception if Index is greater than the number of solutions
-- Exceptions
-- Standard_OutOfRange if Index is less than zero or
-- greater than the number of solutions computed by this algorithm.
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose: The number of possible solutions. We have to decide about the
-- status of the multiple solutions...
circle : Circ2d from gp;
---Purpose: The first argument used for ThisSolution.
line : Lin2d from gp;
---Purpose: The second argument used for ThisSolution.
end CircLin2dBisec;

View File

@@ -0,0 +1,133 @@
// File: GccAna_CircLin2dBisec.cxx
// Created: Fri Oct 11 08:19:14 1991
// Author: Remi GILET
// <reg@topsn3>
//=========================================================================
// CREATION DE LA BISSECTICE ENTRE UN CERCLE ET UNE DROITE. +
//=========================================================================
#include <GccAna_CircLin2dBisec.ixx>
#include <gp_XY.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <GccInt_BParab.hxx>
#include <GccInt_BLine.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
#include <gp.hxx>
//=========================================================================
GccAna_CircLin2dBisec::
GccAna_CircLin2dBisec (const gp_Circ2d& Circle ,
const gp_Lin2d& Line ):
circle(Circle),
line(Line)
{
//=========================================================================
// Initialisation des champs : +
// - circle (Le cercle.) +
// - line (la droite.) +
// - NbrSol (nombre de solution.) +
// - WellDone (Booleen indiquant le succes ou non de l algo.). +
//=========================================================================
NbrSol = 2;
WellDone = Standard_True;
}
//=========================================================================
// Traitement. +
// On recupere les coordonees des origines de la droite (xloc,yloc) et +
// du cercle (xcencir, ycencir). +
// On recupere aussi les coordonees dela direction de la droite (xdir, +
// ydir) et le rayon du cercle R1. +
// On regarde de quel cote de la droite se trouve le centre du cercle +
// pour orienter la parabole (signe). +
// On cree l axe de chacune des paraboles (axeparab1, axeparb2), puis +
// les deux paraboles (biscirlin1, biscirlin1). +
//=========================================================================
Handle(GccInt_Bisec) GccAna_CircLin2dBisec::
ThisSolution (const Standard_Integer Index) const
{
if (!WellDone) StdFail_NotDone::Raise();
if ((Index <=0) || (Index > NbrSol)) Standard_OutOfRange::Raise();
Handle(GccInt_Bisec) bissol;
Standard_Real xdir = line.Direction().X();
Standard_Real ydir = line.Direction().Y();
Standard_Real xloc = line.Location().X();
Standard_Real yloc = line.Location().Y();
Standard_Real xcencir = circle.Location().X();
Standard_Real ycencir = circle.Location().Y();
Standard_Real R1 = circle.Radius();
Standard_Real dist = line.Distance(circle.Location());
if ((Abs(line.Distance(circle.Location())-circle.Radius())
<= gp::Resolution()) && (Index == 1)) {
gp_Lin2d biscirlin1(circle.Location(),gp_Dir2d(-ydir,xdir));
bissol = new GccInt_BLine(biscirlin1);
// ==========================================================
}
else {
Standard_Integer signe;
if ((-ydir*(xcencir-xloc)+xdir*(ycencir-yloc)) > 0.0) {
signe = 1;
}
else {
signe = -1;
}
gp_Ax2d axeparab1;
// gp_Ax2d axeparab2;
gp_Parab2d biscirlin;
if (dist != R1) {
if (Index == 1) {
axeparab1=gp_Ax2d(gp_Pnt2d(gp_XY(xcencir+signe*ydir*(dist+R1)/2,
ycencir-signe*xdir*(dist+R1)/2.)),
gp_Dir2d(-signe*ydir,signe*xdir));
biscirlin = gp_Parab2d(axeparab1,(dist+R1)/2.0);
}
else {
if (dist < R1) {
axeparab1=gp_Ax2d(gp_Pnt2d(gp_XY(xcencir+signe*ydir*(dist-R1)/2,
ycencir-signe*xdir*(dist-R1)/2.)),
gp_Dir2d(signe*ydir,-signe*xdir));
}
else {
axeparab1=gp_Ax2d(gp_Pnt2d(gp_XY(xcencir+signe*ydir*(dist-R1)/2,
ycencir-signe*xdir*(dist-R1)/2.)),
gp_Dir2d(-signe*ydir,signe*xdir));
}
biscirlin = gp_Parab2d(axeparab1,Abs(dist-R1)/2.0);
}
bissol = new GccInt_BParab(biscirlin);
// ==========================================================
}
else {
axeparab1 = gp_Ax2d(gp_Pnt2d(gp_XY(xcencir+signe*ydir*(dist+R1)/2.,
ycencir-signe*xdir*(dist+R1)/2.)),
gp_Dir2d(signe*(-ydir),signe*xdir));
biscirlin = gp_Parab2d(axeparab1,R1);
bissol = new GccInt_BParab(biscirlin);
// ==========================================================
}
}
return bissol;
}
//=========================================================================
Standard_Boolean GccAna_CircLin2dBisec::
IsDone () const { return WellDone; }
Standard_Integer GccAna_CircLin2dBisec::
NbSolutions () const { return NbrSol; }

View File

@@ -0,0 +1,78 @@
-- File: CircPnt2dBisec.cdl
-- Created: Wed Apr 3 11:29:37 1991
-- Author: Remi GILET
-- <reg@topsn2>
---Copyright: Matra Datavision 1991
class CircPnt2dBisec
from GccAna
---Purpose: Describes functions for building a bisecting curve
-- between a 2D circle and a point.
-- A bisecting curve between a circle and a point is such a
-- curve that each of its points is at the same distance from
-- the circle and the point. It can be an ellipse, hyperbola,
-- circle or line, depending on the relative position of the
-- point and the circle. The algorithm computes all the
-- elementary curves which are solutions.
-- A CircPnt2dBisec object provides a framework for:
-- - defining the construction of the bisecting curves,
-- - implementing the construction algorithm, and
-- - consulting the result.
uses Circ2d from gp,
Pnt2d from gp,
Bisec from GccInt
raises OutOfRange from Standard,
NotDone from StdFail
is
Create(Circle1 : Circ2d from gp;
Point2 : Pnt2d from gp) returns CircPnt2dBisec;
---Purpose: Constructs bisecting curves between the circle Circle1 and the point Point2.
IsDone(me) returns Boolean from Standard
is static;
---Purpose: Returns true (this construction algorithm never fails).
NbSolutions(me) returns Integer from Standard
raises NotDone
is static;
---Purpose: Returns the number of curves, representing solutions computed by this algorithm.
ThisSolution(me ;
Index : Integer from Standard) returns Bisec from GccInt
raises OutOfRange, NotDone
is static;
---Purpose: Returns the solution number Index and raises OutOfRange
-- exception if Index is greater than the number of solutions.
-- Exceptions
-- Standard_OutOfRange if Index is less than zero or
-- greater than the number of solutions computed by this algorithm.
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose: The number of possible solutions. We have to decide about the
-- status of the multiple solutions...
circle : Circ2d from gp;
---Purpose: The first argument used for ThisSolution.
point : Pnt2d from gp;
---Purpose: The second argument used for ThisSolution.
theposition : Integer from Standard;
---Purpose: theposition = 1 when the point is outside the circle.
-- theposition = 0 when the point is on the circle.
-- theposition = -1 when the point is inside the circle.
end CircPnt2dBisec;

View File

@@ -0,0 +1,162 @@
// File: GccAna_CircPnt2dBisec.cxx
// Created: Fri Oct 11 08:19:14 1991
// Author: Remi GILET
// <reg@topsn3>
//=========================================================================
// CREATION DE LA BISSECTICE ENTRE UN CERCLE ET UN POINT. +
//=========================================================================
#include <GccAna_CircPnt2dBisec.ixx>
#include <gp_XY.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <GccInt_BHyper.hxx>
#include <GccInt_BCirc.hxx>
#include <GccInt_BElips.hxx>
#include <GccInt_BLine.hxx>
#include <Standard_ConstructionError.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
#include <gp.hxx>
//=========================================================================
GccAna_CircPnt2dBisec::
GccAna_CircPnt2dBisec (const gp_Circ2d& Circle ,
const gp_Pnt2d& Point ):
circle(Circle),
point(Point) {
//=========================================================================
// Initialisation des champs : +
// - circle (Cercle : premier argument.) +
// - line (Ligne : deuxieme argument.) +
// - theposition (Entier indiquant la position de Point par +
// rapport a Circle.) +
// - NbrSol (Entier indiquant le nombre de solutions.) +
// - WellDone (Booleen indiquant le succes ou non de l algo.). +
//=========================================================================
Standard_Real dist = Circle.Radius()-Point.Distance(Circle.Location());
// if (Abs(dist) < gp::Resolution())
if (Abs(dist) < 1.E-10)
{
theposition = 0;
NbrSol = 1;
}
else if (dist > 0.0)
{
theposition = -1;
NbrSol = 1;
}
else {
theposition = 1;
NbrSol = 2;
}
WellDone = Standard_True;
}
//=========================================================================
// Traitement. +
// On recupere les coordonees des origines de la droite (xloc,yloc) et +
// du cercle (xcencirc, ycencirc). +
// On recupere aussi les coordonees dela direction de la droite (xdir, +
// ydir) et le rayon du cercle R1. +
// On regarde de quel cote de la droite se trouve le centre du cercle +
// pour orienter la parabole (signe). +
// On cree l axe de chacune des paraboles (axeparab1, axeparb2), puis +
// les deux paraboles (biscirPnt1, biscirPnt1). +
//=========================================================================
Handle(GccInt_Bisec) GccAna_CircPnt2dBisec::
ThisSolution (const Standard_Integer Index) const
{
if (!WellDone)
StdFail_NotDone::Raise();
if ((Index <=0) || (Index > NbrSol))
Standard_OutOfRange::Raise();
Handle(GccInt_Bisec) bissol;
Standard_Real xpoint = point.X();
Standard_Real ypoint = point.Y();
Standard_Real xcencir = circle.Location().X();
Standard_Real ycencir = circle.Location().Y();
Standard_Real R1 = circle.Radius();
Standard_Real dist = point.Distance(circle.Location());
// if (dist < gp::Resolution())
if (dist < 1.E-10)
{
gp_Circ2d biscirpnt1(gp_Ax2d(point,gp_Dir2d(1.0,0.0)),R1/2.);
bissol = new GccInt_BCirc(biscirpnt1);
// ==========================================================
}
else {
gp_Pnt2d center((xpoint+xcencir)/2.,(ypoint+ycencir)/2.);
gp_Ax2d majax(center,gp_Dir2d(xpoint-xcencir,ypoint-ycencir));
//=========================================================================
// Le point est a l interieur du cercle. +
//=========================================================================
if (theposition == -1) {
gp_Elips2d biscirpnt(majax,R1/2.,Sqrt(R1*R1-dist*dist)/2.);
bissol = new GccInt_BElips(biscirpnt);
// ===========================================================
}
//=========================================================================
// Le point est sur le cercle. +
// Il y a une seule solution : la droite passant par point et le centre +
// du cercle. +
//=========================================================================
else if (theposition == 0) {
gp_Dir2d dirsol;
if (circle.IsDirect())
dirsol=gp_Dir2d(xcencir-xpoint,ycencir-ypoint);
else dirsol = gp_Dir2d(xpoint-xcencir,ypoint-ycencir);
gp_Lin2d biscirpnt(point,dirsol);
bissol = new GccInt_BLine(biscirpnt);
// =========================================================
}
//=========================================================================
// Le point est a l exterieur du cercle. +
// Il y a deux solutions : les deux branches principales de l hyperbole.+
//=========================================================================
else {
// Standard_Real d1 = sqrt(dist*R1-R1*R1);
Standard_Real d1 = sqrt(dist*dist-R1*R1)/2.0;
Standard_Real d2 = R1/2.;
if (Index == 1) {
gp_Hypr2d biscirpnt1(majax,d2,d1);
bissol = new GccInt_BHyper(biscirpnt1);
// =========================================
}
else {
gp_Hypr2d biscirpnt1(majax,d2,d1);
gp_Hypr2d biscirpnt2 = biscirpnt1.OtherBranch();
bissol = new GccInt_BHyper(biscirpnt2);
// =========================================
}
}
}
return bissol;
}
//=========================================================================
Standard_Boolean GccAna_CircPnt2dBisec::
IsDone () const { return WellDone; }
Standard_Integer GccAna_CircPnt2dBisec::
NbSolutions () const { return NbrSol; }

199
src/GccAna/GccAna_Lin2d2Tan.cdl Executable file
View File

@@ -0,0 +1,199 @@
-- File: Lin2d2Tan.cdl
-- Created: Wed Apr 3 11:15:13 1991
-- Author: Remi GILET
-- <reg@topsn2>
---Copyright: Matra Datavision 1991
class Lin2d2Tan
from GccAna
---Purpose: This class implements the algorithms used to
-- create 2d lines tangent to 2 other elements which
-- can be circles or points.
-- Describes functions for building a 2D line:
-- - tangential to 2 circles, or
-- - tangential to a circle and passing through a point, or
-- - passing through 2 points.
-- A Lin2d2Tan object provides a framework for:
-- - defining the construction of 2D line(s),
-- - implementing the construction algorithm, and
-- consulting the result(s).
-- Some constructors may check the type of the qualified argument
-- and raise BadQualifier Error in case of incorrect couple (qualifier,
-- curv).
-- For example: "EnclosedCirc".
uses Pnt2d from gp,
Lin2d from gp,
QualifiedCirc from GccEnt,
Array1OfLin2d from TColgp,
Array1OfPnt2d from TColgp,
Array1OfReal from TColStd,
Position from GccEnt,
Array1OfPosition from GccEnt
raises OutOfRange from Standard,
BadQualifier from GccEnt,
NotDone from StdFail
is
Create (ThePoint1 : Pnt2d from gp ;
ThePoint2 : Pnt2d from gp ;
Tolerance : Real from Standard) returns Lin2d2Tan;
---Purpose: This methods implements the algorithms used to
-- create 2d lines passing thrue 2 points.
-- Tolerance is used because we can't create a line
-- when the distance between the two points is too small.
Create (Qualified1 : QualifiedCirc from GccEnt ;
ThePoint : Pnt2d from gp ;
Tolerance : Real from Standard) returns Lin2d2Tan
raises BadQualifier;
---Purpose: This methods implements the algorithms used to
-- create 2d lines tangent to one circle and passing
-- thrue a point.
-- Exception BadQualifier is raised in the case of
-- EnclosedCirc
-- Tolerance is used because there is no solution
-- when the point is inside the solution according to
-- the tolerance.
Create (Qualified1 : QualifiedCirc from GccEnt ;
Qualified2 : QualifiedCirc from GccEnt ;
Tolerance : Real from Standard) returns Lin2d2Tan
raises BadQualifier;
---Purpose: This methods implements the algorithms used to
-- create 2d lines tangent to 2 circles.
-- Exception BadQualifier is raised in the case of
-- EnclosedCirc
--------------------------------------------------------------------------
IsDone (me) returns Boolean from Standard
is static;
---Purpose: This method returns true when there is a solution
-- and false in the other cases.
NbSolutions(me) returns Integer from Standard
---Purpose: This method returns the number of solutions.
-- Raises NotDone if the construction algorithm didn't succeed.
raises NotDone
is static;
ThisSolution(me ;
Index : Integer from Standard) returns Lin2d
---Purpose : Returns the solution number Index and raises OutOfRange
-- exception if Index is greater than the number of solutions.
-- Be carefull: the Index is only a way to get all the
-- solutions, but is not associated to theses outside the
-- context of the algorithm-object. Raises OutOfRange is raised if Index is greater than
-- the number of solutions.
-- It raises NotDone if the algorithm failed.
raises OutOfRange, NotDone
is static;
WhichQualifier(me ;
Index : Integer from Standard;
Qualif1 : out Position from GccEnt ;
Qualif2 : out Position from GccEnt )
raises OutOfRange, NotDone
is static;
---Purpose: Returns the qualifiers Qualif1 and Qualif2 of the
-- tangency arguments for the solution of index Index
-- computed by this algorithm.
-- The returned qualifiers are:
-- - those specified at the start of construction when the
-- solutions are defined as enclosing or outside with
-- respect to the arguments, or
-- - those computed during construction (i.e. enclosing or
-- outside) when the solutions are defined as unqualified
-- with respect to the arguments, or
-- - GccEnt_noqualifier if the tangency argument is a point.
-- Exceptions
-- Standard_OutOfRange if Index is less than zero or
-- greater than the number of solutions computed by this algorithm.
-- StdFail_NotDone if the construction fails.
Tangency1(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose : Returns informations about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point PntSol on
-- the solution curv.
-- ParArg is the intrinsic parameter of the point PntSol on
-- the argument curv. Raises OutOfRange is raised if Index is greater than
-- the number of solutions.
-- It raises NotDone if the algorithm failed.
raises OutOfRange, NotDone
is static;
Tangency2(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose : Returns informations about the tangency point between the
-- result number Index and the second argument.
-- ParSol is the intrinsic parameter of the point ParSol on
-- the solution curv.
-- ParArg is the intrinsic parameter of the point PntSol on
-- the argument curv. Raises OutOfRange is raised if Index is greater than
-- the number of solutions.
-- It raises NotDone if the algorithm failed.
raises OutOfRange, NotDone
is static;
fields
WellDone : Boolean from Standard;
---Purpose : True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose : The number of possible solutions. We have to decide about the
-- status of the multiple solutions...
linsol : Array1OfLin2d from TColgp;
---Purpose : Thesolutions.
qualifier1 : Array1OfPosition from GccEnt;
---Purpose: The qualifiers of the first argument.
qualifier2 : Array1OfPosition from GccEnt;
---Purpose: The qualifiers of the second argument.
pnttg1sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the first
-- argument on the solution.
pnttg2sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the second
-- argument on the solution.
par1sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the solution.
par2sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the second argument on the solution.
pararg1 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the first argument.
pararg2 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the second argument on the second argument.
end Lin2d2Tan;

515
src/GccAna/GccAna_Lin2d2Tan.cxx Executable file
View File

@@ -0,0 +1,515 @@
// File GccAna_Lin2d2Tan.cxx, REG 08/07/91
//=========================================================================
// Droite tangente a deux cercles ou tangente a un cercle et passant +
// par un point. +
//=========================================================================
#include <GccAna_Lin2d2Tan.ixx>
#include <ElCLib.hxx>
#include <gp_XY.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Circ2d.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Droite passant par deux 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;
}
}
//=========================================================================
// Droite tangente a un cercle passant par un point. +
// ================================================= +
// Suivant le qualifieur attache au cercle Qualified1 (C1) on definit +
// la direction de la tangente a calculer. +
// Cette tangente aura comme point d attache le point P1 (point de tan- +
// gence avec le cercle. +
// Elle fera un angle A (de sinus R1/dist ou -R1/dist) avec la droite +
// passant par le centre du cercle et 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())) {
GccEnt_BadQualifier::Raise();
return;
}
gp_Circ2d C1 = Qualified1.Qualified();
Standard_Real R1 = C1.Radius();
if (Qualified1.IsEnclosed()) { GccEnt_BadQualifier::Raise(); }
// ============================
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.;
}
}
//=========================================================================
// Droite tangente a deux cercles. +
// =============================== +
// Dans le cas limite (les deux cercles tangents interieurs l un a +
// l autre) on prend la droite orthogonale a la droite reliant les deux +
// cercles. +
// Dans les autres cas on fait subir au centre de C1 (Qualified1) ou de +
// C2 (Qualified2), suivant que R1 est plus grand ou non que R2, une +
// rotation d angle A avec sinus(A) = (R1+R2)/dist ou +
// sinus(A) = (R1-R2)/dist ou +
// sinus(A) = (R2-R1)/dist ou +
// sinus(A) = (-R1-R2)/dist +
// Le point ainsi determine est P1 ou P2. +
// la direction de la droite a calculer est celle de la droite passant +
// par le centre de la rotation (centre de C1 ou de C2) et P1 ou P2. +
// On translate ensuite la droite pour la rendre tangente a 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())) {
GccEnt_BadQualifier::Raise();
return;
}
gp_Circ2d C1 = Qualified1.Qualified();
gp_Circ2d C2 = Qualified2.Qualified();
if (Qualified1.IsEnclosed() || Qualified2.IsEnclosed()) {
// =======================================================
GccEnt_BadQualifier::Raise();
}
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) { Standard_OutOfRange::Raise(); }
return linsol(Index);
}
void GccAna_Lin2d2Tan::
WhichQualifier(const Standard_Integer Index ,
GccEnt_Position& Qualif1 ,
GccEnt_Position& Qualif2 ) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
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) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
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) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
ParSol = par2sol(Index);
ParArg = pararg2(Index);
PntSol = gp_Pnt2d(pnttg2sol(Index));
}
}

136
src/GccAna/GccAna_Lin2dBisec.cdl Executable file
View File

@@ -0,0 +1,136 @@
-- File: Lin2dBisec.cdl
-- Created: Wed Apr 3 11:29:37 1991
-- Author: Remi GILET
-- <reg@topsn2>
---Copyright: Matra Datavision 1991
class Lin2dBisec
from GccAna
---Purpose: Describes functions for building bisecting lines between two 2D lines.
-- A bisecting line between two lines is such that each of its
-- points is at the same distance from the two lines.
-- If the two lines are secant, there are two orthogonal
-- bisecting lines which share the angles made by the two
-- straight lines in two equal parts. If D1 and D2 are the
-- unit vectors of the two straight lines, those of the two
-- bisecting lines are collinear with the following vectors:
-- - D1 + D2 for the "internal" bisecting line,
-- - D1 - D2 for the "external" bisecting line.
-- If the two lines are parallel, the (unique) bisecting line is
-- the straight line equidistant from the two straight lines. If
-- the two straight lines are coincident, the algorithm
-- returns the first straight line as the solution.
-- A Lin2dTanObl object provides a framework for:
-- - defining the construction of the bisecting lines,
-- - implementing the construction algorithm, and
-- - consulting the result.
uses Lin2d from gp,
Pnt2d from gp,
Array1OfReal from TColStd,
Array1OfLin2d from TColgp,
Array1OfPnt2d from TColgp
raises OutOfRange from Standard,
NotDone from StdFail
is
Create(Lin1 : Lin2d from gp ;
Lin2 : Lin2d from gp ) returns Lin2dBisec;
---Purpose: Constructs bisecting lines between the two lines Lin1 and Lin2.
IsDone(me) returns Boolean from Standard
is static;
---Purpose: Returns True when the algorithm succeded.
NbSolutions(me) returns Integer from Standard
raises NotDone
is static;
---Purpose: Returns the number of solutions and raise NotDone if
-- the constructor wasn't called before.
ThisSolution(me ;
Index : Integer from Standard) returns Lin2d
---Purpose :Returns the solution number Index .
-- The first solution is the inside one and the second is the
-- outside one.
-- For the first solution the direction is D1+D2 (D1 is
-- the direction of the first argument and D2 the
-- direction of the second argument).
-- For the second solution the direction is D1-D2.
-- Raises NotDone if the construction algorithm
-- didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
Intersection1 (me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns informations about the intersection point between
-- the result number Index and the first argument.
-- Raises NotDone if the construction algorithm didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
Intersection2 (me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose: Returns informations about the intersection point between
-- the result number Index and the second argument.
-- Raises NotDone if the construction algorithm
-- didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose: The number of possible solutions. We have to decide about the
-- status of the multiple solutions...
linsol : Array1OfLin2d from TColgp;
---Purpose : The solutions.
pntint1sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the
-- first argument on the solution.
pntint2sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the
-- second argument on the solution.
par1sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the solution.
par2sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the second argument on the solution.
pararg1 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the first argument.
pararg2 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the second argument on the second argument.
end Lin2dBisec;

155
src/GccAna/GccAna_Lin2dBisec.cxx Executable file
View File

@@ -0,0 +1,155 @@
// File GccAna_Lin2dBisec.cxx, REG 08/07/91
// JCT 06/07/98 on se fie a IntAna2d_AnaIntersection pour savoir si
// les droites sont paralleles (PRO14405)
//=========================================================================
// CREATION DE LA BISSECTICE ENTRE DEUX DROITES. +
//=========================================================================
#include <GccAna_Lin2dBisec.ixx>
#include <ElCLib.hxx>
#include <gp_XY.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp.hxx>
#include <Standard_OutOfRange.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <StdFail_NotDone.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
//=========================================================================
// La premiere bissectrice calculee est la bisectrice interieure, la +
// seconde est la bissectrice exterieure. +
// la direction de la premiere bissectrice est telle que son produit +
// scalaire avec la direction de Lin1 est toujours positif. +
// La seconde bissectrice est tournee dans le sens positif. +
//=========================================================================
GccAna_Lin2dBisec::
GccAna_Lin2dBisec (const gp_Lin2d& Lin1,
const gp_Lin2d& Lin2):
linsol(1,2) ,
pntint1sol(1,2),
pntint2sol(1,2),
par1sol(1,2),
par2sol(1,2),
pararg1(1,2),
pararg2(1,2) {
WellDone = Standard_False;
NbrSol = 0;
IntAna2d_AnaIntersection Intp(Lin1,Lin2);
if (Intp.IsDone()) {
if (Intp.ParallelElements()) {
if (Intp.IdenticalElements()) {
NbrSol = 1;
WellDone = Standard_True;
linsol(NbrSol) = gp_Lin2d(Lin1);
}
else {
// Attention : ne pas utiliser dist = Lin1.Distance(Lin2);
// car les droites sont peut-etre concourrentes pour gp_Lin2d
// d'ou dist = 0.0 (test sur l'angle trop severe ?)
Standard_Real dist = Lin1.Distance(Lin2.Location())/2.0;
Standard_Real cross =
gp_Vec2d ( -Lin2.Direction().Y() , Lin2.Direction().X() )
.Dot ( gp_Vec2d ( Lin2.Location() , Lin1.Location() ) );
if (cross < 0) dist = -dist;
NbrSol++;
WellDone = Standard_True;
linsol(NbrSol) = gp_Lin2d(gp_Pnt2d(Lin2.Location().XY()+
// ========================================================
gp_XY(-Lin2.Direction().Y()*dist,Lin2.Direction().X()*dist)),
// =============================================================
Lin2.Direction());
// =================
}
}
else {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
NbrSol++;
linsol(NbrSol) = gp_Lin2d(Intp.Point(i).Value(),
// ================================================
gp_Dir2d(Lin1.Direction().XY()+Lin2.Direction().XY()));
// ======================================================
NbrSol++;
linsol(NbrSol) = gp_Lin2d(Intp.Point(i).Value(),
// ===============================================
gp_Dir2d(Lin1.Direction().XY()-Lin2.Direction().XY()));
// ======================================================
if (Lin1.Angle(Lin2) >= 0.) { linsol(NbrSol).Reverse(); }
WellDone = Standard_True;
}
}
}
}
for (Standard_Integer i = 1 ; i <= NbrSol ; i++) {
pntint1sol(i) = linsol(i).Location();
pntint2sol(i) = pntint1sol(i);
par1sol(i)=ElCLib::Parameter(linsol(i),pntint1sol(i));
par2sol(i)=ElCLib::Parameter(linsol(i),pntint2sol(i));
pararg1(i)=ElCLib::Parameter(Lin1,pntint1sol(i));
pararg2(i)=ElCLib::Parameter(Lin2,pntint2sol(i));
}
}
//=========================================================================
Standard_Boolean GccAna_Lin2dBisec::
IsDone () const { return WellDone; }
Standard_Integer GccAna_Lin2dBisec::
NbSolutions () const
{
if (!WellDone)
StdFail_NotDone::Raise();
return NbrSol;
}
gp_Lin2d GccAna_Lin2dBisec::
ThisSolution (const Standard_Integer Index) const
{
if (!WellDone)
StdFail_NotDone::Raise();
if (Index <= 0 || Index > NbrSol)
Standard_OutOfRange::Raise();
return linsol(Index);
}
void GccAna_Lin2dBisec::
Intersection1 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
ParSol = par1sol(Index);
ParArg = pararg1(Index);
PntSol = gp_Pnt2d(pntint1sol(Index));
}
}
void GccAna_Lin2dBisec::
Intersection2 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
ParSol = par2sol(Index);
ParArg = pararg2(Index);
PntSol = gp_Pnt2d(pntint2sol(Index));
}
}

170
src/GccAna/GccAna_Lin2dTanObl.cdl Executable file
View File

@@ -0,0 +1,170 @@
-- File: Lin2dTanObl.cdl
-- Created: Wed Apr 3 11:13:00 1991
-- Author: Remi GILET
-- <reg@topsn2>
---Copyright: Matra Datavision 1991
class Lin2dTanObl
from GccAna
---Purpose: This class implements the algorithms used to
-- create 2d line tangent to a circle or a point and
-- making an angle with a line.
-- The angle is in radians.
-- The origin of the solution is the tangency point
-- with the first argument.
-- Its direction is making an angle Angle with the
-- second argument.
--inherits Storable from Standard
uses Lin2d from gp,
Pnt2d from gp,
QualifiedCirc from GccEnt,
Array1OfReal from TColStd,
Array1OfLin2d from TColgp,
Array1OfPnt2d from TColgp,
Position from GccEnt,
Array1OfPosition from GccEnt
raises OutOfRange from Standard,
BadQualifier from GccEnt,
NotDone from StdFail
is
---------------------------------------------------------------------------
Create (ThePoint : Pnt2d from gp ;
TheLine : Lin2d from gp ;
TheAngle : Real from Standard) returns Lin2dTanObl;
---Purpose: This class implements the algorithms used to
-- create 2d line passing through a point and
-- making an angle with a line.
Create (Qualified1 : QualifiedCirc from GccEnt ;
TheLine : Lin2d from gp ;
TheAngle : Real from Standard) returns Lin2dTanObl
raises BadQualifier;
---Purpose: This class implements the algorithms used to
-- create 2d line tangent to a circle and
-- making an angle with a line.
-- Exceptions
-- GccEnt_BadQualifier if a qualifier is inconsistent with
-- the argument it qualifies (for example, enclosed for a circle).
IsDone(me) returns Boolean from Standard
is static;
---Purpose : Returns True if the algorithm succeeded.
-- Note: IsDone protects against a failure arising from a
-- more internal intersection algorithm, which has reached
-- its numeric limits.
NbSolutions(me) returns Integer from Standard
---Purpose : Returns the number of of lines, representing solutions computed by this algorithm.
-- Raises NotDone if the construction algorithm didn't succeed.
raises NotDone
is static;
ThisSolution(me ;
Index : Integer from Standard) returns Lin2d
---Purpose: Returns the solution number Index.
-- Be careful: the Index is only a way to get all the
-- solutions, but is not associated to theses outside the
-- context of the algorithm-object.
-- raises NotDone if the construction algorithm didn't succeed.
-- It raises OutOfRange if Index is greater than the number of solutions.
raises OutOfRange, NotDone
is static;
WhichQualifier(me ;
Index : Integer from Standard;
Qualif1 : out Position from GccEnt )
raises OutOfRange, NotDone
is static;
---Purpose: Returns the qualifier Qualif1 of the tangency argument
-- for the solution of index Index computed by this algorithm.
-- The returned qualifier is:
-- - that specified at the start of construction when the
-- solutions are defined as enclosing or outside with
-- respect to the argument, or
-- - that computed during construction (i.e. enclosing or
-- outside) when the solutions are defined as unqualified
-- with respect to the argument, or
-- - GccEnt_noqualifier if the tangency argument is a point.
-- Exceptions
-- Standard_OutOfRange if Index is less than zero or
-- greater than the number of solutions computed by this algorithm.
-- StdFail_NotDone if the construction fails.
Tangency1(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose : Returns informations about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point ParSol on
-- the solution curv.
-- ParArg is the intrinsic parameter of the point ParArg on
-- the argument curv. Raises NotDone if the construction algorithm
-- didn't succeed.
-- It raises OutOfRange if Index is greater than the number of solutions.
raises OutOfRange, NotDone
is static;
Intersection2 (me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose : Returns informations about the intersection between the
-- result number Index and the third argument.
-- Raises NotDone if the construction algorithm didn't succeed.
-- It raises OutOfRange if Index is greater than the number of solutions.
raises OutOfRange, NotDone
is static;
fields
WellDone : Boolean from Standard;
---Purpose : True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose : The number of possible solutions. We have to decide about the
-- status of the multiple solutions...
linsol : Array1OfLin2d from TColgp;
---Purpose : The solutions.
qualifier1 : Array1OfPosition from GccEnt;
---Purpose: The qualifiers of the first argument.
pnttg1sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the first argument on
-- the solution.
pntint2sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the second argument on
-- the solution.
par1sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution and the
-- first argument on the solution.
par2sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution and the
-- second argument on the solution.
pararg1 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution and the first
-- argument on the first argument.
pararg2 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution and the second
-- argument on the second argument.
end Lin2dTanObl;

253
src/GccAna/GccAna_Lin2dTanObl.cxx Executable file
View File

@@ -0,0 +1,253 @@
//File GccAna_Lin2dTanObl.cxx, REG 08/07/91
//=========================================================================
// CREATION D UNE DROITE TANGENTE A UN CERCLE OU PASSANT PAR UN POINT +
// ET FAISANT UN ANGLE A AVEC UNE DROITE. +
//=========================================================================
#include <GccAna_Lin2dTanObl.ixx>
#include <ElCLib.hxx>
#include <StdFail_NotDone.hxx>
#include <gp_XY.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Circ2d.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
#include <Standard_OutOfRange.hxx>
#include <GccEnt_BadQualifier.hxx>
//=========================================================================
// Creation d une droite passant par un point : ThePoint +
// faisant un angle : TheAngle +
// avec une droite : TheLine. +
// On fait subir a la droite (ThePoint,TheLine.Location()) une rotation +
// d angle TheAngle ==> D1. +
// on cree la droite passant par ThePoint de direction D1. +
//=========================================================================
GccAna_Lin2dTanObl::
GccAna_Lin2dTanObl (const gp_Pnt2d& ThePoint ,
const gp_Lin2d& TheLine ,
const Standard_Real TheAngle ):
linsol(1,1) ,
qualifier1(1,1),
pnttg1sol(1,1) ,
pntint2sol(1,1),
par1sol(1,1) ,
par2sol(1,1) ,
pararg1(1,1) ,
pararg2(1,1)
{
Standard_Real Cosa = TheLine.Direction().X();
Standard_Real Sina = TheLine.Direction().Y();
linsol(1) = gp_Lin2d(ThePoint,
// ==============================
gp_Dir2d(Cosa*Cos(TheAngle)-Sina*Sin(TheAngle),
// ===============================================
Sina*Cos(TheAngle)+Sin(TheAngle)*Cosa));
// =======================================
qualifier1(1) = GccEnt_noqualifier;
pnttg1sol(1) = ThePoint;
IntAna2d_AnaIntersection Intp(linsol(1),TheLine);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
pntint2sol(1) = Intp.Point(i).Value();
}
}
par1sol(1)=ElCLib::Parameter(linsol(1),pnttg1sol(1));
par2sol(1)=ElCLib::Parameter(linsol(1),pntint2sol(1));
pararg1(1)=0.;
pararg2(1)=ElCLib::Parameter(TheLine,pntint2sol(1));
NbrSol = 1;
WellDone = Standard_True;
}
else {
WellDone = Standard_False;
NbrSol=0;
}
}
//=========================================================================
// Creation d une droite tangent a un cercle : Qualified1 (C1) +
// faisant un angle : TheAngle +
// avec une droite : TheLine. +
// On fait subir a la droite (C1.Location,TheLine.Location()) une +
// rotation d angle TheAngle ou -TheAngle ==> D1. +
// on cree la droite passant par C1 de direction D1. +
//=========================================================================
GccAna_Lin2dTanObl::
GccAna_Lin2dTanObl (const GccEnt_QualifiedCirc& Qualified1 ,
const gp_Lin2d& TheLine ,
const Standard_Real TheAngle ):
linsol(1,2) ,
qualifier1(1,2) ,
pnttg1sol(1,2),
pntint2sol(1,2),
par1sol(1,2),
par2sol(1,2),
pararg1(1,2),
pararg2(1,2)
{
WellDone = Standard_False;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
Standard_Real Cosa = TheLine.Direction().X();
Standard_Real Sina = TheLine.Direction().Y();
if (Qualified1.IsEnclosed()) {
// ============================
GccEnt_BadQualifier::Raise();
}
else {
gp_Circ2d C1 = Qualified1.Qualified();
Standard_Real R1 = C1.Radius();
if (Qualified1.IsEnclosing()) {
// =============================
gp_XY xy(Cos(TheAngle)*Cosa-Sin(TheAngle)*Sina,
Cos(TheAngle)*Sina+Sin(TheAngle)*Cosa);
pnttg1sol(1) = gp_Pnt2d(C1.Location().XY()+R1*gp_XY(xy.Y(),-xy.X()));
linsol(1) = gp_Lin2d(pnttg1sol(1),gp_Dir2d(xy));
// ===============================================
qualifier1(1) = Qualified1.Qualifier();
IntAna2d_AnaIntersection Intp(linsol(1),TheLine);
NbrSol = 1;
WellDone = Standard_True;
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
pntint2sol(1) = Intp.Point(i).Value();
}
}
}
}
else if (Qualified1.IsOutside()) {
// ================================
gp_XY xy(Cos(TheAngle)*Cosa-Sin(TheAngle)*Sina,
Cos(TheAngle)*Sina+Sin(TheAngle)*Cosa);
pnttg1sol(1) = gp_Pnt2d(C1.Location().XY()+R1*gp_XY(-xy.Y(),xy.X()));
linsol(1) = gp_Lin2d(pnttg1sol(1),gp_Dir2d(xy));
// ===============================================
qualifier1(1) = Qualified1.Qualifier();
IntAna2d_AnaIntersection Intp(linsol(1),TheLine);
WellDone = Standard_True;
NbrSol = 1;
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
pntint2sol(1) = Intp.Point(i).Value();
}
}
}
}
else if (Qualified1.IsUnqualified()) {
// ====================================
gp_XY xy(Cos(TheAngle)*Cosa-Sin(TheAngle)*Sina,
Cos(TheAngle)*Sina+Sin(TheAngle)*Cosa);
pnttg1sol(1) = gp_Pnt2d(C1.Location().XY()+R1*gp_XY(xy.Y(),-xy.X()));
linsol(1) = gp_Lin2d(pnttg1sol(1),gp_Dir2d(xy));
// ===============================================
qualifier1(1) = GccEnt_enclosing;
IntAna2d_AnaIntersection Intp(linsol(1),TheLine);
WellDone = Standard_True;
NbrSol=1;
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
pntint2sol(1) = Intp.Point(i).Value();
}
}
}
pnttg1sol(2) = gp_Pnt2d(C1.Location().XY()+R1*gp_XY(-xy.Y(),xy.X()));
linsol(2) = gp_Lin2d(pnttg1sol(2),gp_Dir2d(xy));
// ===============================================
qualifier1(2) = GccEnt_outside;
Intp = IntAna2d_AnaIntersection(linsol(1),TheLine);
NbrSol++;
WellDone = Standard_True;
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
pntint2sol(2) = Intp.Point(i).Value();
}
}
}
}
for (Standard_Integer index = 1; index <= NbrSol; index++) {
par1sol(index)=ElCLib::Parameter(linsol(index),pnttg1sol(index));
pararg1(index)=ElCLib::Parameter(C1,pnttg1sol(index));
par2sol(index)=ElCLib::Parameter(linsol(index),pntint2sol(index));
pararg2(index)=ElCLib::Parameter(TheLine,pntint2sol(index));
}
}
}
Standard_Boolean GccAna_Lin2dTanObl::
IsDone () const { return WellDone; }
Standard_Integer GccAna_Lin2dTanObl::
NbSolutions () const
{
if (!WellDone) StdFail_NotDone::Raise();
return NbrSol;
}
gp_Lin2d GccAna_Lin2dTanObl::
ThisSolution (const Standard_Integer Index) const
{
if (!WellDone)
StdFail_NotDone::Raise();
if (Index <= 0 || Index > NbrSol)
Standard_OutOfRange::Raise();
return linsol(Index);
}
void GccAna_Lin2dTanObl::
WhichQualifier(const Standard_Integer Index ,
GccEnt_Position& Qualif1 ) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
Qualif1 = qualifier1(Index);
}
}
void GccAna_Lin2dTanObl::
Tangency1 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
ParSol = par1sol(Index);
ParArg = pararg1(Index);
PntSol = gp_Pnt2d(pnttg1sol(Index));
}
}
void GccAna_Lin2dTanObl::
Intersection2 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
ParSol = par2sol(Index);
ParArg = pararg2(Index);
PntSol = gp_Pnt2d(pntint2sol(Index));
}
}

141
src/GccAna/GccAna_Lin2dTanPar.cdl Executable file
View File

@@ -0,0 +1,141 @@
-- File: Lin2dTanPar.cdl
-- Created: Wed Apr 3 11:10:27 1991
-- Author: Remi GILET
-- <reg@topsn2>
---Copyright: Matra Datavision 1991
class Lin2dTanPar
from GccAna
---Purpose: This class implements the algorithms used to create 2d
-- line tangent to a circle or a point and parallel to
-- another line.
-- The solution has the same orientation as the
-- second argument.
-- Describes functions for building a 2D line parallel to a line and:
-- - tangential to a circle, or
-- - passing through a point.
-- A Lin2dTanPar object provides a framework for:
-- - defining the construction of 2D line(s),
-- - implementing the construction algorithm, and consulting the result(s).
uses Pnt2d from gp,
Lin2d from gp,
QualifiedCirc from GccEnt,
Array1OfReal from TColStd,
Array1OfLin2d from TColgp,
Array1OfPnt2d from TColgp,
Position from GccEnt,
Array1OfPosition from GccEnt
raises OutOfRange from Standard,
BadQualifier from GccEnt,
NotDone from StdFail
is
Create (ThePoint : Pnt2d from gp;
Lin1 : Lin2d from gp) returns Lin2dTanPar;
---Purpose: This method implements the algorithms used to create a 2d
-- line passing through a point and parallel to
-- another line.
Create (Qualified1 : QualifiedCirc from GccEnt;
Lin1 : Lin2d from gp ) returns Lin2dTanPar
raises BadQualifier;
---Purpose: This method implements the algorithms used to create a 2d
-- line tangent to a circle and parallel to another line.
-- It raises BadQualifier in case of EnclosedCirc.
-- Exceptions
-- GccEnt_BadQualifier if a qualifier is inconsistent with
-- the argument it qualifies (for example, enclosed for a circle).
IsDone(me) returns Boolean from Standard
is static;
---Purpose : Returns True if the algorithm succeeded.
NbSolutions(me) returns Integer from Standard
---Purpose : Returns the number of solutions.
-- Raises NotDone if the construction algorithm didn't succeed.
raises NotDone
is static;
ThisSolution(me ;
Index : Integer from Standard) returns Lin2d
---Purpose : Returns the solution number Index and raises OutOfRange
-- exception if Index is greater than the number of solutions.
-- Be careful: the Index is only a way to get all the
-- solutions, but is not associated to those outside the
-- context of the algorithm-object.
-- raises NotDone if the construction algorithm
-- didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
WhichQualifier(me ;
Index : Integer from Standard;
Qualif1 : out Position from GccEnt )
raises OutOfRange, NotDone
is static;
---Purpose: Returns the informations about the qualifiers of the
-- tangency arguments concerning the solution number Index.
-- It returns the real qualifiers (the qualifiers given to the
-- constructor method in case of enclosed, enclosing and outside
-- and the qualifiers computed in case of unqualified).
-- Raises NotDone if the construction algorithm
-- didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
Tangency1(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
Pnt : out Pnt2d from gp )
---Purpose : Returns informations about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point on the
-- solution curv.
-- ParArg is the intrinsic parameter of the point on the
-- argument curv.
-- ParArg is equal 0 when the solution is passing thrue
-- a point. Raises NotDone if the construction algorithm
-- didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose : The number of possible solutions. We have to decide
-- about the status of the multiple solutions...
linsol : Array1OfLin2d from TColgp;
---Purpose: The solutions.
qualifier1 : Array1OfPosition from GccEnt;
---Purpose: The qualifiers of the first argument.
pnttg1sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the
-- first argument on the solution.
par1sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the
-- solution and the first argument on the solution.
pararg1 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the
-- solution and the first argument on the first argument.
end Lin2dTanPar;

154
src/GccAna/GccAna_Lin2dTanPar.cxx Executable file
View File

@@ -0,0 +1,154 @@
// File GccAna_Lin2dTanPar.cxx, REG 08/07/91
//========================================================================
// CREATION D UNE LIGNE TANGENTE A UN CERCLE OU PASSANT PAR UN POINT +
// ET PARALLELE A UNE DROITE. +
//========================================================================
#include <GccAna_Lin2dTanPar.ixx>
#include <ElCLib.hxx>
#include <StdFail_NotDone.hxx>
#include <gp_XY.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Circ2d.hxx>
#include <Standard_OutOfRange.hxx>
#include <GccEnt_BadQualifier.hxx>
//========================================================================
// Passant par un point : +
// On cree la droite d origine ThePoint et +
// de direction Lin1.Direction(). +
//========================================================================
GccAna_Lin2dTanPar::
GccAna_Lin2dTanPar (const gp_Pnt2d& ThePoint ,
const gp_Lin2d& Lin1 ):
linsol(1,1),
qualifier1(1,1) ,
pnttg1sol(1,1),
par1sol(1,1),
pararg1(1,1)
{
linsol(1) = gp_Lin2d(ThePoint,Lin1.Direction());
// ===============================================
qualifier1(1) = GccEnt_noqualifier;
pnttg1sol(1) = ThePoint;
par1sol(1) = 0.;
pararg1(1) = 0.;
NbrSol = 1;
WellDone = Standard_True;
}
//========================================================================
// Tangent a un cercle : +
// On cree suivant le qualifieur la droite +
// - d origine P1 (P1 est un point d intersection entre C1 et +
// une droite passant par le centre de C1 et de +
// direction la normale a Lin1). +
// le choix du point d intersection est fonction +
// du qualifieur. +
// - de direction la direction de Lin1. +
//========================================================================
GccAna_Lin2dTanPar::
GccAna_Lin2dTanPar (const GccEnt_QualifiedCirc& Qualified1,
const gp_Lin2d& Lin1 ):
linsol(1,2),
qualifier1(1,2) ,
pnttg1sol(1,2),
par1sol(1,2),
pararg1(1,2)
{
WellDone = Standard_False;
Standard_Integer signe = 0;
Standard_Integer nbsol = 0;
NbrSol = 0;
if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
GccEnt_BadQualifier::Raise();
return;
}
gp_Circ2d C1 = Qualified1.Qualified();
Standard_Real xdir = (Lin1.Direction()).X();
Standard_Real ydir = (Lin1.Direction()).Y();
if (Qualified1.IsEnclosed()) { GccEnt_BadQualifier::Raise(); }
// ============================
else if (Qualified1.IsEnclosing()) {
// ==================================
nbsol = 1;
signe = 1;
qualifier1(1) = GccEnt_enclosing;
}
else if (Qualified1.IsOutside()) {
// ===================================
nbsol = 1;
signe = -1;
qualifier1(1) = GccEnt_outside;
}
else {
nbsol = 2;
signe = -1;
qualifier1(1) = GccEnt_outside;
qualifier1(2) = GccEnt_enclosing;
}
gp_XY xy(-C1.Radius()*ydir,C1.Radius()*xdir);
for (Standard_Integer j = 1 ; j <= nbsol ; j++) {
signe = -signe;
NbrSol++;
linsol(NbrSol) = gp_Lin2d(gp_Pnt2d((C1.Location().XY()).Added(signe*xy)),
// =========================================================================
Lin1.Direction());
// =================
pnttg1sol(NbrSol) = gp_Pnt2d((C1.Location().XY()).Added(signe*xy));
par1sol(NbrSol) = 0.;
pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
WellDone = Standard_True;
}
}
Standard_Boolean GccAna_Lin2dTanPar::
IsDone () const { return WellDone; }
Standard_Integer GccAna_Lin2dTanPar::NbSolutions () const
{
if (!WellDone)
StdFail_NotDone::Raise();
return NbrSol;
}
gp_Lin2d GccAna_Lin2dTanPar::ThisSolution (const Standard_Integer Index) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 || Index > NbrSol) { Standard_OutOfRange::Raise(); }
return linsol(Index);
}
void GccAna_Lin2dTanPar::
WhichQualifier(const Standard_Integer Index ,
GccEnt_Position& Qualif1 ) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
Qualif1 = qualifier1(Index);
}
}
void GccAna_Lin2dTanPar::
Tangency1 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& Pnt) const {
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
ParSol = par1sol(Index);
ParArg = pararg1(Index);
Pnt = gp_Pnt2d(pnttg1sol(Index));
}
}

196
src/GccAna/GccAna_Lin2dTanPer.cdl Executable file
View File

@@ -0,0 +1,196 @@
-- File: Lin2dTanPer.cdl
-- Created: Wed Apr 3 11:05:31 1991
-- Author: Remi GILET
-- <reg@topsn2>
---Copyright: Matra Datavision 1991
class Lin2dTanPer
from GccAna
---Purpose: This class implements the algorithms used to
-- create 2d lines tangent to a circle or a point and
-- perpendicular to a line or a circle.
-- Describes functions for building a 2D line perpendicular
-- to a line and:
-- - tangential to a circle, or
-- - passing through a point.
-- A Lin2dTanPer object provides a framework for:
-- - defining the construction of 2D line(s),
-- - implementing the construction algorithm, and
-- - consulting the result(s).
--inherits Storable from Standard
uses Pnt2d from gp,
Lin2d from gp,
Circ2d from gp,
QualifiedCirc from GccEnt,
Array1OfReal from TColStd,
Array1OfLin2d from TColgp,
Array1OfPnt2d from TColgp,
Position from GccEnt,
Array1OfPosition from GccEnt
raises BadQualifier from GccEnt,
OutOfRange from Standard,
ConstructionError from Standard,
NotDone from StdFail
is
Create(ThePnt : Pnt2d from gp;
TheLin : Lin2d from gp) returns Lin2dTanPer;
---Purpose: This method implements the algorithms used to
-- create 2d lines passing through a point and
-- perpendicular to a line.
Create(ThePnt : Pnt2d from gp;
TheCircle : Circ2d from gp) returns Lin2dTanPer
raises ConstructionError;
---Purpose: This method implements the algorithms used to
-- create 2d lines passing through a point and
-- perpendicular to a circle.
Create(Qualified1 : QualifiedCirc from GccEnt;
TheLin : Lin2d from gp ) returns Lin2dTanPer
raises BadQualifier;
-- Raises BadQualifier in case of EnclosedCirc.
---Purpose: This method implements the algorithms used to
-- create 2d lines tangent to a circle and
-- perpendicular to a line.
Create(Qualified1 : QualifiedCirc from GccEnt;
TheCircle : Circ2d from gp ) returns Lin2dTanPer
raises BadQualifier,ConstructionError;
-- Raises BadQualifier in case of EnclosedCirc.
---Purpose: This method implements the algorithms used to
-- create 2d lines tangent to a circle and
-- perpendicular to a circle.
-- .........................................................................
IsDone(me) returns Boolean from Standard
is static;
---Purpose : Returns True if the algorithm succeeded.
NbSolutions(me) returns Integer from Standard
---Purpose : Returns the number of solutions.
-- Raises NotDone if the construction algorithm didn't succeed.
raises NotDone
is static;
WhichQualifier(me ;
Index : Integer from Standard;
Qualif1 : out Position from GccEnt )
raises OutOfRange, NotDone
is static;
---Purpose: Returns the qualifier Qualif1 of the tangency argument
-- for the solution of index Index computed by this algorithm.
-- The returned qualifier is:
-- - that specified at the start of construction when the
-- solutions are defined as enclosing or outside with
-- respect to the argument, or
-- - that computed during construction (i.e. enclosing or
-- outside) when the solutions are defined as unqualified
-- with respect to the argument, or
-- - GccEnt_noqualifier if the tangency argument is a point.
-- Exceptions
-- Standard_OutOfRange if Index is less than zero or
-- greater than the number of solutions computed by this algorithm.
-- StdFail_NotDone if the construction fails.
ThisSolution(me ;
Index : Integer from Standard) returns Lin2d from gp
---Purpose : Returns the solution number Index and raises OutOfRange
-- exception if Index is greater than the number of solutions.
-- Be careful: the Index is only a way to get all the
-- solutions, but is not associated to those outside the
-- context of the algorithm-object.
-- Raises NotDone if the construction algorithm
-- didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
Tangency1(me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
Pnt : out Pnt2d from gp )
---Purpose : Returns informations about the tangency point between the
-- result number Index and the first argument.
-- ParSol is the intrinsic parameter of the point on the
-- solution curv.
-- ParArg is the intrinsic parameter of the point on the
-- argument curv.
-- If the first argument is a point ParArg is equal zero.
-- raises NotDone if the construction algorithm didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
Intersection2 (me ;
Index : Integer from Standard;
ParSol,ParArg : out Real from Standard;
PntSol : out Pnt2d from gp )
---Purpose : Returns informations about the intersection between the
-- solution number Index and the second argument.
-- It returns the first intersection in a case of
-- Lin2dTanPer which is perpendicular to a circle .
-- ParSol is the intrinsic parameter of the point on the
-- solution curv.
-- ParArg is the intrinsic parameter of the point on the
-- argument curv. Raises NotDone if the construction algorithm
-- didn't succeed.
-- It raises OutOfRange if Index is greater than the
-- number of solutions.
raises OutOfRange, NotDone
is static;
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
NbrSol : Integer from Standard;
---Purpose: The number of possible solutions. We have to decide
-- about the status of the multiple solutions...
linsol : Array1OfLin2d from TColgp;
---Purpose: The solutions.
qualifier1 : Array1OfPosition from GccEnt;
---Purpose: The qualifiers of the first argument.
pnttg1sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the first
-- argument on the solution.
pntint2sol : Array1OfPnt2d from TColgp;
---Purpose: The tangency point between the solution and the second
-- argument on the solution.
par1sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the solution.
par2sol : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the second argument on the solution.
pararg1 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the first argument on the first argument.
pararg2 : Array1OfReal from TColStd;
---Purpose: The parameter of the tangency point between the solution
-- and the second argument on the second argument.
end Lin2dTanPer;

311
src/GccAna/GccAna_Lin2dTanPer.cxx Executable file
View File

@@ -0,0 +1,311 @@
// File GccAna_Lin2dTanPer.cxx, REG 08/07/91
//=========================================================================
// CREATION D UNE DROITE TANGENTE A UN CERCLE OU PASSANT PAR UN POINT +
// ET ORTHOGONALE A UNE DROITE. +
//=========================================================================
#include <GccAna_Lin2dTanPer.ixx>
#include <ElCLib.hxx>
#include <StdFail_NotDone.hxx>
#include <gp_XY.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Circ2d.hxx>
#include <Standard_OutOfRange.hxx>
#include <GccEnt_BadQualifier.hxx>
#include <IntAna2d_AnaIntersection.hxx>
#include <IntAna2d_IntPoint.hxx>
//=========================================================================
// Droite passant par un point : ThePoint et +
// orthogonale a une droite : TheLin. +
// On cree la droite d origine : ThePoint +
// et de direction : TheLin.Direction() tournee de 90 +
//=========================================================================
GccAna_Lin2dTanPer::
GccAna_Lin2dTanPer (const gp_Pnt2d& ThePnt ,
const gp_Lin2d& TheLin ):
linsol(1,1),
qualifier1(1,1) ,
pnttg1sol(1,1),
pntint2sol(1,1),
par1sol(1,1),
par2sol(1,1),
pararg1(1,1),
pararg2(1,1)
{
linsol(1) = gp_Lin2d(ThePnt,gp_Dir2d(-(TheLin.Direction().Y()),
// ===============================================================
TheLin.Direction().X()));
// ========================
pnttg1sol(1) = ThePnt;
IntAna2d_AnaIntersection Intp(linsol(1),TheLin);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
pntint2sol(1) = Intp.Point(i).Value();
}
}
}
par1sol(1) = ElCLib::Parameter(linsol(1),pnttg1sol(1));
par2sol(1) = ElCLib::Parameter(linsol(1),pntint2sol(1));
pararg1(1) = 0.;
pararg2(1) = ElCLib::Parameter(TheLin,pntint2sol(1));
NbrSol = 1;
WellDone = Standard_True;
}
//=========================================================================
// Droite passant par un point : ThePnt +
// et orthogonale a un cercle : TheCircle. +
// On cree la droite d origine : ThePoint +
// et de direction : (TheCircle.Location(),ThePnt). +
//=========================================================================
GccAna_Lin2dTanPer::
GccAna_Lin2dTanPer (const gp_Pnt2d& ThePnt ,
const gp_Circ2d& TheCircle ):
linsol(1,1),
qualifier1(1,1) ,
pnttg1sol(1,1),
pntint2sol(1,1),
par1sol(1,1),
par2sol(1,1),
pararg1(1,1),
pararg2(1,1)
{
linsol(1) = gp_Lin2d(ThePnt,
// ============================
gp_Dir2d(TheCircle.Location().XY()-ThePnt.XY()));
// ================================================
pnttg1sol(1) = ThePnt;
IntAna2d_AnaIntersection Intp(linsol(1),TheCircle);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
Standard_Real maxdist = RealLast();
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
if (Intp.Point(i).Value().Distance(ThePnt) < maxdist) {
pntint2sol(1) = Intp.Point(i).Value();
}
}
}
}
par1sol(1) = ElCLib::Parameter(linsol(1),pnttg1sol(1));
par2sol(1) = ElCLib::Parameter(linsol(1),pntint2sol(1));
pararg1(1) = 0.;
pararg2(1) = ElCLib::Parameter(TheCircle,pntint2sol(1));
NbrSol = 1;
WellDone = Standard_True;
}
//=========================================================================
// Droite tangente a un cercle : Qualified1 (C1) +
// et orthogonale a une droite : TheLin. +
// On cree la droite d origine : P1 (sur C1) +
// et de direction : TheLin.Direction() tournee de 90` +
//=========================================================================
GccAna_Lin2dTanPer::
GccAna_Lin2dTanPer (const GccEnt_QualifiedCirc& Qualified1,
const gp_Lin2d& TheLin ):
linsol(1,2),
qualifier1(1,2) ,
pnttg1sol(1,2),
pntint2sol(1,2),
par1sol(1,2),
par2sol(1,2),
pararg1(1,2),
pararg2(1,2)
{
WellDone = Standard_False;
Standard_Integer nbsol = 0;
Standard_Integer signe = 0;
NbrSol = 0;
gp_Circ2d C1 = Qualified1.Qualified();
if (Qualified1.IsEnclosed()) {
// ============================
GccEnt_BadQualifier::Raise();
}
else if (Qualified1.IsEnclosing()) {
// ==================================
nbsol = 1;
signe = -1;
}
else if (Qualified1.IsOutside()) {
// ================================
nbsol = 1;
signe = 1;
}
else {
nbsol = 2;
signe = -1;
}
gp_XY xy(C1.Radius()*TheLin.Direction().XY());
for (Standard_Integer j = 1 ; j <= nbsol ; j++) {
signe = -signe;
NbrSol++;
linsol(NbrSol)=gp_Lin2d(gp_Pnt2d((C1.Location().XY()).Added(signe*xy)),
// =======================================================================
gp_Dir2d(-TheLin.Direction().Y(),
// =================================
TheLin.Direction().X()));
// ========================
pnttg1sol(NbrSol) = gp_Pnt2d((C1.Location().XY()).Added(signe*xy));
IntAna2d_AnaIntersection Intp(linsol(NbrSol),TheLin);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
pntint2sol(NbrSol) = Intp.Point(i).Value();
}
}
}
par1sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pnttg1sol(NbrSol));
par2sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pntint2sol(NbrSol));
pararg1(NbrSol) = ElCLib::Parameter(C1,pnttg1sol(NbrSol));
pararg2(NbrSol) = ElCLib::Parameter(TheLin,pntint2sol(NbrSol));
WellDone = Standard_True;
}
}
//=========================================================================
// Droite tangente a un cercle : Qualified1 (C1) +
// et orthogonale a un cercle : TheCircle. +
// On cree la droite d origine : P1 (sur C1) +
// et de direction : TheLin.Direction() tournee de 90` +
//=========================================================================
GccAna_Lin2dTanPer::
GccAna_Lin2dTanPer (const GccEnt_QualifiedCirc& Qualified1,
const gp_Circ2d& TheCircle ):
linsol(1,2),
qualifier1(1,2) ,
pnttg1sol(1,2),
pntint2sol(1,2),
par1sol(1,2),
par2sol(1,2),
pararg1(1,2),
pararg2(1,2)
{
WellDone = Standard_False;
NbrSol = 0;
Standard_Integer nbsol = 0;
Standard_Integer signe = 0;
gp_Circ2d C1 = Qualified1.Qualified();
if (Qualified1.IsEnclosed()) {
// ============================
GccEnt_BadQualifier::Raise();
}
else if (Qualified1.IsEnclosing()) {
// ==================================
nbsol = 1;
signe = -1;
qualifier1(1) = GccEnt_enclosing;
}
else if (Qualified1.IsOutside()) {
// ================================
nbsol = 1;
signe = 1;
qualifier1(1) = GccEnt_outside;
}
else if (Qualified1.IsUnqualified()) {
// ====================================
nbsol = 2;
signe = -1;
qualifier1(1) = GccEnt_enclosing;
qualifier1(2) = GccEnt_outside;
}
for (Standard_Integer j = 1 ; j <= 2 ; j++) {
NbrSol++;
signe = -signe;
gp_Dir2d D1(TheCircle.Location().XY()-C1.Location().XY());
linsol(NbrSol) = gp_Lin2d(gp_Pnt2d((C1.Location().XY())+
// ===================================================
signe*(D1.XY()*C1.Radius())),gp_Dir2d(-D1.Y(),D1.X()));
// ======================================================
pnttg1sol(NbrSol) = gp_Pnt2d((C1.Location().XY())+
signe*(D1.XY()*C1.Radius()));
IntAna2d_AnaIntersection Intp(linsol(NbrSol),TheCircle);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
Standard_Real maxdist = RealLast();
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
if (Intp.Point(i).Value().Distance(pnttg1sol(NbrSol)) < maxdist) {
pntint2sol(NbrSol) = Intp.Point(i).Value();
}
}
}
}
par1sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pnttg1sol(NbrSol));
par2sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pntint2sol(NbrSol));
pararg1(NbrSol) = ElCLib::Parameter(C1,pnttg1sol(NbrSol));
pararg2(NbrSol) = ElCLib::Parameter(TheCircle,pntint2sol(NbrSol));
WellDone = Standard_True;
}
}
Standard_Boolean GccAna_Lin2dTanPer::
IsDone () const { return WellDone; }
Standard_Integer GccAna_Lin2dTanPer::
NbSolutions () const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
return NbrSol;
}
gp_Lin2d GccAna_Lin2dTanPer::
ThisSolution (const Standard_Integer Index) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
if (Index <= 0 || Index > NbrSol) { Standard_RangeError::Raise(); }
return linsol(Index);
}
void GccAna_Lin2dTanPer::
WhichQualifier(const Standard_Integer Index ,
GccEnt_Position& Qualif1 ) const
{
if (!WellDone) { StdFail_NotDone::Raise(); }
if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
Qualif1 = qualifier1(Index);
}
}
void GccAna_Lin2dTanPer::
Tangency1 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& Pnt) const{
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
ParSol = par1sol(Index);
ParArg = pararg1(Index);
Pnt = gp_Pnt2d(pnttg1sol(Index));
}
}
void GccAna_Lin2dTanPer::
Intersection2 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const {
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
else {
ParSol = par2sol(Index);
ParArg = pararg2(Index);
PntSol = gp_Pnt2d(pntint2sol(Index));
}
}

View File

@@ -0,0 +1,57 @@
-- File: LinPnt2dBisec.cdl
-- Created: Wed Apr 3 11:29:37 1991
-- Author: Remi GILET
-- <reg@topsn2>
---Copyright: Matra Datavision 1991
class LinPnt2dBisec
from GccAna
---Purpose: Describes functions for building bisecting curves between a 2D line and a point.
-- A bisecting curve between a line and a point is such a
-- curve that each of its points is at the same distance from
-- the circle and the point. It can be a parabola or a line,
-- depending on the relative position of the line and the
-- circle. There is always one unique solution.
-- A LinPnt2dBisec object provides a framework for:
-- - defining the construction of the bisecting curve,
-- - implementing the construction algorithm, and
-- - consulting the result.
--inherits Storable from Standard
uses Lin2d from gp,
Pnt2d from gp,
Bisec from GccInt
raises ConstructionError from Standard,
NotDone from StdFail
is
Create(Line1 : Lin2d from gp;
Point2 : Pnt2d from gp) returns LinPnt2dBisec
raises ConstructionError;
---Purpose: Constructs a bisecting curve between the line Line1 and the point Point2.
IsDone(me) returns Boolean from Standard
is static;
---Purpose : Returns True if the algorithm succeeded.
ThisSolution(me) returns Bisec from GccInt
---Purpose : Returns the number of solutions.
raises NotDone
is static;
---Purpose: It raises NotDone if the construction algorithm didn't succeed.
fields
WellDone : Boolean from Standard;
---Purpose: True if the algorithm succeeded.
bissol : Bisec from GccInt;
---Purpose : The solutions.
end LinPnt2dBisec;

View File

@@ -0,0 +1,79 @@
// File: GccAna_LinPnt2dBisec.cxx
// Created: Fri Oct 4 09:53:31 1991
// Author: Remi GILET
// <reg@phobox>
//=========================================================================
// CREATION DE LA BISSECTRICE ENTRE UNE DROITE ET UN POINTS. +
//=========================================================================
#include <GccAna_LinPnt2dBisec.ixx>
#include <gp_XY.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Ax2d.hxx>
#include <GccInt_BParab.hxx>
#include <GccInt_BLine.hxx>
#include <Standard_ConstructionError.hxx>
#include <StdFail_NotDone.hxx>
#include <gp.hxx>
//=========================================================================
GccAna_LinPnt2dBisec::
GccAna_LinPnt2dBisec (const gp_Lin2d& Line1 ,
const gp_Pnt2d& Point2) {
WellDone = Standard_False;
Standard_Real xdir = Line1.Direction().X();
Standard_Real ydir = Line1.Direction().Y();
Standard_Real xloc = Line1.Location().X();
Standard_Real yloc = Line1.Location().Y();
Standard_Real dist = Line1.Distance(Point2);
// if ( dist > gp::Resolution()) {
if ( dist > 1.e-10)
{
Standard_Real xpoint2 = Point2.X();
Standard_Real ypoint2 = Point2.Y();
if ((-ydir*(xpoint2-xloc)+xdir*(ypoint2-yloc)) > 0.0)
{
gp_Ax2d axeparab(gp_Pnt2d(Point2.XY()-dist/2.*gp_XY(-ydir,xdir)),
gp_Dir2d(-ydir,xdir));
gp_Parab2d bislinpnt(axeparab,dist/2.0);
bissol = new GccInt_BParab(bislinpnt);
// =====================================
}
else
{
gp_Ax2d axeparab(gp_Pnt2d(Point2.XY()+dist/2.*gp_XY(-ydir,xdir)),
gp_Dir2d(ydir,-xdir));
gp_Parab2d bislinpnt(axeparab,dist/2.0);
bissol = new GccInt_BParab(bislinpnt);
// =====================================
}
WellDone = Standard_True;
}
else
{
gp_Lin2d bislinpnt(Point2,gp_Dir2d(-ydir,xdir));
bissol = new GccInt_BLine(bislinpnt);
// ====================================
WellDone = Standard_True;
}
}
//=========================================================================
Standard_Boolean GccAna_LinPnt2dBisec::
IsDone () const { return WellDone; }
Handle(GccInt_Bisec) GccAna_LinPnt2dBisec::
ThisSolution () const
{
if (!WellDone)
StdFail_NotDone::Raise();
return bissol;
}

View File

@@ -0,0 +1,61 @@
-- File: Pnt2dBisec.cdl
-- Created: Wed Apr 3 11:29:37 1991
-- Author: Remi GILET
-- <reg@topsn2>
---Copyright: Matra Datavision 1991
class Pnt2dBisec
from GccAna
---Purpose: This class implements the algorithms used to
-- create the bisecting line between two 2d points
-- Describes functions for building a bisecting line between two 2D points.
-- The bisecting line between two points is the bisector of
-- the segment which joins the two points, if these are not coincident.
-- The algorithm does not find a solution if the two points are coincident.
-- A Pnt2dBisec object provides a framework for:
-- - defining the construction of the bisecting line,
-- - implementing the construction algorithm, and consulting the result.
uses Pnt2d from gp,
Lin2d from gp
raises NotDone from StdFail
is
Create(Point1 : Pnt2d from gp ;
Point2 : Pnt2d from gp ) returns Pnt2dBisec;
---Purpose: Constructs a bisecting line between the points Point1 and Point2.
IsDone(me) returns Boolean from Standard
is static;
---Purpose: Returns true (this construction algorithm never fails).
HasSolution(me) returns Boolean from Standard
is static;
---Purpose: Returns true if this algorithm has a solution, i.e. if the
-- two points are not coincident.
ThisSolution(me) returns Lin2d from gp
raises NotDone
is static;
---Purpose : Returns a line, representing the solution computed by this algorithm.
fields
WellDone : Boolean from Standard;
-- True if the algorithm succeeded.
HasSol : Boolean from Standard;
-- True if there is a solution.
linsol : Lin2d from gp;
---Purpose : The solutions.
end Pnt2dBisec;

View File

@@ -0,0 +1,59 @@
// File: GccAna_Pnt2dBisec.cxx
// Created: Fri Oct 4 09:53:31 1991
// Author: Remi GILET
// <reg@phobox>
//=========================================================================
// CREATION DE LA BISSECTRICE ENTRE DEUX POINTS. +
//=========================================================================
#include <GccAna_Pnt2dBisec.ixx>
#include <gp_XY.hxx>
#include <gp_Dir2d.hxx>
#include <Standard_ConstructionError.hxx>
#include <StdFail_NotDone.hxx>
#include <GccAna_NoSolution.hxx>
#include <gp.hxx>
//=========================================================================
GccAna_Pnt2dBisec::
GccAna_Pnt2dBisec (const gp_Pnt2d& Point1,
const gp_Pnt2d& Point2) {
WellDone = Standard_False;
// if (Point1.Distance(Point2) > gp::Resolution()) {
if (Point1.Distance(Point2) > 1.e-10) {
gp_Dir2d dir1(Point2.XY()-Point1.XY());
linsol = gp_Lin2d(gp_Pnt2d((Point2.X()+Point1.X())/2.,
// ======================================================
(Point2.Y()+Point1.Y())/2.),
// ============================
gp_Dir2d(-dir1.Y(),dir1.X()));
// =============================
HasSol = Standard_True;
WellDone = Standard_True;
}
else {
HasSol = Standard_False;
WellDone = Standard_True;
}
}
//=========================================================================
Standard_Boolean GccAna_Pnt2dBisec::
IsDone () const { return WellDone; }
Standard_Boolean GccAna_Pnt2dBisec::
HasSolution () const { return HasSol; }
gp_Lin2d GccAna_Pnt2dBisec::
ThisSolution () const {
if (!WellDone) { StdFail_NotDone::Raise(); }
else if (!HasSol) { GccAna_NoSolution::Raise(); }
return linsol;
}