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