0024510: Remove unused local variables
[occt.git] / src / GccAna / GccAna_Circ2dTanOnRad.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
973c2be1 6// This library is free software; you can redistribute it and / or modify it
7// under the terms of the GNU Lesser General Public version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15// PRO12736 : bug quand OnLine // Ox, JCT 20/03/98
16
17//========================================================================
0d969553
Y
18// circular tangent to element of type : - Circle. +
19// - Line. +
7fd59977 20// - Point. +
0d969553
Y
21// center on second element of type : - Circle. +
22// - Line. +
23// of given radius : Radius. +
7fd59977 24//========================================================================
25
26#include <GccAna_Circ2dTanOnRad.ixx>
27
28#include <ElCLib.hxx>
29#include <math_DirectPolynomialRoots.hxx>
30#include <TColStd_Array1OfReal.hxx>
31#include <Standard_NegativeValue.hxx>
32#include <gp_Dir2d.hxx>
33#include <Standard_OutOfRange.hxx>
34#include <StdFail_NotDone.hxx>
35#include <GccEnt_BadQualifier.hxx>
36
37typedef math_DirectPolynomialRoots Roots;
38
39//=========================================================================
0d969553
Y
40// Circle tangent : to circle Qualified1 (C1). +
41// center : on straight line OnLine. +
42// of radius : Radius. +
7fd59977 43// +
0d969553
Y
44// Initialise the table of solutions cirsol and all fields. +
45// Eliminate depending on the qualifier the cases not being solutions. +
46// Solve the equation of the second degree indicating that the found center +
47// point (xc,yc) is at a distance Radius from circle C1 and +
48// on straight line OnLine. +
49// The solutions aret represented by circles : +
50// - with center Pntcen(xc,yc) +
51// - with radius Radius. +
7fd59977 52//=========================================================================
53
54GccAna_Circ2dTanOnRad::
55 GccAna_Circ2dTanOnRad (const GccEnt_QualifiedCirc& Qualified1,
56 const gp_Lin2d& OnLine ,
57 const Standard_Real Radius ,
58 const Standard_Real Tolerance ) :
59 cirsol(1,4) ,
60 qualifier1(1,4) ,
61 TheSame1(1,4) ,
62 pnttg1sol(1,4) ,
63 pntcen3(1,4) ,
64 par1sol(1,4) ,
65 pararg1(1,4) ,
66 parcen3(1,4)
67{
68
69 TheSame1.Init(0);
70 gp_Dir2d dirx(1.0,0.0);
71 Standard_Real Tol = Abs(Tolerance);
72 WellDone = Standard_False;
73 NbrSol = 0;
74 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
75 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
76 GccEnt_BadQualifier::Raise();
77 return;
78 }
79 TColStd_Array1OfReal Coef(1,2);
80 gp_Circ2d C1 = Qualified1.Qualified();
81
82 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
83 else {
84 Standard_Integer nbsol = 0;
85 Standard_Integer signe = 0;
86 gp_Pnt2d Center;
87 Standard_Real xc;
88 Standard_Real yc;
89 Standard_Real R1 = C1.Radius();
90 Standard_Real dist = OnLine.Distance(C1.Location());
91 Standard_Real xdir = (OnLine.Direction()).X();
92 Standard_Real ydir = (OnLine.Direction()).Y();
93 Standard_Real lxloc = (OnLine.Location()).X();
94 Standard_Real lyloc = (OnLine.Location()).Y();
95 gp_Pnt2d center1(C1.Location());
96 Standard_Real x1 = center1.X();
97 Standard_Real y1 = center1.Y();
7fd59977 98 if (Qualified1.IsEnclosed()) {
99// ============================
100 if (Tol < Radius-R1+dist) { WellDone = Standard_True; }
101 else {
102 if (Abs(Radius-R1+dist) < Tol) {
103 WellDone = Standard_True;
104 NbrSol = 1;
105 if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) {
106 Center = gp_Pnt2d(x1-ydir*dist,y1+xdir*dist);
107 }
108 else { Center = gp_Pnt2d(x1+ydir*dist,y1-xdir*dist); }
109 signe = 1;
110 }
111 else {
112 Coef(1) = (R1-Radius)*(R1-Radius);
113 nbsol = 1;
114 }
115 }
116 }
117 else if (Qualified1.IsEnclosing()) {
118// ==================================
119 if (R1+dist-Radius > Tol) { WellDone = Standard_True; }
120 else {
121 if (R1+dist-Radius > 0.0) {
122 WellDone = Standard_True;
123 NbrSol = 1;
124 if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) {
125 Center = gp_Pnt2d(x1-ydir*dist,y1+xdir*dist);
126 }
127 else { Center = gp_Pnt2d(x1+ydir*dist,y1-xdir*dist); }
128 signe = -1;
129 }
130 else {
131 Coef(1) = (Radius-R1)*(Radius-R1);
132 nbsol = 1;
133 }
134 }
135 }
136 else {
137// ====
138 if (dist-R1-Radius > Tol) { WellDone = Standard_False; }
139 else {
140 if (Abs(dist-R1-Radius) < Tol) {
141 WellDone = Standard_True;
142 NbrSol = 1;
143 if (-ydir*(x1-lxloc)+xdir*(y1-lyloc)<0.0) {
144 Center = gp_Pnt2d(x1-ydir*dist,y1+xdir*dist);
145 }
146 else { Center = gp_Pnt2d(x1+ydir*dist,y1-xdir*dist); }
147 signe = -1;
148 }
149 else {
150 if (Qualified1.IsOutside()) {
151// ===========================
152 Coef(1) = (Radius+R1)*(Radius+R1);
153 nbsol = 1;
154 }
155 else {
156// ====
157 Coef(1) = (Radius-R1)*(Radius-R1);
158 Coef(2) = (Radius+R1)*(Radius+R1);
159 nbsol = 2;
160 }
161 }
162 }
163 }
164 if (signe != 0) {
165 cirsol(1) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
166// ==================================================
167 Standard_Real distcc1 = Center.Distance(center1);
168 if (!Qualified1.IsUnqualified()) {
169 qualifier1(1) = Qualified1.Qualifier();
170 }
171 else if (Abs(distcc1+Radius-R1) < Tol) {
172 qualifier1(1) = GccEnt_enclosed;
173 }
174 else if (Abs(distcc1-R1-Radius) < Tol) {
175 qualifier1(1) = GccEnt_outside;
176 }
177 else { qualifier1(1) = GccEnt_enclosing; }
178 if (Abs(Radius-R1) <= Tol) { TheSame1(1) = 1; }
179 else {
180 gp_Dir2d dir1cen(Center.X()-x1,Center.Y()-y1);
181 pnttg1sol(1) = gp_Pnt2d(Center.XY()+signe*Radius*dir1cen.XY());
182 par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
183 pararg1(1)=ElCLib::Parameter(C1,pnttg1sol(1));
184 }
185 pntcen3(1) = cirsol(NbrSol).Location();
186 parcen3(1)=ElCLib::Parameter(OnLine,pntcen3(1));
187 }
188 else if (nbsol > 0) {
189 for (Standard_Integer j = 1 ; j <= nbsol ; j++) {
190 Standard_Real A,B,C;
191 OnLine.Coefficients(A,B,C);
192 Standard_Real D = A;
193 Standard_Real x0,y0;
194 if ( Abs(D) <= Tol ) {
195 A = B;
196 B = D;
7fd59977 197 x0 = y1;
198 y0 = x1;
199 }
200 else{
201 x0 = x1;
202 y0 = y1;
203 }
204 Roots Sol((B*B+A*A)/(A*A),
205 2.0*(B*C/(A*A)+(B/A)*x0-y0),
206 x0*x0+y0*y0+C*C/(A*A)-Coef(j)+2.0*C*x0/A);
207 if (Sol.IsDone()) {
208 for (Standard_Integer i = 1 ; i <= Sol.NbSolutions() ; i++) {
209
210 if ( Abs(D) > Tol ) {
211 yc = Sol.Value(i);
212 xc = -(B/A)*yc-C/A;
213 }
214 else {
215 xc = Sol.Value(i);
216 yc = -(B/A)*xc-C/A;
217 }
218 Center = gp_Pnt2d(xc,yc);
219 if (OnLine.Distance(Center)>Tol)
220 continue;
221 NbrSol++;
222 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
223// =======================================================
224 Standard_Real distcc1 = Center.Distance(center1);
225 if (!Qualified1.IsUnqualified()) {
226 qualifier1(NbrSol) = Qualified1.Qualifier();
227 }
228 else if (Abs(distcc1+Radius-R1) < Tol) {
229 qualifier1(NbrSol) = GccEnt_enclosed;
230 }
231 else if (Abs(distcc1-R1-Radius) < Tol) {
232 qualifier1(NbrSol) = GccEnt_outside;
233 }
234 else { qualifier1(NbrSol) = GccEnt_enclosing; }
235 gp_Dir2d dir1cen(Center.X()-x1,Center.Y()-y1);
236 if ((Radius > R1) || (Center.Distance(center1) > R1)) {
237 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dir1cen.XY());
238 }
239 else {
240 pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()-Radius*dir1cen.XY());
241 }
242 pntcen3(NbrSol) = cirsol(NbrSol).Location();
243 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
244 pnttg1sol(NbrSol));
245 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
246 parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen3(NbrSol));
247 }
248 WellDone = Standard_True;
249 }
250 }
251 }
252 }
253 }
254
255Standard_Boolean GccAna_Circ2dTanOnRad::
256 IsDone () const { return WellDone; }
257
258Standard_Integer GccAna_Circ2dTanOnRad::
259 NbSolutions () const { return NbrSol; }
260
261gp_Circ2d GccAna_Circ2dTanOnRad::ThisSolution (const Standard_Integer Index) const
262{
263 if (Index > NbrSol || Index <= 0) {
264 Standard_OutOfRange::Raise();
265 }
266 return cirsol(Index);
267}
268
269void GccAna_Circ2dTanOnRad::
270 WhichQualifier(const Standard_Integer Index ,
271 GccEnt_Position& Qualif1 ) const
272{
273 if (!WellDone) { StdFail_NotDone::Raise(); }
274 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
275 else {
276 Qualif1 = qualifier1(Index);
277 }
278}
279
280void GccAna_Circ2dTanOnRad::
281 Tangency1 (const Standard_Integer Index,
282 Standard_Real& ParSol,
283 Standard_Real& ParArg,
284 gp_Pnt2d& PntSol) const{
285 if (!WellDone) {
286 StdFail_NotDone::Raise();
287 }
288 else if (Index <= 0 ||Index > NbrSol) {
289 Standard_OutOfRange::Raise();
290 }
291 else {
292 ParSol = par1sol(Index);
293 ParArg = pararg1(Index);
294 PntSol = gp_Pnt2d(pnttg1sol(Index));
295 }
296 }
297
298
299void GccAna_Circ2dTanOnRad::
300 CenterOn3 (const Standard_Integer Index,
301 Standard_Real& ParArg,
302 gp_Pnt2d& PntSol) const{
303 if (!WellDone) {
304 StdFail_NotDone::Raise();
305 }
306 else if (Index <= 0 ||Index > NbrSol) {
307 Standard_OutOfRange::Raise();
308 }
309 else {
310 ParArg = parcen3(Index);
311 PntSol = pnttg1sol(Index);
312 }
313 }
314
315Standard_Boolean GccAna_Circ2dTanOnRad::IsTheSame1 (const Standard_Integer Index) const
316{
317 if (!WellDone)
318 StdFail_NotDone::Raise();
319
320 if (Index <= 0 ||Index > NbrSol)
321 Standard_OutOfRange::Raise();
322
323 if (TheSame1(Index) == 0)
324 return Standard_False;
325
326 return Standard_True;
327}