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