1 // File GccAna_Lin2dTanPer.cxx, REG 08/07/91
3 //=========================================================================
4 // CREATION of a STRAIGHT LINE TANGENT to a CIRCLE or PASSING by a POINT +
5 // and ORTHOGONAL to a STRAIGHT LINE. +
6 //=========================================================================
8 #include <GccAna_Lin2dTanPer.ixx>
11 #include <StdFail_NotDone.hxx>
13 #include <gp_Dir2d.hxx>
14 #include <gp_Vec2d.hxx>
15 #include <gp_Circ2d.hxx>
16 #include <Standard_OutOfRange.hxx>
17 #include <GccEnt_BadQualifier.hxx>
18 #include <IntAna2d_AnaIntersection.hxx>
19 #include <IntAna2d_IntPoint.hxx>
21 //=========================================================================
22 // Straight line passing by point : ThePoint and +
23 // orthogonal to straight line : TheLin. +
24 // Create the straight line of origin : ThePoint +
25 // and direction : TheLin.Direction() turned by 90 +
26 //=========================================================================
29 GccAna_Lin2dTanPer (const gp_Pnt2d& ThePnt ,
30 const gp_Lin2d& TheLin ):
41 linsol(1) = gp_Lin2d(ThePnt,gp_Dir2d(-(TheLin.Direction().Y()),
42 // ===============================================================
43 TheLin.Direction().X()));
44 // ========================
45 pnttg1sol(1) = ThePnt;
46 IntAna2d_AnaIntersection Intp(linsol(1),TheLin);
48 if (!Intp.IsEmpty()) {
49 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
50 pntint2sol(1) = Intp.Point(i).Value();
54 par1sol(1) = ElCLib::Parameter(linsol(1),pnttg1sol(1));
55 par2sol(1) = ElCLib::Parameter(linsol(1),pntint2sol(1));
57 pararg2(1) = ElCLib::Parameter(TheLin,pntint2sol(1));
59 WellDone = Standard_True;
62 //=========================================================================
63 // Straight line passing by point : ThePnt +
64 // and orthogonal to circle : TheCircle. +
65 // Create the straight line of origin : ThePoint +
66 // and direction : (TheCircle.Location(),ThePnt). +
67 //=========================================================================
70 GccAna_Lin2dTanPer (const gp_Pnt2d& ThePnt ,
71 const gp_Circ2d& TheCircle ):
82 linsol(1) = gp_Lin2d(ThePnt,
83 // ============================
84 gp_Dir2d(TheCircle.Location().XY()-ThePnt.XY()));
85 // ================================================
86 pnttg1sol(1) = ThePnt;
87 IntAna2d_AnaIntersection Intp(linsol(1),TheCircle);
89 if (!Intp.IsEmpty()) {
90 Standard_Real maxdist = RealLast();
91 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
92 if (Intp.Point(i).Value().Distance(ThePnt) < maxdist) {
93 pntint2sol(1) = Intp.Point(i).Value();
98 par1sol(1) = ElCLib::Parameter(linsol(1),pnttg1sol(1));
99 par2sol(1) = ElCLib::Parameter(linsol(1),pntint2sol(1));
101 pararg2(1) = ElCLib::Parameter(TheCircle,pntint2sol(1));
103 WellDone = Standard_True;
106 //=========================================================================
107 // Straight line tangent to circle : Qualified1 (C1) +
108 // and orthogonal to straight line : TheLin. +
109 // Create straight line of origin : P1 (on C1) +
110 // and direction : TheLin.Direction() turned by 90` +
111 //=========================================================================
114 GccAna_Lin2dTanPer (const GccEnt_QualifiedCirc& Qualified1,
115 const gp_Lin2d& TheLin ):
126 WellDone = Standard_False;
127 Standard_Integer nbsol = 0;
128 Standard_Integer signe = 0;
130 gp_Circ2d C1 = Qualified1.Qualified();
132 if (Qualified1.IsEnclosed()) {
133 // ============================
134 GccEnt_BadQualifier::Raise();
136 else if (Qualified1.IsEnclosing()) {
137 // ==================================
141 else if (Qualified1.IsOutside()) {
142 // ================================
150 gp_XY xy(C1.Radius()*TheLin.Direction().XY());
151 for (Standard_Integer j = 1 ; j <= nbsol ; j++) {
154 linsol(NbrSol)=gp_Lin2d(gp_Pnt2d((C1.Location().XY()).Added(signe*xy)),
155 // =======================================================================
156 gp_Dir2d(-TheLin.Direction().Y(),
157 // =================================
158 TheLin.Direction().X()));
159 // ========================
160 pnttg1sol(NbrSol) = gp_Pnt2d((C1.Location().XY()).Added(signe*xy));
161 IntAna2d_AnaIntersection Intp(linsol(NbrSol),TheLin);
163 if (!Intp.IsEmpty()) {
164 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
165 pntint2sol(NbrSol) = Intp.Point(i).Value();
169 par1sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pnttg1sol(NbrSol));
170 par2sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pntint2sol(NbrSol));
171 pararg1(NbrSol) = ElCLib::Parameter(C1,pnttg1sol(NbrSol));
172 pararg2(NbrSol) = ElCLib::Parameter(TheLin,pntint2sol(NbrSol));
173 WellDone = Standard_True;
177 //=========================================================================
178 // Straight line tangent to circle : Qualified1 (C1) +
179 // and orthogonal to circle : TheCircle. +
180 // Create straight line of origin : P1 (on C1) +
181 // and direction : TheLin.Direction() turned by 90` +
182 //=========================================================================
185 GccAna_Lin2dTanPer (const GccEnt_QualifiedCirc& Qualified1,
186 const gp_Circ2d& TheCircle ):
197 WellDone = Standard_False;
199 Standard_Integer nbsol = 0;
200 Standard_Integer signe = 0;
201 gp_Circ2d C1 = Qualified1.Qualified();
203 if (Qualified1.IsEnclosed()) {
204 // ============================
205 GccEnt_BadQualifier::Raise();
207 else if (Qualified1.IsEnclosing()) {
208 // ==================================
211 qualifier1(1) = GccEnt_enclosing;
213 else if (Qualified1.IsOutside()) {
214 // ================================
217 qualifier1(1) = GccEnt_outside;
219 else if (Qualified1.IsUnqualified()) {
220 // ====================================
223 qualifier1(1) = GccEnt_enclosing;
224 qualifier1(2) = GccEnt_outside;
226 for (Standard_Integer j = 1 ; j <= 2 ; j++) {
229 gp_Dir2d D1(TheCircle.Location().XY()-C1.Location().XY());
230 linsol(NbrSol) = gp_Lin2d(gp_Pnt2d((C1.Location().XY())+
231 // ===================================================
232 signe*(D1.XY()*C1.Radius())),gp_Dir2d(-D1.Y(),D1.X()));
233 // ======================================================
234 pnttg1sol(NbrSol) = gp_Pnt2d((C1.Location().XY())+
235 signe*(D1.XY()*C1.Radius()));
236 IntAna2d_AnaIntersection Intp(linsol(NbrSol),TheCircle);
238 if (!Intp.IsEmpty()) {
239 Standard_Real maxdist = RealLast();
240 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
241 if (Intp.Point(i).Value().Distance(pnttg1sol(NbrSol)) < maxdist) {
242 pntint2sol(NbrSol) = Intp.Point(i).Value();
247 par1sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pnttg1sol(NbrSol));
248 par2sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pntint2sol(NbrSol));
249 pararg1(NbrSol) = ElCLib::Parameter(C1,pnttg1sol(NbrSol));
250 pararg2(NbrSol) = ElCLib::Parameter(TheCircle,pntint2sol(NbrSol));
251 WellDone = Standard_True;
255 Standard_Boolean GccAna_Lin2dTanPer::
256 IsDone () const { return WellDone; }
258 Standard_Integer GccAna_Lin2dTanPer::
261 if (!WellDone) { StdFail_NotDone::Raise(); }
265 gp_Lin2d GccAna_Lin2dTanPer::
266 ThisSolution (const Standard_Integer Index) const
268 if (!WellDone) { StdFail_NotDone::Raise(); }
269 if (Index <= 0 || Index > NbrSol) { Standard_RangeError::Raise(); }
270 return linsol(Index);
273 void GccAna_Lin2dTanPer::
274 WhichQualifier(const Standard_Integer Index ,
275 GccEnt_Position& Qualif1 ) const
277 if (!WellDone) { StdFail_NotDone::Raise(); }
278 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
280 Qualif1 = qualifier1(Index);
284 void GccAna_Lin2dTanPer::
285 Tangency1 (const Standard_Integer Index,
286 Standard_Real& ParSol,
287 Standard_Real& ParArg,
288 gp_Pnt2d& Pnt) const{
289 if (!WellDone) { StdFail_NotDone::Raise(); }
290 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
292 ParSol = par1sol(Index);
293 ParArg = pararg1(Index);
294 Pnt = gp_Pnt2d(pnttg1sol(Index));
298 void GccAna_Lin2dTanPer::
299 Intersection2 (const Standard_Integer Index,
300 Standard_Real& ParSol,
301 Standard_Real& ParArg,
302 gp_Pnt2d& PntSol) const {
303 if (!WellDone) { StdFail_NotDone::Raise(); }
304 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
306 ParSol = par2sol(Index);
307 ParArg = pararg2(Index);
308 PntSol = gp_Pnt2d(pntint2sol(Index));