Commit | Line | Data |
---|---|---|
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 | // |
973c2be1 | 6 | // This library is free software; you can redistribute it and / or modify it |
7 | // under the terms of the GNU Lesser General Public 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. | |
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 | //========================================================================= | |
0d969553 Y |
16 | // CREATION of a STRAIGHT LINE TANGENT to a CIRCLE or PASSING by a POINT + |
17 | // and ORTHOGONAL to a STRAIGHT LINE. + | |
7fd59977 | 18 | //========================================================================= |
19 | ||
20 | #include <GccAna_Lin2dTanPer.ixx> | |
21 | ||
22 | #include <ElCLib.hxx> | |
23 | #include <StdFail_NotDone.hxx> | |
24 | #include <gp_XY.hxx> | |
25 | #include <gp_Dir2d.hxx> | |
26 | #include <gp_Vec2d.hxx> | |
27 | #include <gp_Circ2d.hxx> | |
28 | #include <Standard_OutOfRange.hxx> | |
29 | #include <GccEnt_BadQualifier.hxx> | |
30 | #include <IntAna2d_AnaIntersection.hxx> | |
31 | #include <IntAna2d_IntPoint.hxx> | |
32 | ||
33 | //========================================================================= | |
0d969553 Y |
34 | // Straight line passing by point : ThePoint and + |
35 | // orthogonal to straight line : TheLin. + | |
36 | // Create the straight line of origin : ThePoint + | |
37 | // and direction : TheLin.Direction() turned by 90 + | |
7fd59977 | 38 | //========================================================================= |
39 | ||
40 | GccAna_Lin2dTanPer:: | |
41 | GccAna_Lin2dTanPer (const gp_Pnt2d& ThePnt , | |
42 | const gp_Lin2d& TheLin ): | |
43 | linsol(1,1), | |
44 | qualifier1(1,1) , | |
45 | pnttg1sol(1,1), | |
46 | pntint2sol(1,1), | |
47 | par1sol(1,1), | |
48 | par2sol(1,1), | |
49 | pararg1(1,1), | |
50 | pararg2(1,1) | |
51 | { | |
52 | ||
53 | linsol(1) = gp_Lin2d(ThePnt,gp_Dir2d(-(TheLin.Direction().Y()), | |
54 | // =============================================================== | |
55 | TheLin.Direction().X())); | |
56 | // ======================== | |
57 | pnttg1sol(1) = ThePnt; | |
58 | IntAna2d_AnaIntersection Intp(linsol(1),TheLin); | |
59 | if (Intp.IsDone()) { | |
60 | if (!Intp.IsEmpty()) { | |
61 | for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { | |
62 | pntint2sol(1) = Intp.Point(i).Value(); | |
63 | } | |
64 | } | |
65 | } | |
66 | par1sol(1) = ElCLib::Parameter(linsol(1),pnttg1sol(1)); | |
67 | par2sol(1) = ElCLib::Parameter(linsol(1),pntint2sol(1)); | |
68 | pararg1(1) = 0.; | |
69 | pararg2(1) = ElCLib::Parameter(TheLin,pntint2sol(1)); | |
70 | NbrSol = 1; | |
71 | WellDone = Standard_True; | |
72 | } | |
73 | ||
74 | //========================================================================= | |
0d969553 Y |
75 | // Straight line passing by point : ThePnt + |
76 | // and orthogonal to circle : TheCircle. + | |
77 | // Create the straight line of origin : ThePoint + | |
78 | // and direction : (TheCircle.Location(),ThePnt). + | |
7fd59977 | 79 | //========================================================================= |
80 | ||
81 | GccAna_Lin2dTanPer:: | |
82 | GccAna_Lin2dTanPer (const gp_Pnt2d& ThePnt , | |
83 | const gp_Circ2d& TheCircle ): | |
84 | linsol(1,1), | |
85 | qualifier1(1,1) , | |
86 | pnttg1sol(1,1), | |
87 | pntint2sol(1,1), | |
88 | par1sol(1,1), | |
89 | par2sol(1,1), | |
90 | pararg1(1,1), | |
91 | pararg2(1,1) | |
92 | { | |
93 | ||
94 | linsol(1) = gp_Lin2d(ThePnt, | |
95 | // ============================ | |
96 | gp_Dir2d(TheCircle.Location().XY()-ThePnt.XY())); | |
97 | // ================================================ | |
98 | pnttg1sol(1) = ThePnt; | |
99 | IntAna2d_AnaIntersection Intp(linsol(1),TheCircle); | |
100 | if (Intp.IsDone()) { | |
101 | if (!Intp.IsEmpty()) { | |
102 | Standard_Real maxdist = RealLast(); | |
103 | for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { | |
104 | if (Intp.Point(i).Value().Distance(ThePnt) < maxdist) { | |
105 | pntint2sol(1) = Intp.Point(i).Value(); | |
106 | } | |
107 | } | |
108 | } | |
109 | } | |
110 | par1sol(1) = ElCLib::Parameter(linsol(1),pnttg1sol(1)); | |
111 | par2sol(1) = ElCLib::Parameter(linsol(1),pntint2sol(1)); | |
112 | pararg1(1) = 0.; | |
113 | pararg2(1) = ElCLib::Parameter(TheCircle,pntint2sol(1)); | |
114 | NbrSol = 1; | |
115 | WellDone = Standard_True; | |
116 | } | |
117 | ||
118 | //========================================================================= | |
0d969553 Y |
119 | // Straight line tangent to circle : Qualified1 (C1) + |
120 | // and orthogonal to straight line : TheLin. + | |
121 | // Create straight line of origin : P1 (on C1) + | |
122 | // and direction : TheLin.Direction() turned by 90` + | |
7fd59977 | 123 | //========================================================================= |
124 | ||
125 | GccAna_Lin2dTanPer:: | |
126 | GccAna_Lin2dTanPer (const GccEnt_QualifiedCirc& Qualified1, | |
127 | const gp_Lin2d& TheLin ): | |
128 | linsol(1,2), | |
129 | qualifier1(1,2) , | |
130 | pnttg1sol(1,2), | |
131 | pntint2sol(1,2), | |
132 | par1sol(1,2), | |
133 | par2sol(1,2), | |
134 | pararg1(1,2), | |
135 | pararg2(1,2) | |
136 | { | |
137 | ||
138 | WellDone = Standard_False; | |
139 | Standard_Integer nbsol = 0; | |
140 | Standard_Integer signe = 0; | |
141 | NbrSol = 0; | |
142 | gp_Circ2d C1 = Qualified1.Qualified(); | |
143 | ||
144 | if (Qualified1.IsEnclosed()) { | |
145 | // ============================ | |
146 | GccEnt_BadQualifier::Raise(); | |
147 | } | |
148 | else if (Qualified1.IsEnclosing()) { | |
149 | // ================================== | |
150 | nbsol = 1; | |
151 | signe = -1; | |
152 | } | |
153 | else if (Qualified1.IsOutside()) { | |
154 | // ================================ | |
155 | nbsol = 1; | |
156 | signe = 1; | |
157 | } | |
158 | else { | |
159 | nbsol = 2; | |
160 | signe = -1; | |
161 | } | |
162 | gp_XY xy(C1.Radius()*TheLin.Direction().XY()); | |
163 | for (Standard_Integer j = 1 ; j <= nbsol ; j++) { | |
164 | signe = -signe; | |
165 | NbrSol++; | |
166 | linsol(NbrSol)=gp_Lin2d(gp_Pnt2d((C1.Location().XY()).Added(signe*xy)), | |
167 | // ======================================================================= | |
168 | gp_Dir2d(-TheLin.Direction().Y(), | |
169 | // ================================= | |
170 | TheLin.Direction().X())); | |
171 | // ======================== | |
172 | pnttg1sol(NbrSol) = gp_Pnt2d((C1.Location().XY()).Added(signe*xy)); | |
173 | IntAna2d_AnaIntersection Intp(linsol(NbrSol),TheLin); | |
174 | if (Intp.IsDone()) { | |
175 | if (!Intp.IsEmpty()) { | |
176 | for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { | |
177 | pntint2sol(NbrSol) = Intp.Point(i).Value(); | |
178 | } | |
179 | } | |
180 | } | |
181 | par1sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pnttg1sol(NbrSol)); | |
182 | par2sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pntint2sol(NbrSol)); | |
183 | pararg1(NbrSol) = ElCLib::Parameter(C1,pnttg1sol(NbrSol)); | |
184 | pararg2(NbrSol) = ElCLib::Parameter(TheLin,pntint2sol(NbrSol)); | |
185 | WellDone = Standard_True; | |
186 | } | |
187 | } | |
188 | ||
189 | //========================================================================= | |
0d969553 Y |
190 | // Straight line tangent to circle : Qualified1 (C1) + |
191 | // and orthogonal to circle : TheCircle. + | |
192 | // Create straight line of origin : P1 (on C1) + | |
193 | // and direction : TheLin.Direction() turned by 90` + | |
7fd59977 | 194 | //========================================================================= |
195 | ||
196 | GccAna_Lin2dTanPer:: | |
197 | GccAna_Lin2dTanPer (const GccEnt_QualifiedCirc& Qualified1, | |
198 | const gp_Circ2d& TheCircle ): | |
199 | linsol(1,2), | |
200 | qualifier1(1,2) , | |
201 | pnttg1sol(1,2), | |
202 | pntint2sol(1,2), | |
203 | par1sol(1,2), | |
204 | par2sol(1,2), | |
205 | pararg1(1,2), | |
206 | pararg2(1,2) | |
207 | { | |
208 | ||
209 | WellDone = Standard_False; | |
210 | NbrSol = 0; | |
7fd59977 | 211 | Standard_Integer signe = 0; |
212 | gp_Circ2d C1 = Qualified1.Qualified(); | |
213 | ||
214 | if (Qualified1.IsEnclosed()) { | |
215 | // ============================ | |
216 | GccEnt_BadQualifier::Raise(); | |
217 | } | |
218 | else if (Qualified1.IsEnclosing()) { | |
219 | // ================================== | |
7fd59977 | 220 | signe = -1; |
221 | qualifier1(1) = GccEnt_enclosing; | |
222 | } | |
223 | else if (Qualified1.IsOutside()) { | |
224 | // ================================ | |
7fd59977 | 225 | signe = 1; |
226 | qualifier1(1) = GccEnt_outside; | |
227 | } | |
228 | else if (Qualified1.IsUnqualified()) { | |
229 | // ==================================== | |
7fd59977 | 230 | signe = -1; |
231 | qualifier1(1) = GccEnt_enclosing; | |
232 | qualifier1(2) = GccEnt_outside; | |
233 | } | |
234 | for (Standard_Integer j = 1 ; j <= 2 ; j++) { | |
235 | NbrSol++; | |
236 | signe = -signe; | |
237 | gp_Dir2d D1(TheCircle.Location().XY()-C1.Location().XY()); | |
238 | linsol(NbrSol) = gp_Lin2d(gp_Pnt2d((C1.Location().XY())+ | |
239 | // =================================================== | |
240 | signe*(D1.XY()*C1.Radius())),gp_Dir2d(-D1.Y(),D1.X())); | |
241 | // ====================================================== | |
242 | pnttg1sol(NbrSol) = gp_Pnt2d((C1.Location().XY())+ | |
243 | signe*(D1.XY()*C1.Radius())); | |
244 | IntAna2d_AnaIntersection Intp(linsol(NbrSol),TheCircle); | |
245 | if (Intp.IsDone()) { | |
246 | if (!Intp.IsEmpty()) { | |
247 | Standard_Real maxdist = RealLast(); | |
248 | for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) { | |
249 | if (Intp.Point(i).Value().Distance(pnttg1sol(NbrSol)) < maxdist) { | |
250 | pntint2sol(NbrSol) = Intp.Point(i).Value(); | |
251 | } | |
252 | } | |
253 | } | |
254 | } | |
255 | par1sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pnttg1sol(NbrSol)); | |
256 | par2sol(NbrSol) = ElCLib::Parameter(linsol(NbrSol),pntint2sol(NbrSol)); | |
257 | pararg1(NbrSol) = ElCLib::Parameter(C1,pnttg1sol(NbrSol)); | |
258 | pararg2(NbrSol) = ElCLib::Parameter(TheCircle,pntint2sol(NbrSol)); | |
259 | WellDone = Standard_True; | |
260 | } | |
261 | } | |
262 | ||
263 | Standard_Boolean GccAna_Lin2dTanPer:: | |
264 | IsDone () const { return WellDone; } | |
265 | ||
266 | Standard_Integer GccAna_Lin2dTanPer:: | |
267 | NbSolutions () const | |
268 | { | |
269 | if (!WellDone) { StdFail_NotDone::Raise(); } | |
270 | return NbrSol; | |
271 | } | |
272 | ||
273 | gp_Lin2d GccAna_Lin2dTanPer:: | |
274 | ThisSolution (const Standard_Integer Index) const | |
275 | { | |
276 | if (!WellDone) { StdFail_NotDone::Raise(); } | |
277 | if (Index <= 0 || Index > NbrSol) { Standard_RangeError::Raise(); } | |
278 | return linsol(Index); | |
279 | } | |
280 | ||
281 | void GccAna_Lin2dTanPer:: | |
282 | WhichQualifier(const Standard_Integer Index , | |
283 | GccEnt_Position& Qualif1 ) const | |
284 | { | |
285 | if (!WellDone) { StdFail_NotDone::Raise(); } | |
286 | if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } | |
287 | else { | |
288 | Qualif1 = qualifier1(Index); | |
289 | } | |
290 | } | |
291 | ||
292 | void GccAna_Lin2dTanPer:: | |
293 | Tangency1 (const Standard_Integer Index, | |
294 | Standard_Real& ParSol, | |
295 | Standard_Real& ParArg, | |
296 | gp_Pnt2d& Pnt) const{ | |
297 | if (!WellDone) { StdFail_NotDone::Raise(); } | |
298 | else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } | |
299 | else { | |
300 | ParSol = par1sol(Index); | |
301 | ParArg = pararg1(Index); | |
302 | Pnt = gp_Pnt2d(pnttg1sol(Index)); | |
303 | } | |
304 | } | |
305 | ||
306 | void GccAna_Lin2dTanPer:: | |
307 | Intersection2 (const Standard_Integer Index, | |
308 | Standard_Real& ParSol, | |
309 | Standard_Real& ParArg, | |
310 | gp_Pnt2d& PntSol) const { | |
311 | if (!WellDone) { StdFail_NotDone::Raise(); } | |
312 | else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } | |
313 | else { | |
314 | ParSol = par2sol(Index); | |
315 | ParArg = pararg2(Index); | |
316 | PntSol = gp_Pnt2d(pntint2sol(Index)); | |
317 | } | |
318 | } | |
319 |