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.
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>
25 #include <IntAna2d_AnaIntersection.hxx>
26 #include <IntAna2d_IntPoint.hxx>
27 #include <Standard_NegativeValue.hxx>
28 #include <Standard_OutOfRange.hxx>
29 #include <StdFail_NotDone.hxx>
31 //=========================================================================
32 // Circle tangent to straight line Qualified1 (L1). +
33 // center on circle OnCirc. +
34 // with radius Radius. +
36 // Initialize table of solutions cirsol and all fields. +
37 // Eliminate cases not being the solution. +
38 // Create parallel line(s) to L1 in the required direction(s). +
39 // Intersect parallel line(s) with OnCirc and obtain +
40 // center points of found solutions. +
41 // Create solutions cirsol. +
42 //=========================================================================
43 GccAna_Circ2dTanOnRad::
44 GccAna_Circ2dTanOnRad (const GccEnt_QualifiedLin& Qualified1,
45 const gp_Circ2d& OnCirc ,
46 const Standard_Real Radius ,
47 const Standard_Real Tolerance ):
49 //=========================================================================
50 // Initialization of fields. +
51 //=========================================================================
64 gp_Dir2d dirx(1.0,0.0);
65 Standard_Real Tol = Abs(Tolerance);
66 WellDone = Standard_False;
68 if (!(Qualified1.IsEnclosed() ||
69 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
70 throw GccEnt_BadQualifier();
74 //=========================================================================
75 // Initialisation of various variables. +
76 //=========================================================================
78 Standard_Integer nbsol = 0;
79 Standard_Integer sign = 0;
80 gp_Lin2d L1 = Qualified1.Qualified();
81 gp_Pnt2d origin1(L1.Location());
82 gp_Dir2d dir1(L1.Direction());
83 gp_Dir2d normL1(-dir1.Y(),dir1.X());
84 Standard_Real dist1 = L1.Distance(OnCirc.Location())-OnCirc.Radius();
85 Standard_Real dist2 = L1.Distance(OnCirc.Location())+OnCirc.Radius();
87 //=========================================================================
89 //=========================================================================
91 if (Radius < 0.0) { throw Standard_NegativeValue(); }
93 L1 = Qualified1.Qualified();
94 if ((dist1-Radius>Tol) || (Tol<Radius-dist2)) { WellDone=Standard_True; }
99 if (dist1-Radius > 0.0) { dist1 = Radius; }
100 else if (dist2-Radius < 0.0) { dist2 = Radius; }
102 if (Qualified1.IsEnclosed()) {
103 // ============================
107 else if (Qualified1.IsOutside()) {
108 // ================================
117 for (Standard_Integer j = 1 ; j <= nbsol ;j++) {
119 gp_Lin2d L(gp_Pnt2d(origin1.X()-sign*Radius*dir1.Y(),
120 origin1.Y()+sign*Radius*dir1.X()),dir1);
121 IntAna2d_AnaIntersection Intp(L,OnCirc);
123 if (!Intp.IsEmpty()) {
124 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
126 gp_Pnt2d Center(Intp.Point(i).Value());
127 gp_Ax2d axe(Center,dirx);
128 cirsol(NbrSol) = gp_Circ2d(axe,Radius);
129 // ======================================
130 gp_Dir2d dc1(origin1.XY()-Center.XY());
131 sign = (Standard_Integer) dc1.Dot(normL1);
132 if (!Qualified1.IsUnqualified()) {
133 qualifier1(NbrSol) = Qualified1.Qualifier();
135 else if (dc1.Dot(normL1) > 0.0) {
136 qualifier1(NbrSol) = GccEnt_outside;
138 else { qualifier1(NbrSol) = GccEnt_enclosed; }
139 pntcen3(NbrSol) = cirsol(NbrSol).Location();
140 pnttg1sol(NbrSol) = gp_Pnt2d(pntcen3(NbrSol).XY()+
141 gp_XY(sign*Radius*dir1.Y(),
142 -sign*Radius*dir1.X()));
143 pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
144 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
146 parcen3(NbrSol)=ElCLib::Parameter(OnCirc,pntcen3(NbrSol));
149 WellDone = Standard_True;