1 // File: GccAna_Circ2d2TanOn_10.cxx
2 // Created: Thu Jan 2 16:00:00 1992
6 #include <GccAna_Circ2d2TanOn.jxx>
9 #include <gp_Dir2d.hxx>
10 #include <gp_Ax2d.hxx>
11 #include <IntAna2d_AnaIntersection.hxx>
12 #include <IntAna2d_IntPoint.hxx>
13 #include <GccAna_LinPnt2dBisec.hxx>
14 #include <GccInt_IType.hxx>
15 #include <GccInt_Bisec.hxx>
16 #include <GccInt_BLine.hxx>
17 #include <IntAna2d_Conic.hxx>
18 #include <GccEnt_BadQualifier.hxx>
20 //=========================================================================
21 // Creation d un cercle tangent a une Droite L1 et a un point Point2. +
22 // centre sur un cercle. +
23 // Nous commencons par distinguer les differents cas limites que nous +
24 // allons traiter separement. +
25 // Pour le cas general: +
26 // ==================== +
27 // Nous calculons les bissectrices a L1 et Point2 qui nous donnent +
28 // l ensemble des lieux possibles des centres de tous les cercles +
29 // tangents a L1 et Point2. +
30 // Nous intersectons ces bissectrices avec le cerclee OnCirc ce qui nous +
31 // donne les points parmis lesquels nous allons choisir les solutions. +
32 // Les choix s effectuent a partir des Qualifieurs qualifiant L1. +
33 //=========================================================================
36 GccAna_Circ2d2TanOn (const GccEnt_QualifiedLin& Qualified1 ,
37 const gp_Pnt2d& Point2 ,
38 const gp_Circ2d& OnCirc ,
39 const Standard_Real Tolerance ):
57 WellDone = Standard_False;
59 if (!(Qualified1.IsEnclosed() ||
60 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
61 GccEnt_BadQualifier::Raise();
64 Standard_Real Tol = Abs(Tolerance);
66 gp_Lin2d L1 = Qualified1.Qualified();
67 gp_Pnt2d originL1(L1.Location());
68 gp_Dir2d dirL1(L1.Direction());
69 gp_Dir2d normL1(-dirL1.Y(),dirL1.X());
71 //=========================================================================
72 // Traitement des cas limites. +
73 //=========================================================================
75 Standard_Real Ron = OnCirc.Radius();
76 Standard_Real distpc = OnCirc.Location().Distance(Point2);
77 gp_Dir2d dir(OnCirc.Location().XY()-Point2.XY());
78 gp_Pnt2d pinterm(Point2.XY()+(distpc+Ron)*dir.XY());
79 Standard_Real dist1 = L1.Distance(pinterm);
80 if (Abs(dist1-distpc-Ron) > Tol) {
82 gp_Pnt2d pinterm(Point2.XY()+(distpc-Ron)*dir.XY()); // Unused ! BUG ???
83 Standard_Real dist1 = L1.Distance(pinterm); // Unused ! BUG ???
86 if (Abs(dist1-distpc+Ron) <= Tol) {
87 dir = gp_Dir2d(-dirL1.Y(),dirL1.X());
88 gp_Dir2d direc(originL1.XY()-pinterm.XY());
89 if (Qualified1.IsOutside()) {
90 if (direc.Dot(dir) >= 0.0) { WellDone = Standard_True; }
92 else if (Qualified1.IsEnclosed()) {
93 if (direc.Dot(dir) <= 0.0) { WellDone = Standard_True; }
95 else { WellDone = Standard_True; }
98 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(pinterm,dirx),dist1);
99 // =======================================================
100 gp_Dir2d dc1(originL1.XY()-pinterm.XY());
101 Standard_Real sign = dc1.Dot(normL1);
102 if (!Qualified1.IsUnqualified()) {
103 qualifier1(NbrSol) = Qualified1.Qualifier();
105 else if (dc1.Dot(normL1) > 0.0) { qualifier1(NbrSol) = GccEnt_outside; }
106 else { qualifier1(NbrSol) = GccEnt_enclosed; }
107 qualifier2(NbrSol) = GccEnt_noqualifier;
108 dc1 = gp_Dir2d(sign*gp_XY(-dirL1.Y(),dirL1.X()));
109 pnttg1sol(NbrSol) = gp_Pnt2d(pinterm.XY()+dist1*dc1.XY());
110 par1sol(NbrSol) = ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
111 pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
112 pntcen(NbrSol) = pinterm;
113 parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen(NbrSol));
114 parcen3(NbrSol) = 0.;
115 pnttg2sol(NbrSol) = Point2;
116 pararg2(NbrSol) = 0.;
117 par2sol(NbrSol) = ElCLib::Parameter(cirsol(NbrSol),pnttg2sol(NbrSol));
122 //=========================================================================
124 //=========================================================================
126 GccAna_LinPnt2dBisec Bis(L1,Point2);
128 Handle(GccInt_Bisec) Sol = Bis.ThisSolution();
129 GccInt_IType type = Sol->ArcType();
130 IntAna2d_AnaIntersection Intp;
131 if (type == GccInt_Lin) {
132 Intp.Perform(Sol->Line(),OnCirc);
134 if (type == GccInt_Par) {
135 Intp.Perform(OnCirc,IntAna2d_Conic(Sol->Parabola()));
138 if (!Intp.IsEmpty()) {
139 for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
140 gp_Pnt2d Center(Intp.Point(j).Value());
141 Standard_Real Radius = L1.Distance(Center);
142 // Standard_Integer nbsol = 1;
143 Standard_Boolean ok = Standard_False;
144 if (Qualified1.IsEnclosed()) {
145 if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
146 ((originL1.Y()-Center.Y())*(dirL1.X())))<=0){
150 else if (Qualified1.IsOutside()) {
151 if ((((originL1.X()-Center.X())*(-dirL1.Y()))+
152 ((originL1.Y()-Center.Y())*(dirL1.X())))>=0){
156 else if (Qualified1.IsUnqualified()) {
161 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
162 // =======================================================
163 TheSame1(NbrSol) = 0;
164 TheSame2(NbrSol) = 0;
165 gp_Dir2d dc1(originL1.XY()-Center.XY());
166 Standard_Real sign = dc1.Dot(normL1);
167 if (!Qualified1.IsUnqualified()) {
168 qualifier1(NbrSol) = Qualified1.Qualifier();
170 else if (dc1.Dot(normL1) > 0.0) {
171 qualifier1(NbrSol) = GccEnt_outside;
173 else { qualifier1(NbrSol) = GccEnt_enclosed; }
174 qualifier2(NbrSol) = GccEnt_noqualifier;
175 dc1=gp_Dir2d(sign*gp_XY(-dirL1.Y(),dirL1.X()));
176 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+dist1*dc1.XY());
177 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
179 pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
180 pntcen(NbrSol) = Center;
181 parcen3(NbrSol) = ElCLib::Parameter(OnCirc,pntcen(NbrSol));
182 pnttg2sol(NbrSol) = Point2;
183 pararg2(NbrSol) = 0.;
184 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
186 qualifier2(NbrSol) = GccEnt_noqualifier;
190 WellDone = Standard_True;