1 // File: GccAna_Circ2d2TanRad_2.cxx
2 // Created: Tue Sep 24 09:12:49 1991
6 #include <GccAna_Circ2d2TanRad.jxx>
8 #include <gp_Circ2d.hxx>
10 #include <gp_Dir2d.hxx>
11 #include <gp_Lin2d.hxx>
12 #include <IntAna2d_AnaIntersection.hxx>
13 #include <IntAna2d_IntPoint.hxx>
14 #include <Standard_NegativeValue.hxx>
15 #include <GccEnt_BadQualifier.hxx>
17 // circulare tangent to a circle a point and a given radius
18 //=============================================================
20 //========================================================================
21 // Initialize WellDone to false. +
22 // Return circle C1. +
23 // Leave with error if the construction is impossible. +
24 // Create parallel to C1 in the proper direction. +
25 // Create circle with center in Point1 of radius Radius. +
26 // Intersect the parallel and the circle. +
27 // ==> The center point of the solution. +
28 // Create the solution that will be added to already found solutions. +
30 //========================================================================
32 GccAna_Circ2d2TanRad::
33 GccAna_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1 ,
34 const gp_Pnt2d& Point2 ,
35 const Standard_Real Radius ,
36 const Standard_Real Tolerance ):
50 gp_Dir2d dirx(1.0,0.0);
51 Standard_Real Tol = Abs(Tolerance);
53 WellDone = Standard_False;
54 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
55 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
56 GccEnt_BadQualifier::Raise();
60 for ( i = 1 ; i <= 4 ; i++) {
64 Standard_Real deport = 0.;
65 Standard_Integer signe = 0;
66 Standard_Integer nbsol = 0;
67 gp_Circ2d C1 = Qualified1.Qualified();
68 TColgp_Array1OfCirc2d C(1,4);
69 Standard_Real R1 = C1.Radius();
70 Standard_Real distance = (C1.Location()).Distance(Point2);
71 Standard_Real dispc1 = C1.Distance(Point2);
72 gp_Dir2d dir1(Point2.XY()-(C1.Location().XY()));
73 gp_Pnt2d center1(C1.Location());
74 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
76 if ( dispc1-Radius*2.0 > Tol) { WellDone = Standard_True; }
77 else if (Qualified1.IsEnclosed()) {
78 // =================================
79 if ((distance-R1>Tol)||(Radius-R1>Tol)) { WellDone = Standard_True; }
81 if (Abs(distance-R1) < Tol) {
87 C(1) = gp_Circ2d(C1.XAxis(),Abs(Radius-R1));
88 C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
93 else if (Qualified1.IsEnclosing()) {
94 // ==================================
95 if ((Tol<R1-distance)||(Tol<R1-Radius)) { WellDone = Standard_True; }
97 if (Abs(distance-R1) < Tol) {
103 C(1) = gp_Circ2d(C1.XAxis(),Abs(Radius-R1));
104 C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
109 else if (Qualified1.IsOutside()) {
110 // ================================
111 if (Tol < R1-distance) { WellDone = Standard_True; }
112 else if ((Abs(distance-R1) < Tol) || (Abs(dispc1-Radius*2.0) < Tol)) {
118 C(1) = gp_Circ2d(C1.XAxis(),Radius+R1);
119 C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
123 else if (Qualified1.IsUnqualified()) {
124 // ====================================
125 if (Abs(dispc1-Radius*2.0) < Tol) {
126 WellDone = Standard_True;
127 gp_Pnt2d Center(center1.XY()+(distance-Radius)*dir1.XY());
128 cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
129 // ==================================================
130 if (Abs(Center.Distance(center1)-R1) < Tol) {
131 qualifier1(1) = GccEnt_enclosed;
133 else { qualifier1(1) = GccEnt_outside; }
134 qualifier2(1) = GccEnt_noqualifier;
135 pnttg1sol(1) = gp_Pnt2d(Center.XY()-Radius*dir1.XY());
136 pnttg2sol(1) = Point2;
137 WellDone = Standard_True;
140 else if ((Abs(R1-Radius)<Tol) && (Abs(distance-R1)<Tol)){
141 cirsol(1) = gp_Circ2d(C1);
142 // =========================
143 qualifier1(1) = GccEnt_unqualified;
144 qualifier2(1) = GccEnt_noqualifier;
146 pnttg2sol(1) = Point2;
147 WellDone = Standard_True;
149 C(1) = gp_Circ2d(C1.XAxis(),Radius+R1);
150 C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
154 C(1) = gp_Circ2d(C1.XAxis(),Abs(Radius-R1));
155 C(2) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
156 C(3) = gp_Circ2d(C1.XAxis(),Radius+R1);
157 C(4) = gp_Circ2d(gp_Ax2d(Point2,dirx),Radius);
162 for (Standard_Integer j = 1 ; j <= nbsol ; j++) {
163 IntAna2d_AnaIntersection Intp(C(2*j-1),C(2*j));
165 if (!Intp.IsEmpty()) {
166 for (i = 1 ; i <= Intp.NbPoints() ; i++) {
168 gp_Pnt2d Center(Intp.Point(i).Value());
169 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
170 // =======================================================
171 Standard_Real distcc1 = center1.Distance(Center);
172 if (!Qualified1.IsUnqualified()) {
173 qualifier1(NbrSol) = Qualified1.Qualifier();
175 else if (Abs(distcc1+Radius-R1) < Tol) {
176 qualifier1(NbrSol) = GccEnt_enclosed;
178 else if (Abs(distcc1-R1-Radius) < Tol) {
179 qualifier1(NbrSol) = GccEnt_outside;
181 else { qualifier1(NbrSol) = GccEnt_enclosing; }
182 qualifier2(NbrSol) = GccEnt_noqualifier;
183 dir1 = gp_Dir2d(Center.XY()-center1.XY());
185 gp_Dir2d dir2(Center.XY()-Point2.XY());
187 if ((Center.Distance(center1) > C1.Radius()) &&
188 (Radius < Center.Distance(center1)+C1.Radius())) {
189 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1.XY());
191 else if ((Center.Distance(center1) < C1.Radius()) &&
192 (Radius < C1.Radius())) {
193 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dir1.XY());
196 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1.XY());
198 pnttg2sol(NbrSol) = Point2;
201 WellDone = Standard_True;
205 else if (nbsol < 0) {
206 gp_Pnt2d Center(center1.XY()+deport*dir1.XY());
207 cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
208 // ==================================================
209 qualifier1(1) = Qualified1.Qualifier();
210 qualifier2(1) = GccEnt_noqualifier;
211 if (Abs(deport) <= Tol && Abs(Radius-R1) <= Tol) {
215 pnttg1sol(1) = gp_Pnt2d(Center.XY()+signe*Radius*dir1.XY());
217 pnttg2sol(1) = Point2;
218 WellDone = Standard_True;
222 for (i = 1 ; i <= NbrSol ; i++) {
223 par1sol(i)=ElCLib::Parameter(cirsol(i),pnttg1sol(i));
224 if (TheSame1(i) == 0) {
225 pararg1(i)=ElCLib::Parameter(C1,pnttg1sol(i));
227 par2sol(i) = ElCLib::Parameter(cirsol(i),pnttg2sol(i));