Warnings on vc14 were eliminated
[occt.git] / src / GccAna / GccAna_Circ2dTanOnRad_3.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.
7fd59977 14
7fd59977 15
16#include <ElCLib.hxx>
42cf5bc1 17#include <GccAna_Circ2dTanOnRad.hxx>
18#include <GccEnt_BadQualifier.hxx>
19#include <GccEnt_QualifiedCirc.hxx>
20#include <GccEnt_QualifiedLin.hxx>
21#include <gp_Circ2d.hxx>
22#include <gp_Dir2d.hxx>
23#include <gp_Lin2d.hxx>
24#include <gp_Pnt2d.hxx>
7fd59977 25#include <IntAna2d_AnaIntersection.hxx>
26#include <IntAna2d_IntPoint.hxx>
27#include <Standard_NegativeValue.hxx>
28#include <Standard_OutOfRange.hxx>
42cf5bc1 29#include <StdFail_NotDone.hxx>
7fd59977 30#include <TColgp_Array1OfDir2d.hxx>
7fd59977 31
32//=========================================================================
0d969553
Y
33// Circle tangent to a circle Qualified1 (C1). +
34// center on a circle OnCirc. +
35// of radius Radius. +
7fd59977 36// +
0d969553
Y
37// Initialize the table of solutions cirsol and all fields. +
38// Eliminate cases not being the solution. +
39// Create parallel(s) to C1 in the required direction(s). +
40// Intersect parallel(s) with OnCirc and obtain the +
41// center point(s) of found solution(s). +
42// Create solution(s) cirsol. +
7fd59977 43//=========================================================================
7fd59977 44GccAna_Circ2dTanOnRad::
45 GccAna_Circ2dTanOnRad (const GccEnt_QualifiedCirc& Qualified1,
46 const gp_Circ2d& OnCirc ,
47 const Standard_Real Radius ,
48 const Standard_Real Tolerance ):
49 cirsol(1,4) ,
50 qualifier1(1,4) ,
51 TheSame1(1,4) ,
52 pnttg1sol(1,4),
53 pntcen3(1,4) ,
54 par1sol(1,4) ,
55 pararg1(1,4) ,
56 parcen3(1,4)
57{
58
59 TheSame1.Init(0);
60 gp_Dir2d dirx(1.0,0.0);
61 Standard_Real Tol = Abs(Tolerance);
62 Standard_Integer signe[5];
63 signe[0] = 0;
64 signe[1] = 0;
65 signe[2] = 0;
66 signe[3] = 0;
67 signe[4] = 0;
68 Standard_Real disparal[2];
69 Standard_Integer nparal = 0;
70 Standard_Integer sign = 0;
71 WellDone = Standard_False;
72 NbrSol = 0;
73 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
74 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
9775fa61 75 throw GccEnt_BadQualifier();
7fd59977 76 return;
77 }
78 gp_Circ2d C1 = Qualified1.Qualified();
79 TColgp_Array1OfPnt2d Center(1,4);
80 TColgp_Array1OfDir2d dir1on(1,4);
81
9775fa61 82 if (Radius < 0.0) { throw Standard_NegativeValue(); }
7fd59977 83 else {
84 Standard_Real R1 = C1.Radius();
85 Standard_Real R2 = OnCirc.Radius();
86 Standard_Real c1x = C1.Location().X();
87 Standard_Real c1y = C1.Location().Y();
88 gp_Pnt2d center1(c1x,c1y);
89 Standard_Real dist = OnCirc.Location().Distance(center1);
90 Standard_Real onx = OnCirc.Location().X();
91 Standard_Real ony = OnCirc.Location().Y();
92 if (Qualified1.IsEnclosed()) {
93// ============================
94 if ((Radius-R1 > Tol) || (R1-dist-R2-Radius > Tol)) {
95 WellDone=Standard_True;
96 }
97 else {
98 if (Abs(Radius-R1) < Tol) {
99 if (OnCirc.Distance(center1) < Tol) {
100 cirsol(NbrSol) = C1;
101// ==============
102 qualifier1(NbrSol) = Qualified1.Qualifier();
103 NbrSol = 1;
104 TheSame1(NbrSol) = 1;
105 pntcen3(NbrSol) = center1;
106 parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen3(NbrSol));
107 WellDone = Standard_True;
108 }
109 else { WellDone = Standard_False; }
110 }
111 else if (Abs(R1-dist-R2-Radius) <= Tol) {
112 dir1on(1) = gp_Dir2d(c1x-onx,c1y-ony);
113 sign = -1;
114 }
115 else {
116 nparal = 1;
117 disparal[0] = Abs(R1-Radius);
118 }
119 }
120 }
121 else if (Qualified1.IsEnclosing()) {
122// ==================================
123 if ((Tol<R1-Radius)||(Tol<R1+dist-R2-Radius)||(Radius-R1-dist-R2>Tol)) {
124 WellDone = Standard_True;
125 }
126 else {
127 if (Abs(Radius-R1) < Tol) {
128 if (OnCirc.Distance(center1) < Tol) {
129 cirsol(NbrSol) = C1;
130// ==============
131 qualifier1(NbrSol) = Qualified1.Qualifier();
132 NbrSol = 1;
133 TheSame1(NbrSol) = 1;
134 pntcen3(NbrSol) = center1;
135 parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen3(NbrSol));
136 WellDone = Standard_True;
137 }
138 else { WellDone = Standard_True; }
139 }
140 else if ((Abs(R1+dist-R2-Radius)<Tol)||(Abs(Radius-R1-dist-R2)<Tol)) {
141 dir1on(1) = gp_Dir2d(c1x-onx,c1y-ony);
142 if (Abs(R1+dist-R2-Radius) < Tol) { sign = 1; }
143 else { sign = -1; }
144 }
145 else {
146 nparal = 1;
147 disparal[0] = Abs(R1-Radius);
148 }
149 }
150 }
151 else if (Qualified1.IsOutside()) {
152// ================================
153 if ((dist-R2-R1-Radius>Tol)||(Radius-dist-R2+R1>Tol)) {
154 WellDone=Standard_True;
155 }
156 else {
157 dir1on(1) = gp_Dir2d(c1x-onx,c1y-ony);
158 if (Abs(R1-dist-R2+Radius) < Tol) {
159 sign = -1;
160 }
161 else if (Abs(dist-R1-R2-Radius) < Tol) { sign = 1; }
162 else {
163 nparal = 1;
164 disparal[0] = Abs(R1+Radius);
165 }
166 }
167 }
168 else {
169 if ((dist-R2-R1-Radius>Tol)||(Radius-dist-R1-R2>Tol)) {
170 WellDone=Standard_True;
171 }
172 else if ((R1-dist-R2>Tol)&&(Tol<R1-R2-dist-Radius)) {
173 WellDone = Standard_True;
174 }
175 else {
176 dir1on(1) = gp_Dir2d(c1x-onx,c1y-ony);
177 if (Abs(dist-R1-R2-Radius) < Tol) {
178 sign = 1;
179 }
180 else if (dist+R1+R2-Radius < 0.0) { sign = -1; }
181 else if ((R1-dist+R2>0.0) && (R1-R2-dist-Radius>0.0)) { sign = -1; }
182 else {
183 nparal = 2;
184 disparal[0] = Abs(R1+Radius);
185 disparal[1] = Abs(R1-Radius);
186 }
187 }
188 }
189 for (Standard_Integer jj = 0 ; jj < nparal ; jj++) {
190 IntAna2d_AnaIntersection Intp(OnCirc,
191 gp_Circ2d(gp_Ax2d(center1,dirx),disparal[jj]));
192 if (Intp.IsDone()) {
193 if (!Intp.IsEmpty()) {
194 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
195 NbrSol++;
196 Center(NbrSol) = gp_Pnt2d(Intp.Point(i).Value());
197 cirsol(NbrSol)=gp_Circ2d(gp_Ax2d(Center(NbrSol),dirx),Radius);
198// =============================================================
199 Standard_Real distcc1 = Center(NbrSol).Distance(center1);
200 if (!Qualified1.IsUnqualified()) {
201 qualifier1(NbrSol) = Qualified1.Qualifier();
202 }
203 else if (Abs(distcc1+Radius-R1) < Tol) {
204 qualifier1(NbrSol) = GccEnt_enclosed;
205 }
206 else if (Abs(distcc1-R1-Radius) < Tol) {
207 qualifier1(NbrSol) = GccEnt_outside;
208 }
209 else { qualifier1(NbrSol) = GccEnt_enclosing; }
210 dir1on(NbrSol) = gp_Dir2d(c1x-Center(NbrSol).X(),
211 c1y-Center(NbrSol).Y());
212 if ((R1>Radius) && (Center(NbrSol).Distance (center1)<=R1)){
213 signe[NbrSol-1] = -1;
214 }
215 else {
216 signe[NbrSol-1] = 1;
217 }
218 }
219 }
220 WellDone = Standard_True;
221 }
222 }
223 if (sign != 0) {
224 Center(1) = gp_Pnt2d(OnCirc.Location().XY()+sign*R2*dir1on(1).XY());
225 cirsol(1) = gp_Circ2d(gp_Ax2d(Center(1),dirx),Radius);
226// =====================================================
227 Standard_Real distcc1 = Center(1).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 NbrSol = 1;
239 signe[NbrSol-1] = 1;
240 WellDone = Standard_True;
241 }
242 Standard_Integer ii = 0;
243 while (signe[ii] != 0) {
244 pnttg1sol(ii+1) = gp_Pnt2d(Center(ii+1).XY()+
245 signe[ii]*Radius*dir1on(ii+1).XY());
246 pntcen3(ii+1) = cirsol(ii+1).Location();
247 pararg1(ii+1)=ElCLib::Parameter(C1,pnttg1sol(ii+1));
248 par1sol(ii+1)=ElCLib::Parameter(cirsol(ii+1),pnttg1sol(ii+1));
249 parcen3(ii+1)=ElCLib::Parameter(OnCirc,pntcen3(ii+1));
250 ii++;
251 }
252 }
253 }