1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 //================================================================================
16 // Creation of a circle tangent to an element and having center in a point +
17 //================================================================================
20 #include <GccAna_Circ2dTanCen.hxx>
21 #include <GccEnt_BadQualifier.hxx>
22 #include <GccEnt_QualifiedCirc.hxx>
24 #include <gp_Circ2d.hxx>
25 #include <gp_Dir2d.hxx>
26 #include <gp_Lin2d.hxx>
27 #include <gp_Pnt2d.hxx>
28 #include <Standard_NegativeValue.hxx>
29 #include <Standard_OutOfRange.hxx>
30 #include <StdFail_NotDone.hxx>
32 //========================================================================
33 // Creation of a circle tangent to a circle with center in a point. +
34 // - Calculate the distance between the center of the circle and the point of +
36 // - Check that this distance is compatible with the qualifier of the circle. +
37 // Si yes, the radius of the solution will be : +
38 // C1.Radius()-dist if the qualifier is Enclosed. +
39 // C1.Radius()+dist if the qualifier is Enclosing. +
40 // dist-C1.Radius() if the qualifier is Outside. +
41 // a mix of these values if the qualifier is Unqualified. +
42 //========================================================================
44 GccAna_Circ2dTanCen (const GccEnt_QualifiedCirc& Qualified1,
45 const gp_Pnt2d& Pcenter ,
46 const Standard_Real Tolerance ):
48 //========================================================================
49 // Initialization of fields. +
50 //========================================================================
61 Standard_Real Radius = 0.0;
62 WellDone = Standard_False;
63 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
64 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
65 throw GccEnt_BadQualifier();
68 gp_Dir2d dirx(1.0,0.0);
69 Standard_Real Tol = Abs(Tolerance);
70 gp_Circ2d C1 = Qualified1.Qualified();
71 Standard_Real R1 = C1.Radius();
72 gp_Pnt2d center1(C1.Location());
74 Standard_Integer signe = 0;
75 Standard_Integer signe1 = 0;
77 if (!Qualified1.IsUnqualified()) {
78 dist = Pcenter.Distance(center1);
79 if (Qualified1.IsEnclosed()) {
80 // ============================
82 Radius = Abs(R1-dist);
85 else { WellDone = Standard_True; }
87 else if (Qualified1.IsEnclosing()) {
88 // =================================
92 else if (Qualified1.IsOutside()) {
93 // ===============================
94 if (dist < R1-Tol) { WellDone = Standard_True; }
96 Radius = Abs(R1-dist);
102 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),Radius);
103 // ========================================================
104 qualifier1(NbrSol) = Qualified1.Qualifier();
105 if (dist <= gp::Resolution()) { TheSame1(NbrSol) = 1; }
107 TheSame1(NbrSol) = 0;
108 gp_Dir2d d(Pcenter.X()-center1.X(),Pcenter.Y()-center1.Y());
109 pnttg1sol(NbrSol) = gp_Pnt2d(Pcenter.XY()+signe*Radius*d.XY());
110 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
111 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
113 WellDone = Standard_True;
118 dist = Pcenter.Distance(center1);
119 if (dist >= gp::Resolution()) {
121 for (Standard_Integer i = 1; i <= 2 ; i++) {
129 Radius = Abs(R1+signe*dist);
131 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),Radius);
132 // ========================================================
133 Standard_Real distcc1 = Pcenter.Distance(center1);
134 if (!Qualified1.IsUnqualified()) {
135 qualifier1(NbrSol) = Qualified1.Qualifier();
137 else if (Abs(distcc1+Radius-R1) < Tol) {
138 qualifier1(NbrSol) = GccEnt_enclosed;
140 else if (Abs(distcc1-R1-Radius) < Tol) {
141 qualifier1(NbrSol) = GccEnt_outside;
143 else { qualifier1(NbrSol) = GccEnt_enclosing; }
144 TheSame1(NbrSol) = 0;
145 WellDone = Standard_True;
146 gp_Dir2d d(Pcenter.X()-center1.X(),Pcenter.Y()-center1.Y());
147 pnttg1sol(NbrSol) = gp_Pnt2d(Pcenter.XY()+signe1*Radius*d.XY());
148 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),pnttg1sol(NbrSol));
149 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
154 cirsol(NbrSol) = gp_Circ2d(C1);
155 // ==============================
156 qualifier1(1) = Qualified1.Qualifier();
157 TheSame1(NbrSol) = 1;
158 WellDone = Standard_True;
163 //=========================================================================
164 // Circle tangent to line Linetan and center in a point Pcenter. +
165 // Calculate the distance from the point to the line ==> Radius. +
166 // Create the circle with center Pcenter of radius Radius. +
167 //=========================================================================
169 GccAna_Circ2dTanCen::
170 GccAna_Circ2dTanCen (const gp_Lin2d& Linetan ,
171 const gp_Pnt2d& Pcenter ):
173 //=========================================================================
174 // Initialisation of fields. +
175 //=========================================================================
185 gp_Dir2d dirx(1.0,0.0);
186 Standard_Real rayon = Linetan.Distance(Pcenter);
187 cirsol(1) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),rayon);
188 // ==================================================
189 qualifier1(1) = GccEnt_noqualifier;
191 Standard_Real xloc = Linetan.Location().X();
192 Standard_Real yloc = Linetan.Location().Y();
193 Standard_Real xdir = Linetan.Direction().X();
194 Standard_Real ydir = Linetan.Direction().Y();
196 if (gp_Dir2d(xloc-Pcenter.X(),yloc-Pcenter.Y())
197 .Dot(gp_Dir2d(-ydir,xdir)) > 0.0) {
198 pnttg1sol(1) = gp_Pnt2d(Pcenter.XY()+rayon*gp_XY(-ydir,xdir));
199 par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
200 pararg1(1)=ElCLib::Parameter(Linetan,pnttg1sol(1));
203 pnttg1sol(1) = gp_Pnt2d(Pcenter.XY()+rayon*gp_XY(ydir,-xdir));
204 par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
205 pararg1(1)=ElCLib::Parameter(Linetan,pnttg1sol(1));
208 WellDone = Standard_True;
211 //=========================================================================
212 // Circle tangent to point Point1 and centered in a point Pcenter. +
213 // Calculate the distance from Pcenter to Point1 ==> Radius. +
214 // Create the circle with center Pcenter of radius Radius. +
215 //=========================================================================
217 GccAna_Circ2dTanCen::
218 GccAna_Circ2dTanCen (const gp_Pnt2d& Point1 ,
219 const gp_Pnt2d& Pcenter ):
221 //=========================================================================
222 // Initialisation of fields. +
223 //=========================================================================
233 gp_Dir2d dirx(1.0,0.0);
234 Standard_Real rayon = Point1.Distance(Pcenter);
235 cirsol(1) = gp_Circ2d(gp_Ax2d(Pcenter,dirx),rayon);
236 // =================================================
237 qualifier1(1) = GccEnt_noqualifier;
239 pnttg1sol(1) = Point1;
240 par1sol(1)=ElCLib::Parameter(cirsol(1),pnttg1sol(1));
243 WellDone = Standard_True;
246 //=========================================================================
248 Standard_Boolean GccAna_Circ2dTanCen::
249 IsDone () const { return WellDone; }
251 Standard_Integer GccAna_Circ2dTanCen::
252 NbSolutions () const { return NbrSol; }
254 gp_Circ2d GccAna_Circ2dTanCen::
255 ThisSolution (const Standard_Integer Index) const
257 if (Index > NbrSol || Index <= 0) { throw Standard_OutOfRange(); }
258 return cirsol(Index);
261 void GccAna_Circ2dTanCen::
262 WhichQualifier(const Standard_Integer Index ,
263 GccEnt_Position& Qualif1 ) const
265 if (!WellDone) { throw StdFail_NotDone(); }
266 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
268 Qualif1 = qualifier1(Index);
272 void GccAna_Circ2dTanCen::
273 Tangency1 (const Standard_Integer Index,
274 Standard_Real& ParSol,
275 Standard_Real& ParArg,
276 gp_Pnt2d& PntSol) const{
277 if (!WellDone) { throw StdFail_NotDone(); }
278 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
280 if (TheSame1(Index) == 0) {
281 PntSol = gp_Pnt2d(pnttg1sol(Index));
282 ParSol = par1sol(Index);
283 ParArg = pararg1(Index);
285 else { throw StdFail_NotDone(); }
289 Standard_Boolean GccAna_Circ2dTanCen::
290 IsTheSame1 (const Standard_Integer Index) const
293 throw StdFail_NotDone();
294 if (Index <= 0 ||Index > NbrSol)
295 throw Standard_OutOfRange();
297 if (TheSame1(Index) == 0)
298 return Standard_False;
300 return Standard_True;