Commit | Line | Data |
---|---|---|
7fd59977 | 1 | |
2 | #include <stdio.h> | |
3 | ||
4 | #include <Extrema_ExtElC.ixx> | |
5 | #include <StdFail_InfiniteSolutions.hxx> | |
6 | #include <StdFail_NotDone.hxx> | |
7 | #include <ElCLib.hxx> | |
8 | #include <math_TrigonometricFunctionRoots.hxx> | |
9 | #include <math_DirectPolynomialRoots.hxx> | |
10 | #include <Standard_OutOfRange.hxx> | |
11 | #include <Standard_NotImplemented.hxx> | |
12 | #include <Precision.hxx> | |
13 | #include <Extrema_ExtPElC.hxx> | |
14 | #include <IntAna_QuadQuadGeo.hxx> | |
15 | #include <Extrema_ExtPElC.hxx> | |
16 | ||
17 | #include <gp_Pln.hxx> | |
18 | #include <gp_Ax3.hxx> | |
19 | #include <gp_Ax2.hxx> | |
20 | #include <gp_Pnt.hxx> | |
21 | #include <gp_Dir.hxx> | |
22 | #include <gp_Ax1.hxx> | |
23 | ||
eb0a5b14 P |
24 | //modified by NIZNHY-PKV Wed Sep 21 08:02:16 2011f |
25 | static | |
26 | void RefineDir(gp_Dir& aDir); | |
27 | //modified by NIZNHY-PKV Wed Sep 21 08:02:20 2011t | |
093fdf5f P |
28 | //======================================================================= |
29 | //class : ExtremaExtElC_TrigonometricRoots | |
30 | //purpose : | |
7fd59977 | 31 | //== Classe Interne (Donne des racines classees d un polynome trigo) |
32 | //== Code duplique avec IntAna_IntQuadQuad.cxx (lbr le 26 mars 98) | |
33 | //== Solution fiable aux problemes de coefficients proches de 0 | |
34 | //== avec essai de rattrapage si coeff<1.e-10 (jct le 27 avril 98) | |
093fdf5f | 35 | //======================================================================= |
7fd59977 | 36 | class ExtremaExtElC_TrigonometricRoots { |
37 | private: | |
38 | Standard_Real Roots[4]; | |
39 | Standard_Boolean done; | |
40 | Standard_Integer NbRoots; | |
41 | Standard_Boolean infinite_roots; | |
42 | public: | |
093fdf5f P |
43 | ExtremaExtElC_TrigonometricRoots(const Standard_Real CC, |
44 | const Standard_Real SC, | |
45 | const Standard_Real C, | |
46 | const Standard_Real S, | |
47 | const Standard_Real Cte, | |
48 | const Standard_Real Binf, | |
49 | const Standard_Real Bsup); | |
50 | // | |
51 | Standard_Boolean IsDone() { | |
52 | return done; | |
53 | } | |
54 | // | |
7fd59977 | 55 | Standard_Boolean IsARoot(Standard_Real u) { |
093fdf5f P |
56 | Standard_Integer i; |
57 | Standard_Real PIpPI, aEps; | |
58 | // | |
59 | aEps=RealEpsilon(); | |
60 | PIpPI=Standard_PI+Standard_PI; | |
7fd59977 | 61 | for(Standard_Integer i=0 ; i<NbRoots; i++) { |
093fdf5f P |
62 | if(Abs(u - Roots[i])<=aEps) { |
63 | return Standard_True ; | |
64 | } | |
65 | if(Abs(u - Roots[i]-PIpPI)<=aEps) { | |
66 | return Standard_True; | |
67 | } | |
7fd59977 | 68 | } |
093fdf5f | 69 | return Standard_False; |
7fd59977 | 70 | } |
093fdf5f | 71 | // |
7fd59977 | 72 | Standard_Integer NbSolutions() { |
093fdf5f P |
73 | if(!done) { |
74 | StdFail_NotDone::Raise(); | |
75 | } | |
76 | return NbRoots; | |
7fd59977 | 77 | } |
093fdf5f | 78 | // |
7fd59977 | 79 | Standard_Boolean InfiniteRoots() { |
093fdf5f P |
80 | if(!done) { |
81 | StdFail_NotDone::Raise(); | |
82 | } | |
83 | return infinite_roots; | |
7fd59977 | 84 | } |
093fdf5f P |
85 | // |
86 | Standard_Real Value(const Standard_Integer& n) { | |
87 | if((!done)||(n>NbRoots)) { | |
88 | StdFail_NotDone::Raise(); | |
89 | } | |
90 | return Roots[n-1]; | |
7fd59977 | 91 | } |
92 | }; | |
093fdf5f P |
93 | //======================================================================= |
94 | //function : ExtremaExtElC_TrigonometricRoots | |
95 | //purpose : | |
96 | //======================================================================= | |
97 | ExtremaExtElC_TrigonometricRoots:: | |
98 | ExtremaExtElC_TrigonometricRoots(const Standard_Real CC, | |
99 | const Standard_Real SC, | |
100 | const Standard_Real C, | |
101 | const Standard_Real S, | |
102 | const Standard_Real Cte, | |
103 | const Standard_Real Binf, | |
104 | const Standard_Real Bsup) | |
105 | { | |
106 | Standard_Integer i, nbessai; | |
107 | Standard_Real cc ,sc, c, s, cte; | |
108 | // | |
109 | nbessai = 1; | |
110 | cc = CC; | |
111 | sc = SC; | |
112 | c = C; | |
113 | s = S; | |
114 | cte = Cte; | |
7fd59977 | 115 | done=Standard_False; |
116 | while (nbessai<=2 && !done) { | |
117 | //-- F= AA*CN*CN+2*BB*CN*SN+CC*CN+DD*SN+EE; | |
118 | math_TrigonometricFunctionRoots MTFR(cc,sc,c,s,cte,Binf,Bsup); | |
093fdf5f | 119 | // |
7fd59977 | 120 | if(MTFR.IsDone()) { |
121 | done=Standard_True; | |
122 | if(MTFR.InfiniteRoots()) { | |
123 | infinite_roots=Standard_True; | |
124 | } | |
093fdf5f P |
125 | else { //else #1 |
126 | Standard_Boolean Triee; | |
127 | Standard_Integer j, SvNbRoots; | |
128 | Standard_Real aTwoPI, aMaxCoef, aPrecision; | |
129 | // | |
130 | aTwoPI=PI+PI; | |
7fd59977 | 131 | NbRoots=MTFR.NbSolutions(); |
093fdf5f | 132 | for(i=0;i<NbRoots;++i) { |
7fd59977 | 133 | Roots[i]=MTFR.Value(i+1); |
093fdf5f P |
134 | if(Roots[i]<0.) { |
135 | Roots[i]=Roots[i]+aTwoPI; | |
136 | } | |
137 | if(Roots[i]>aTwoPI) { | |
138 | Roots[i]=Roots[i]-aTwoPI; | |
139 | } | |
7fd59977 | 140 | } |
7fd59977 | 141 | //-- La recherche directe donne n importe quoi. |
142 | // modified by OCC Tue Oct 3 18:41:27 2006.BEGIN | |
093fdf5f | 143 | aMaxCoef = Max(CC,SC); |
7fd59977 | 144 | aMaxCoef = Max(aMaxCoef,C); |
145 | aMaxCoef = Max(aMaxCoef,S); | |
146 | aMaxCoef = Max(aMaxCoef,Cte); | |
093fdf5f | 147 | aPrecision = Max(1.e-8, 1.e-12*aMaxCoef); |
7fd59977 | 148 | // modified by OCC Tue Oct 3 18:41:33 2006.END |
149 | ||
093fdf5f P |
150 | SvNbRoots=NbRoots; |
151 | for(i=0; i<SvNbRoots; ++i) { | |
7fd59977 | 152 | Standard_Real y; |
093fdf5f | 153 | Standard_Real co=cos(Roots[i]); |
7fd59977 | 154 | Standard_Real si=sin(Roots[i]); |
155 | y=co*(CC*co + (SC+SC)*si + C) + S*si + Cte; | |
156 | // modified by OCC Tue Oct 3 18:43:00 2006 | |
157 | if(Abs(y)>aPrecision) { | |
7fd59977 | 158 | NbRoots--; |
159 | Roots[i]=1000.0; | |
160 | } | |
161 | } | |
093fdf5f | 162 | // |
7fd59977 | 163 | do { |
093fdf5f P |
164 | Standard_Real t; |
165 | // | |
7fd59977 | 166 | Triee=Standard_True; |
093fdf5f | 167 | for(i=1, j=0; i<SvNbRoots; ++i, ++j) { |
7fd59977 | 168 | if(Roots[i]<Roots[j]) { |
169 | Triee=Standard_False; | |
093fdf5f P |
170 | t=Roots[i]; |
171 | Roots[i]=Roots[j]; | |
172 | Roots[j]=t; | |
7fd59977 | 173 | } |
174 | } | |
175 | } | |
176 | while(!Triee); | |
093fdf5f | 177 | // |
7fd59977 | 178 | infinite_roots=Standard_False; |
b2342827 | 179 | if(NbRoots==0) { //--!!!!! Detect case Pol = Cte ( 1e-50 ) !!!! |
7fd59977 | 180 | if((Abs(CC) + Abs(SC) + Abs(C) + Abs(S)) < 1e-10) { |
181 | if(Abs(Cte) < 1e-10) { | |
182 | infinite_roots=Standard_True; | |
183 | } | |
184 | } | |
185 | } | |
093fdf5f P |
186 | } // else #1 |
187 | } // if(MTFR.IsDone()) { | |
7fd59977 | 188 | else { |
b2342827 | 189 | // try to set very small coefficients to ZERO |
093fdf5f P |
190 | if (Abs(CC)<1e-10) { |
191 | cc = 0.0; | |
192 | } | |
193 | if (Abs(SC)<1e-10) { | |
194 | sc = 0.0; | |
195 | } | |
196 | if (Abs(C)<1e-10) { | |
197 | c = 0.0; | |
198 | } | |
199 | if (Abs(S)<1e-10){ | |
200 | s = 0.0; | |
201 | } | |
202 | if (Abs(Cte)<1e-10){ | |
203 | cte = 0.0; | |
204 | } | |
7fd59977 | 205 | nbessai++; |
206 | } | |
093fdf5f | 207 | } // while (nbessai<=2 && !done) { |
7fd59977 | 208 | } |
209 | ||
093fdf5f P |
210 | //======================================================================= |
211 | //function : Extrema_ExtElC | |
212 | //purpose : | |
213 | //======================================================================= | |
214 | Extrema_ExtElC::Extrema_ExtElC () | |
215 | { | |
216 | myDone = Standard_False; | |
217 | } | |
218 | //======================================================================= | |
219 | //function : Extrema_ExtElC | |
220 | //purpose : | |
221 | //======================================================================= | |
222 | Extrema_ExtElC::Extrema_ExtElC (const gp_Lin& C1, | |
223 | const gp_Lin& C2, | |
7fd59977 | 224 | const Standard_Real) |
b2342827 Y |
225 | // Function: |
226 | // Find min distance between 2 straight lines. | |
227 | ||
228 | // Method: | |
229 | // Let D1 and D2, be 2 directions of straight lines C1 and C2. | |
230 | // 2 cases are considered: | |
231 | // 1- if Angle(D1,D2) < AngTol, straight lines are parallel. | |
232 | // The distance is the distance between a point of C1 and the straight line C2. | |
233 | // 2- if Angle(D1,D2) > AngTol: | |
234 | // Let P1=C1(u1) and P2=C2(u2) be 2 solution points: | |
235 | // Then, ( P1P2.D1 = 0. (1) | |
7fd59977 | 236 | // ( P1P2.D2 = 0. (2) |
b2342827 Y |
237 | // Let O1 and O2 be the origins of C1 and C2; |
238 | // THen, (1) <=> (O1P2-u1*D1).D1 = 0. as O1P1 = u1*D1 | |
239 | // <=> u1 = O1P2.D1 as D1.D1 = 1. | |
240 | // (2) <=> (P1O2+u2*D2).D2 = 0. as O2P2 = u2*D2 | |
241 | // <=> u2 = O2P1.D2 as D2.D2 = 1. | |
7fd59977 | 242 | // <=> u2 = (O2O1+O1P1).D2 |
b2342827 | 243 | // <=> u2 = O2O1.D2+((O1P2.T1)T1).T2) as O1P1 = u1*T1 = (O1P2.T1)T1 |
7fd59977 | 244 | // <=> u2 = O2O1.D2+(((O1O2+O2P2).D1)D1).D2) |
245 | // <=> u2 = O2O1.D2+((O1O2.D1)D1).D2)+(O2P2.D1)(D1.D2) | |
246 | // <=> u2 = ((O1O2.D1)D1-O1O2).D2 + u2*(D2.D1)(D1.D2) | |
247 | // <=> u2 = (((O1O2.D1)D1-O1O2).D2) / 1.-(D1.D2)**2 | |
248 | { | |
249 | myDone = Standard_False; | |
250 | myNbExt = 0; | |
251 | ||
252 | gp_Dir D1 = C1.Position().Direction(); | |
253 | gp_Dir D2 = C2.Position().Direction(); | |
254 | // MSV 16/01/2000: avoid "divide by zero" | |
255 | Standard_Real D1DotD2 = D1.Dot(D2); | |
256 | Standard_Real aSin = 1.-D1DotD2*D1DotD2; | |
257 | if (aSin < gp::Resolution() || | |
258 | D1.IsParallel(D2, Precision::Angular())) { | |
259 | myIsPar = Standard_True; | |
260 | mySqDist[0] = C2.SquareDistance(C1.Location()); | |
261 | mySqDist[1] = mySqDist[0]; | |
262 | } | |
263 | else { | |
264 | myIsPar = Standard_False; | |
265 | gp_Pnt O1 = C1.Location(); | |
266 | gp_Pnt O2 = C2.Location(); | |
267 | gp_Vec O1O2 (O1,O2); | |
268 | Standard_Real U2 = (D1.XYZ()*(O1O2.Dot(D1))-(O1O2.XYZ())).Dot(D2.XYZ()); | |
269 | if( Precision::IsInfinite(U2) ) { | |
270 | myIsPar = Standard_True; | |
271 | mySqDist[0] = C2.SquareDistance(C1.Location()); | |
272 | mySqDist[1] = mySqDist[0]; | |
273 | } | |
274 | else { | |
275 | U2 /= aSin; | |
276 | if( Precision::IsInfinite(U2) ) { | |
277 | myIsPar = Standard_True; | |
278 | mySqDist[0] = C2.SquareDistance(C1.Location()); | |
279 | mySqDist[1] = mySqDist[0]; | |
280 | } | |
281 | else { | |
282 | gp_Pnt P2(ElCLib::Value(U2,C2)); | |
283 | Standard_Real U1 = (gp_Vec(O1,P2)).Dot(D1); | |
284 | if( Precision::IsInfinite(U1) ) { | |
285 | myIsPar = Standard_True; | |
286 | mySqDist[0] = C2.SquareDistance(C1.Location()); | |
287 | mySqDist[1] = mySqDist[0]; | |
288 | } | |
289 | else { | |
290 | gp_Pnt P1(ElCLib::Value(U1,C1)); | |
291 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
292 | myPoint[myNbExt][0] = Extrema_POnCurv(U1,P1); | |
293 | myPoint[myNbExt][1] = Extrema_POnCurv(U2,P2); | |
294 | myNbExt = 1; | |
295 | } | |
296 | } | |
297 | } | |
298 | } | |
299 | myDone = Standard_True; | |
300 | } | |
093fdf5f P |
301 | //======================================================================= |
302 | //function : Extrema_ExtElC | |
303 | //purpose : | |
304 | //======================================================================= | |
305 | Extrema_ExtElC::Extrema_ExtElC (const gp_Lin& C1, | |
306 | const gp_Circ& C2, | |
7fd59977 | 307 | const Standard_Real) |
308 | /*----------------------------------------------------------------------------- | |
309 | Fonction: | |
b2342827 | 310 | Find extreme distances between straight line C1 and circle C2. |
7fd59977 | 311 | |
b2342827 Y |
312 | Method: |
313 | Let P1=C1(u1) and P2=C2(u2) be two solution points | |
314 | D the direction of straight line C1 | |
315 | T tangent at point P2; | |
316 | Then, ( P1P2.D = 0. (1) | |
7fd59977 | 317 | ( P1P2.T = 0. (2) |
b2342827 Y |
318 | Let O1 and O2 be the origins of C1 and C2; |
319 | Then, (1) <=> (O1P2-u1*D).D = 0. as O1P1 = u1*D | |
320 | <=> u1 = O1P2.D as D.D = 1. | |
321 | (2) <=> P1O2.T = 0. as O2P2.T = 0. | |
322 | <=> ((P2O1.D)D+O1O2).T = 0. as P1O1 = -u1*D = (P2O1.D)D | |
7fd59977 | 323 | <=> (((P2O2+O2O1).D)D+O1O2).T = 0. |
324 | <=> ((P2O2.D)(D.T)+((O2O1.D)D-O2O1).T = 0. | |
b2342827 Y |
325 | We are in the reference of the circle; let: |
326 | Cos = Cos(u2) and Sin = Sin(u2), | |
7fd59977 | 327 | P2 (R*Cos,R*Sin,0.), |
328 | T (-R*Sin,R*Cos,0.), | |
329 | D (Dx,Dy,Dz), | |
330 | V (Vx,Vy,Vz) = (O2O1.D)D-O2O1; | |
b2342827 | 331 | Then, the equation by Cos and Sin is as follows: |
7fd59977 | 332 | -(2*R*R*Dx*Dy) * Cos**2 + A1 |
333 | R*R*(Dx**2-Dy**2) * Cos*Sin + 2* A2 | |
334 | R*Vy * Cos + A3 | |
335 | -R*Vx * Sin + A4 | |
336 | R*R*Dx*Dy = 0. A5 | |
b2342827 | 337 | Use the algorithm math_TrigonometricFunctionRoots to solve this equation. |
7fd59977 | 338 | -----------------------------------------------------------------------------*/ |
339 | { | |
eb0a5b14 P |
340 | Standard_Real Dx,Dy,Dz,aRO2O1, aTolRO2O1; |
341 | Standard_Real R, A1, A2, A3, A4, A5, aTol; | |
342 | gp_Dir x2, y2, z2, D, D1; | |
343 | // | |
7fd59977 | 344 | myIsPar = Standard_False; |
345 | myDone = Standard_False; | |
346 | myNbExt = 0; | |
b2342827 Y |
347 | |
348 | // Calculate T1 in the reference of the circle ... | |
eb0a5b14 P |
349 | D = C1.Direction(); |
350 | D1 = D; | |
7fd59977 | 351 | x2 = C2.XAxis().Direction(); |
352 | y2 = C2.YAxis().Direction(); | |
353 | z2 = C2.Axis().Direction(); | |
eb0a5b14 P |
354 | Dx = D.Dot(x2); |
355 | Dy = D.Dot(y2); | |
356 | Dz = D.Dot(z2); | |
357 | // | |
358 | D.SetCoord(Dx, Dy, Dz); | |
359 | //modified by NIZNHY-PKV Wed Sep 21 08:02:46 2011f | |
360 | RefineDir(D); | |
361 | D.Coord(Dx, Dy, Dz); | |
362 | //modified by NIZNHY-PKV Wed Sep 21 08:02:48 2011t | |
363 | // | |
364 | // Calcul de V dans le repere du cercle: | |
7fd59977 | 365 | gp_Pnt O1 = C1.Location(); |
366 | gp_Pnt O2 = C2.Location(); | |
367 | gp_Vec O2O1 (O2,O1); | |
eb0a5b14 P |
368 | // |
369 | //modified by NIZNHY-PKV Wed Sep 21 07:45:39 2011f | |
370 | aTolRO2O1=gp::Resolution(); | |
371 | aRO2O1=O2O1.Magnitude(); | |
372 | if (aRO2O1 > aTolRO2O1) { | |
373 | gp_Dir aDO2O1; | |
374 | // | |
375 | O2O1.Multiply(1./aRO2O1); | |
376 | aDO2O1.SetCoord(O2O1.Dot(x2), O2O1.Dot(y2), O2O1.Dot(z2)); | |
377 | RefineDir(aDO2O1); | |
378 | O2O1.SetXYZ(aRO2O1*aDO2O1.XYZ()); | |
379 | } | |
380 | else { | |
381 | O2O1.SetCoord(O2O1.Dot(x2), O2O1.Dot(y2), O2O1.Dot(z2)); | |
382 | } | |
383 | //O2O1.SetCoord(O2O1.Dot(x2), O2O1.Dot(y2), O2O1.Dot(z2)); | |
384 | //modified by NIZNHY-PKV Wed Sep 21 07:45:42 2011t | |
385 | // | |
7fd59977 | 386 | gp_XYZ Vxyz = (D.XYZ()*(O2O1.Dot(D)))-O2O1.XYZ(); |
b2342827 Y |
387 | |
388 | // Calculate the coefficients of the equation by Cos and Sin ... | |
eb0a5b14 P |
389 | aTol=1.e-12; |
390 | R = C2.Radius(); | |
391 | A5 = R*R*Dx*Dy; | |
392 | A1 = -2.*A5; | |
393 | A2 = R*R*(Dx*Dx-Dy*Dy)/2.; | |
394 | A3 = R*Vxyz.Y(); | |
395 | A4 = -R*Vxyz.X(); | |
396 | // | |
397 | if(fabs(A5) <= aTol) { | |
398 | A5 = 0.; | |
399 | } | |
400 | if(fabs(A1) <= aTol) { | |
401 | A1 = 0.; | |
402 | } | |
403 | if(fabs(A2) <= aTol) { | |
404 | A2 = 0.; | |
405 | } | |
406 | if(fabs(A3) <= aTol) { | |
407 | A3 = 0.; | |
408 | } | |
409 | if(fabs(A4) <= aTol) { | |
410 | A4 = 0.; | |
411 | } | |
412 | // | |
7fd59977 | 413 | ExtremaExtElC_TrigonometricRoots Sol(A1,A2,A3,A4,A5,0.,PI+PI); |
eb0a5b14 P |
414 | if (!Sol.IsDone()) { |
415 | return; | |
416 | } | |
7fd59977 | 417 | if (Sol.InfiniteRoots()) { |
418 | myIsPar = Standard_True; | |
419 | mySqDist[0] = R*R; | |
420 | myDone = Standard_True; | |
421 | return; | |
422 | } | |
b2342827 | 423 | // Storage of solutions ... |
eb0a5b14 | 424 | Standard_Integer NoSol, NbSol; |
7fd59977 | 425 | Standard_Real U1,U2; |
eb0a5b14 P |
426 | gp_Pnt P1,P2; |
427 | // | |
428 | NbSol = Sol.NbSolutions(); | |
429 | for (NoSol=1; NoSol<=NbSol; ++NoSol) { | |
7fd59977 | 430 | U2 = Sol.Value(NoSol); |
431 | P2 = ElCLib::Value(U2,C2); | |
432 | U1 = (gp_Vec(O1,P2)).Dot(D1); | |
433 | P1 = ElCLib::Value(U1,C1); | |
434 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
435 | myPoint[myNbExt][0] = Extrema_POnCurv(U1,P1); | |
436 | myPoint[myNbExt][1] = Extrema_POnCurv(U2,P2); | |
437 | myNbExt++; | |
438 | } | |
439 | myDone = Standard_True; | |
440 | } | |
093fdf5f P |
441 | //======================================================================= |
442 | //function : Extrema_ExtElC | |
443 | //purpose : | |
444 | //======================================================================= | |
445 | Extrema_ExtElC::Extrema_ExtElC (const gp_Lin& C1, | |
446 | const gp_Elips& C2) | |
7fd59977 | 447 | { |
448 | /*----------------------------------------------------------------------------- | |
b2342827 Y |
449 | Function: |
450 | Find extreme distances between straight line C1 and ellipse C2. | |
451 | ||
452 | Method: | |
453 | Let P1=C1(u1) and P2=C2(u2) two solution points | |
454 | D the direction of straight line C1 | |
455 | T the tangent to point P2; | |
456 | Then, ( P1P2.D = 0. (1) | |
7fd59977 | 457 | ( P1P2.T = 0. (2) |
b2342827 Y |
458 | Let O1 and O2 be the origins of C1 and C2; |
459 | Then, (1) <=> (O1P2-u1*D).D = 0. as O1P1 = u1*D | |
460 | <=> u1 = O1P2.D as D.D = 1. | |
461 | (2) <=> P1O2.T = 0. as O2P2.T = 0. | |
462 | <=> ((P2O1.D)D+O1O2).T = 0. as P1O1 = -u1*D = (P2O1.D)D | |
7fd59977 | 463 | <=> (((P2O2+O2O1).D)D+O1O2).T = 0. |
464 | <=> ((P2O2.D)(D.T)+((O2O1.D)D-O2O1).T = 0. | |
b2342827 Y |
465 | We are in the reference of the ellipse; let: |
466 | Cos = Cos(u2) and Sin = Sin(u2), | |
7fd59977 | 467 | P2 (MajR*Cos,MinR*Sin,0.), |
468 | T (-MajR*Sin,MinR*Cos,0.), | |
469 | D (Dx,Dy,Dz), | |
470 | V (Vx,Vy,Vz) = (O2O1.D)D-O2O1; | |
b2342827 | 471 | Then, get the following equation by Cos and Sin: |
7fd59977 | 472 | -(2*MajR*MinR*Dx*Dy) * Cos**2 + |
473 | (MajR*MajR*Dx**2-MinR*MinR*Dy**2) * Cos*Sin + | |
474 | MinR*Vy * Cos + | |
475 | - MajR*Vx * Sin + | |
476 | MinR*MajR*Dx*Dy = 0. | |
b2342827 | 477 | Use algorithm math_TrigonometricFunctionRoots to solve this equation. |
7fd59977 | 478 | -----------------------------------------------------------------------------*/ |
479 | myIsPar = Standard_False; | |
480 | myDone = Standard_False; | |
481 | myNbExt = 0; | |
482 | ||
b2342827 | 483 | // Calculate T1 the reference of the ellipse ... |
7fd59977 | 484 | gp_Dir D = C1.Direction(); |
485 | gp_Dir D1 = D; | |
486 | gp_Dir x2, y2, z2; | |
487 | x2 = C2.XAxis().Direction(); | |
488 | y2 = C2.YAxis().Direction(); | |
489 | z2 = C2.Axis().Direction(); | |
490 | Standard_Real Dx = D.Dot(x2); | |
491 | Standard_Real Dy = D.Dot(y2); | |
492 | Standard_Real Dz = D.Dot(z2); | |
493 | D.SetCoord(Dx,Dy,Dz); | |
494 | ||
b2342827 | 495 | // Calculate V ... |
7fd59977 | 496 | gp_Pnt O1 = C1.Location(); |
497 | gp_Pnt O2 = C2.Location(); | |
498 | gp_Vec O2O1 (O2,O1); | |
499 | O2O1.SetCoord(O2O1.Dot(x2), O2O1.Dot(y2), O2O1.Dot(z2)); | |
500 | gp_XYZ Vxyz = (D.XYZ()*(O2O1.Dot(D)))-O2O1.XYZ(); | |
501 | ||
b2342827 | 502 | // Calculate the coefficients of the equation by Cos and Sin ... |
7fd59977 | 503 | Standard_Real MajR = C2.MajorRadius(); |
504 | Standard_Real MinR = C2.MinorRadius(); | |
505 | Standard_Real A5 = MajR*MinR*Dx*Dy; | |
506 | Standard_Real A1 = -2.*A5; | |
507 | Standard_Real R2 = MajR*MajR; | |
508 | Standard_Real r2 = MinR*MinR; | |
509 | Standard_Real A2 =(R2*Dx*Dx -r2*Dy*Dy -R2 +r2)/2.0; | |
510 | Standard_Real A3 = MinR*Vxyz.Y(); | |
511 | Standard_Real A4 = -MajR*Vxyz.X(); | |
093fdf5f P |
512 | // |
513 | //modified by NIZNHY-PKV Thu Feb 03 14:51:04 2011f | |
514 | Standard_Real aEps=1.e-12; | |
515 | // | |
516 | if(fabs(A5) <= aEps) A5 = 0.; | |
517 | if(fabs(A1) <= aEps) A1 = 0.; | |
518 | if(fabs(A2) <= aEps) A2 = 0.; | |
519 | if(fabs(A3) <= aEps) A3 = 0.; | |
520 | if(fabs(A4) <= aEps) A4 = 0.; | |
521 | //modified by NIZNHY-PKV Thu Feb 03 14:51:08 2011t | |
522 | // | |
7fd59977 | 523 | ExtremaExtElC_TrigonometricRoots Sol(A1,A2,A3,A4,A5,0.,PI+PI); |
524 | if (!Sol.IsDone()) { return; } | |
525 | ||
b2342827 | 526 | // Storage of solutions ... |
7fd59977 | 527 | gp_Pnt P1,P2; |
528 | Standard_Real U1,U2; | |
529 | Standard_Integer NbSol = Sol.NbSolutions(); | |
530 | for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) { | |
531 | U2 = Sol.Value(NoSol); | |
532 | P2 = ElCLib::Value(U2,C2); | |
533 | U1 = (gp_Vec(O1,P2)).Dot(D1); | |
534 | P1 = ElCLib::Value(U1,C1); | |
535 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
536 | myPoint[myNbExt][0] = Extrema_POnCurv(U1,P1); | |
537 | myPoint[myNbExt][1] = Extrema_POnCurv(U2,P2); | |
538 | myNbExt++; | |
539 | } | |
540 | myDone = Standard_True; | |
541 | } | |
7fd59977 | 542 | |
093fdf5f P |
543 | //======================================================================= |
544 | //function : Extrema_ExtElC | |
545 | //purpose : | |
546 | //======================================================================= | |
547 | Extrema_ExtElC::Extrema_ExtElC (const gp_Lin& C1, | |
548 | const gp_Hypr& C2) | |
7fd59977 | 549 | { |
550 | /*----------------------------------------------------------------------------- | |
b2342827 Y |
551 | Function: |
552 | Find extrema between straight line C1 and hyperbola C2. | |
553 | ||
554 | Method: | |
555 | Let P1=C1(u1) and P2=C2(u2) be two solution points | |
556 | D the direction of straight line C1 | |
557 | T the tangent at point P2; | |
558 | Then, ( P1P2.D = 0. (1) | |
559 | ( P1P2.T = 0. (2) | |
560 | Let O1 and O2 be the origins of C1 and C2; | |
561 | Then, (1) <=> (O1P2-u1*D).D = 0. as O1P1 = u1*D | |
562 | <=> u1 = O1P2.D as D.D = 1. | |
7fd59977 | 563 | (2) <=> (P1O2 + O2P2).T= 0. |
b2342827 | 564 | <=> ((P2O1.D)D+O1O2 + O2P2).T = 0. as P1O1 = -u1*D = (P2O1.D)D |
7fd59977 | 565 | <=> (((P2O2+O2O1).D)D+O1O2 + O2P2).T = 0. |
566 | <=> (P2O2.D)(D.T)+((O2O1.D)D-O2O1).T + O2P2.T= 0. | |
b2342827 Y |
567 | We are in the reference of the hyperbola; let: |
568 | by writing P (R* Chu, r* Shu, 0.0) | |
569 | and Chu = (v**2 + 1)/(2*v) , | |
570 | Shu = (V**2 - 1)/(2*v) | |
7fd59977 | 571 | |
572 | T(R*Shu, r*Chu) | |
573 | D (Dx,Dy,Dz), | |
574 | V (Vx,Vy,Vz) = (O2O1.D)D-O2O1; | |
575 | ||
b2342827 | 576 | Then we obtain the following equation by v: |
7fd59977 | 577 | (-2*R*r*Dx*Dy - R*R*Dx*Dx-r*r*Dy*Dy + R*R + r*r) * v**4 + |
578 | (2*R*Vx + 2*r*Vy) * v**3 + | |
579 | (-2*R*Vx + 2*r*Vy) * v + | |
580 | (-2*R*r*Dx*Dy - (R*R*Dx*Dx-r*r*Dy*Dy + R*R + r*r)) = 0 | |
581 | ||
582 | ||
b2342827 | 583 | Use the algorithm math_DirectPolynomialRoots to solve this equation. |
7fd59977 | 584 | -----------------------------------------------------------------------------*/ |
585 | myIsPar = Standard_False; | |
586 | myDone = Standard_False; | |
587 | myNbExt = 0; | |
588 | ||
b2342827 | 589 | // Calculate T1 in the reference of the hyperbola... |
7fd59977 | 590 | gp_Dir D = C1.Direction(); |
591 | gp_Dir D1 = D; | |
592 | gp_Dir x2, y2, z2; | |
593 | x2 = C2.XAxis().Direction(); | |
594 | y2 = C2.YAxis().Direction(); | |
595 | z2 = C2.Axis().Direction(); | |
596 | Standard_Real Dx = D.Dot(x2); | |
597 | Standard_Real Dy = D.Dot(y2); | |
598 | Standard_Real Dz = D.Dot(z2); | |
599 | D.SetCoord(Dx,Dy,Dz); | |
600 | ||
b2342827 | 601 | // Calculate V ... |
7fd59977 | 602 | gp_Pnt O1 = C1.Location(); |
603 | gp_Pnt O2 = C2.Location(); | |
604 | gp_Vec O2O1 (O2,O1); | |
605 | O2O1.SetCoord(O2O1.Dot(x2), O2O1.Dot(y2), O2O1.Dot(z2)); | |
606 | gp_XYZ Vxyz = (D.XYZ()*(O2O1.Dot(D)))-O2O1.XYZ(); | |
607 | Standard_Real Vx = Vxyz.X(); | |
608 | Standard_Real Vy = Vxyz.Y(); | |
609 | ||
b2342827 | 610 | // Calculate coefficients of the equation by v |
7fd59977 | 611 | Standard_Real R = C2.MajorRadius(); |
612 | Standard_Real r = C2.MinorRadius(); | |
613 | Standard_Real a = -2*R*r*Dx*Dy; | |
614 | Standard_Real b = -R*R*Dx*Dx - r*r*Dy*Dy + R*R + r*r; | |
615 | Standard_Real A1 = a + b; | |
616 | Standard_Real A2 = 2*R*Vx + 2*r*Vy; | |
617 | Standard_Real A4 = -2*R*Vx + 2*r*Vy; | |
618 | Standard_Real A5 = a - b; | |
619 | ||
620 | math_DirectPolynomialRoots Sol(A1,A2,0.0,A4, A5); | |
621 | if (!Sol.IsDone()) { return; } | |
622 | ||
b2342827 | 623 | // Store solutions ... |
7fd59977 | 624 | gp_Pnt P1,P2; |
625 | Standard_Real U1,U2, v; | |
626 | Standard_Integer NbSol = Sol.NbSolutions(); | |
627 | for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) { | |
628 | v = Sol.Value(NoSol); | |
629 | if (v > 0.0) { | |
630 | U2 = Log(v); | |
631 | P2 = ElCLib::Value(U2,C2); | |
632 | U1 = (gp_Vec(O1,P2)).Dot(D1); | |
633 | P1 = ElCLib::Value(U1,C1); | |
634 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
635 | myPoint[myNbExt][0] = Extrema_POnCurv(U1,P1); | |
636 | myPoint[myNbExt][1] = Extrema_POnCurv(U2,P2); | |
637 | myNbExt++; | |
638 | } | |
639 | } | |
640 | myDone = Standard_True; | |
641 | } | |
093fdf5f P |
642 | //======================================================================= |
643 | //function : Extrema_ExtElC | |
644 | //purpose : | |
645 | //======================================================================= | |
646 | Extrema_ExtElC::Extrema_ExtElC (const gp_Lin& C1, | |
647 | const gp_Parab& C2) | |
7fd59977 | 648 | { |
649 | /*----------------------------------------------------------------------------- | |
b2342827 Y |
650 | Function: |
651 | Find extreme distances between straight line C1 and parabole C2. | |
652 | ||
653 | Method: | |
654 | Let P1=C1(u1) and P2=C2(u2) be two solution points | |
655 | D the direction of straight line C1 | |
656 | T the tangent to point P2; | |
657 | Then, ( P1P2.D = 0. (1) | |
658 | ( P1P2.T = 0. (2) | |
659 | Let O1 and O2 be the origins of C1 and C2; | |
660 | Then, (1) <=> (O1P2-u1*D).D = 0. as O1P1 = u1*D | |
661 | <=> u1 = O1P2.D as D.D = 1. | |
7fd59977 | 662 | (2) <=> (P1O2 + O2P2).T= 0. |
b2342827 | 663 | <=> ((P2O1.D)D+O1O2 + O2P2).T = 0. as P1O1 = -u1*D = (P2O1.D)D |
7fd59977 | 664 | <=> (((P2O2+O2O1).D)D+O1O2 + O2P2).T = 0. |
665 | <=> (P2O2.D)(D.T)+((O2O1.D)D-O2O1).T + O2P2.T = 0. | |
b2342827 | 666 | We are in the reference of the parabola; let: |
7fd59977 | 667 | P2 (y*y/(2*p), y, 0) |
668 | T (y/p, 1, 0) | |
669 | D (Dx,Dy,Dz), | |
670 | V (Vx,Vy,Vz) = (O2O1.D)D-O2O1; | |
671 | ||
b2342827 | 672 | Then, get the following equation by y: |
7fd59977 | 673 | ((1-Dx*Dx)/(2*p*p)) * y*y*y + A1 |
674 | (-3*Dx*Dy/(2*p)) * y*y + A2 | |
675 | (1-Dy*Dy + Vx/p) * y + A3 | |
676 | Vy = 0. A4 | |
677 | ||
b2342827 | 678 | Use the algorithm math_DirectPolynomialRoots to solve this equation. |
7fd59977 | 679 | -----------------------------------------------------------------------------*/ |
680 | myIsPar = Standard_False; | |
681 | myDone = Standard_False; | |
682 | myNbExt = 0; | |
683 | ||
b2342827 | 684 | // Calculate T1 in the reference of the parabola... |
7fd59977 | 685 | gp_Dir D = C1.Direction(); |
686 | gp_Dir D1 = D; | |
687 | gp_Dir x2, y2, z2; | |
688 | x2 = C2.XAxis().Direction(); | |
689 | y2 = C2.YAxis().Direction(); | |
690 | z2 = C2.Axis().Direction(); | |
691 | Standard_Real Dx = D.Dot(x2); | |
692 | Standard_Real Dy = D.Dot(y2); | |
693 | Standard_Real Dz = D.Dot(z2); | |
694 | D.SetCoord(Dx,Dy,Dz); | |
695 | ||
b2342827 | 696 | // Calculate V ... |
7fd59977 | 697 | gp_Pnt O1 = C1.Location(); |
698 | gp_Pnt O2 = C2.Location(); | |
699 | gp_Vec O2O1 (O2,O1); | |
700 | O2O1.SetCoord(O2O1.Dot(x2), O2O1.Dot(y2), O2O1.Dot(z2)); | |
701 | gp_XYZ Vxyz = (D.XYZ()*(O2O1.Dot(D)))-O2O1.XYZ(); | |
702 | ||
b2342827 | 703 | // Calculate coefficients of the equation by y |
7fd59977 | 704 | Standard_Real P = C2.Parameter(); |
705 | Standard_Real A1 = (1-Dx*Dx)/(2.0*P*P); | |
706 | Standard_Real A2 = (-3.0*Dx*Dy/(2.0*P)); | |
707 | Standard_Real A3 = (1 - Dy*Dy + Vxyz.X()/P); | |
708 | Standard_Real A4 = Vxyz.Y(); | |
709 | ||
710 | math_DirectPolynomialRoots Sol(A1,A2,A3,A4); | |
711 | if (!Sol.IsDone()) { return; } | |
712 | ||
b2342827 | 713 | // Storage of solutions ... |
7fd59977 | 714 | gp_Pnt P1,P2; |
715 | Standard_Real U1,U2; | |
716 | Standard_Integer NbSol = Sol.NbSolutions(); | |
717 | for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) { | |
718 | U2 = Sol.Value(NoSol); | |
719 | P2 = ElCLib::Value(U2,C2); | |
720 | U1 = (gp_Vec(O1,P2)).Dot(D1); | |
721 | P1 = ElCLib::Value(U1,C1); | |
722 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
723 | myPoint[myNbExt][0] = Extrema_POnCurv(U1,P1); | |
724 | myPoint[myNbExt][1] = Extrema_POnCurv(U2,P2); | |
725 | myNbExt++; | |
726 | } | |
727 | myDone = Standard_True; | |
728 | } | |
7fd59977 | 729 | //======================================================================= |
730 | //function : Extrema_ExtElC | |
731 | //purpose : | |
732 | //======================================================================= | |
093fdf5f P |
733 | Extrema_ExtElC::Extrema_ExtElC (const gp_Circ& C1, |
734 | const gp_Circ& C2) | |
7fd59977 | 735 | { |
736 | Standard_Boolean bIsSamePlane, bIsSameAxe; | |
737 | Standard_Real aTolD, aTolD2, aTolA, aD2, aDC2; | |
738 | gp_Pnt aPc1, aPc2; | |
739 | gp_Dir aDc1, aDc2; | |
740 | // | |
741 | myIsPar = Standard_False; | |
742 | myDone = Standard_False; | |
743 | myNbExt = 0; | |
744 | // | |
745 | aTolA=Precision::Angular(); | |
746 | aTolD=Precision::Confusion(); | |
747 | aTolD2=aTolD*aTolD; | |
748 | // | |
749 | aPc1=C1.Location(); | |
750 | aDc1=C1.Axis().Direction(); | |
751 | ||
752 | aPc2=C2.Location(); | |
753 | aDc2=C2.Axis().Direction(); | |
754 | gp_Pln aPlc1(aPc1, aDc1); | |
755 | // | |
756 | aD2=aPlc1.SquareDistance(aPc2); | |
757 | bIsSamePlane=aDc1.IsParallel(aDc2, aTolA) && aD2<aTolD2; | |
758 | if (!bIsSamePlane) { | |
759 | return; | |
760 | } | |
761 | // | |
762 | aDC2=aPc1.SquareDistance(aPc2); | |
763 | bIsSameAxe=aDC2<aTolD2; | |
764 | // | |
765 | if(bIsSameAxe) { | |
766 | myIsPar = Standard_True; | |
767 | Standard_Real dR = C1.Radius() - C2.Radius(); | |
768 | Standard_Real dC = C1.Location().Distance(C2.Location()); | |
769 | mySqDist[0] = dR*dR + dC*dC; | |
770 | dR = C1.Radius() + C2.Radius(); | |
771 | mySqDist[1] = dR*dR + dC*dC; | |
772 | myDone = Standard_True; | |
773 | } | |
774 | else { | |
775 | Standard_Boolean bIn, bOut; | |
776 | Standard_Integer j1, j2; | |
777 | Standard_Real aR1, aR2, aD12, aT11, aT12, aT21, aT22; | |
778 | gp_Circ aC1, aC2; | |
779 | gp_Pnt aP11, aP12, aP21, aP22; | |
780 | // | |
781 | myDone = Standard_True; | |
782 | // | |
783 | aR1=C1.Radius(); | |
784 | aR2=C2.Radius(); | |
785 | // | |
786 | j1=0; | |
787 | j2=1; | |
788 | aC1=C1; | |
789 | aC2=C2; | |
790 | if (aR2>aR1) { | |
791 | j1=1; | |
792 | j2=0; | |
793 | aC1=C2; | |
794 | aC2=C1; | |
795 | } | |
796 | // | |
797 | aR1=aC1.Radius(); // max radius | |
798 | aR2=aC2.Radius(); // min radius | |
799 | // | |
800 | aPc1=aC1.Location(); | |
801 | aPc2=aC2.Location(); | |
802 | // | |
803 | aD12=aPc1.Distance(aPc2); | |
804 | gp_Vec aVec12(aPc1, aPc2); | |
805 | gp_Dir aDir12(aVec12); | |
806 | // | |
807 | // 1. Four common solutions | |
808 | myNbExt=4; | |
809 | // | |
810 | aP11.SetXYZ(aPc1.XYZ()-aR1*aDir12.XYZ()); | |
811 | aP12.SetXYZ(aPc1.XYZ()+aR1*aDir12.XYZ()); | |
812 | aP21.SetXYZ(aPc2.XYZ()-aR2*aDir12.XYZ()); | |
813 | aP22.SetXYZ(aPc2.XYZ()+aR2*aDir12.XYZ()); | |
814 | // | |
815 | aT11=ElCLib::Parameter(aC1, aP11); | |
816 | aT12=ElCLib::Parameter(aC1, aP12); | |
817 | aT21=ElCLib::Parameter(aC2, aP21); | |
818 | aT22=ElCLib::Parameter(aC2, aP22); | |
819 | // | |
820 | // P11, P21 | |
821 | myPoint[0][j1].SetValues(aT11, aP11); | |
822 | myPoint[0][j2].SetValues(aT21, aP21); | |
823 | mySqDist[0]=aP11.SquareDistance(aP21); | |
824 | // P11, P22 | |
825 | myPoint[1][j1].SetValues(aT11, aP11); | |
826 | myPoint[1][j2].SetValues(aT22, aP22); | |
827 | mySqDist[1]=aP11.SquareDistance(aP22); | |
828 | // | |
829 | // P12, P21 | |
830 | myPoint[2][j1].SetValues(aT12, aP12); | |
831 | myPoint[2][j2].SetValues(aT21, aP21); | |
832 | mySqDist[2]=aP12.SquareDistance(aP21); | |
833 | // | |
834 | // P12, P22 | |
835 | myPoint[3][j1].SetValues(aT12, aP12); | |
836 | myPoint[3][j2].SetValues(aT22, aP22); | |
837 | mySqDist[3]=aP12.SquareDistance(aP22); | |
838 | // | |
839 | // 2. Check for intersections | |
840 | bOut=aD12>(aR1+aR2+aTolD); | |
841 | bIn =aD12<(aR1-aR2-aTolD); | |
842 | if (!bOut && !bIn) { | |
843 | Standard_Boolean bNbExt6; | |
844 | Standard_Real aAlpha, aBeta, aT[2], aVal, aDist2; | |
845 | gp_Pnt aPt, aPL1, aPL2; | |
846 | gp_Dir aDLt; | |
847 | // | |
848 | aAlpha=0.5*(aR1*aR1-aR2*aR2+aD12*aD12)/aD12; | |
849 | aVal=aR1*aR1-aAlpha*aAlpha; | |
850 | if (aVal<0.) {// see pkv/900/L4 for details | |
851 | aVal=-aVal; | |
852 | } | |
853 | aBeta=Sqrt(aVal); | |
854 | //aBeta=Sqrt(aR1*aR1-aAlpha*aAlpha); | |
855 | //-- | |
856 | aPt.SetXYZ(aPc1.XYZ()+aAlpha*aDir12.XYZ()); | |
857 | // | |
858 | aDLt=aDc1^aDir12; | |
859 | aPL1.SetXYZ(aPt.XYZ()+aBeta*aDLt.XYZ()); | |
860 | aPL2.SetXYZ(aPt.XYZ()-aBeta*aDLt.XYZ()); | |
861 | // | |
862 | aDist2=aPL1.SquareDistance(aPL2); | |
863 | bNbExt6=aDist2>aTolD2; | |
864 | // | |
865 | myNbExt=5;// just in case. see pkv/900/L4 for details | |
866 | aT[j1]=ElCLib::Parameter(aC1, aPL1); | |
867 | aT[j2]=ElCLib::Parameter(aC2, aPL1); | |
868 | myPoint[4][j1].SetValues(aT[j1], aPL1); | |
869 | myPoint[4][j2].SetValues(aT[j2], aPL1); | |
870 | mySqDist[4]=0.; | |
871 | // | |
872 | if (bNbExt6) { | |
873 | myNbExt=6; | |
874 | aT[j1]=ElCLib::Parameter(aC1, aPL2); | |
875 | aT[j2]=ElCLib::Parameter(aC2, aPL2); | |
876 | myPoint[5][j1].SetValues(aT[j1], aPL2); | |
877 | myPoint[5][j2].SetValues(aT[j2], aPL2); | |
878 | mySqDist[5]=0.; | |
879 | } | |
880 | // | |
881 | }// if (!bOut || !bIn) { | |
882 | }// else | |
883 | } | |
093fdf5f P |
884 | //======================================================================= |
885 | //function : Extrema_ExtElC | |
886 | //purpose : | |
887 | //======================================================================= | |
888 | Extrema_ExtElC::Extrema_ExtElC (const gp_Circ&, const gp_Elips&) | |
889 | { | |
890 | Standard_NotImplemented::Raise(); | |
891 | } | |
892 | //======================================================================= | |
893 | //function : Extrema_ExtElC | |
894 | //purpose : | |
895 | //======================================================================= | |
896 | Extrema_ExtElC::Extrema_ExtElC (const gp_Circ&, const gp_Hypr&) | |
897 | { | |
898 | Standard_NotImplemented::Raise(); | |
899 | } | |
900 | //======================================================================= | |
901 | //function : Extrema_ExtElC | |
902 | //purpose : | |
903 | //======================================================================= | |
904 | Extrema_ExtElC::Extrema_ExtElC (const gp_Circ&, const gp_Parab&) | |
905 | { | |
906 | Standard_NotImplemented::Raise(); | |
907 | } | |
908 | //======================================================================= | |
909 | //function : Extrema_ExtElC | |
910 | //purpose : | |
911 | //======================================================================= | |
912 | Extrema_ExtElC::Extrema_ExtElC (const gp_Elips&, const gp_Elips&) | |
913 | { | |
914 | Standard_NotImplemented::Raise(); | |
915 | } | |
916 | //======================================================================= | |
917 | //function : Extrema_ExtElC | |
918 | //purpose : | |
919 | //======================================================================= | |
920 | Extrema_ExtElC::Extrema_ExtElC (const gp_Elips&, const gp_Hypr&) | |
921 | { | |
922 | Standard_NotImplemented::Raise(); | |
923 | } | |
924 | //======================================================================= | |
925 | //function : Extrema_ExtElC | |
926 | //purpose : | |
927 | //======================================================================= | |
928 | Extrema_ExtElC::Extrema_ExtElC (const gp_Elips&, const gp_Parab&) | |
929 | { | |
930 | Standard_NotImplemented::Raise(); | |
931 | } | |
932 | //======================================================================= | |
933 | //function : Extrema_ExtElC | |
934 | //purpose : | |
935 | //======================================================================= | |
936 | Extrema_ExtElC::Extrema_ExtElC (const gp_Hypr&, const gp_Hypr&) | |
937 | { | |
938 | Standard_NotImplemented::Raise(); | |
939 | } | |
940 | //======================================================================= | |
941 | //function : Extrema_ExtElC | |
942 | //purpose : | |
943 | //======================================================================= | |
944 | Extrema_ExtElC::Extrema_ExtElC (const gp_Hypr&, const gp_Parab&) | |
945 | { | |
946 | Standard_NotImplemented::Raise(); | |
947 | } | |
948 | //======================================================================= | |
949 | //function : Extrema_ExtElC | |
950 | //purpose : | |
951 | //======================================================================= | |
952 | Extrema_ExtElC::Extrema_ExtElC (const gp_Parab&, const gp_Parab&) | |
953 | { | |
954 | Standard_NotImplemented::Raise(); | |
955 | } | |
956 | //======================================================================= | |
957 | //function : IsDone | |
958 | //purpose : | |
959 | //======================================================================= | |
960 | Standard_Boolean Extrema_ExtElC::IsDone () const { | |
961 | return myDone; | |
962 | } | |
963 | //======================================================================= | |
964 | //function : IsParallel | |
965 | //purpose : | |
966 | //======================================================================= | |
967 | Standard_Boolean Extrema_ExtElC::IsParallel () const | |
968 | { | |
969 | if (!IsDone()) { | |
970 | StdFail_NotDone::Raise(); | |
971 | } | |
972 | return myIsPar; | |
973 | } | |
974 | //======================================================================= | |
975 | //function : NbExt | |
976 | //purpose : | |
977 | //======================================================================= | |
978 | Standard_Integer Extrema_ExtElC::NbExt () const | |
979 | { | |
980 | if (IsParallel()) { | |
981 | StdFail_InfiniteSolutions::Raise(); | |
982 | } | |
983 | return myNbExt; | |
984 | } | |
985 | //======================================================================= | |
986 | //function : SquareDistance | |
987 | //purpose : | |
988 | //======================================================================= | |
989 | Standard_Real Extrema_ExtElC::SquareDistance (const Standard_Integer N) const | |
990 | { | |
991 | if (!myDone) { | |
992 | StdFail_NotDone::Raise(); | |
993 | } | |
994 | if (myIsPar) { | |
995 | if (N < 1 || N > 2) { | |
996 | Standard_OutOfRange::Raise(); | |
997 | } | |
998 | } | |
999 | else { | |
1000 | if (N < 1 || N > NbExt()) { | |
1001 | Standard_OutOfRange::Raise(); | |
1002 | } | |
1003 | } | |
1004 | return mySqDist[N-1]; | |
1005 | } | |
eb0a5b14 P |
1006 | //======================================================================= |
1007 | //function : Points | |
1008 | //purpose : | |
1009 | //======================================================================= | |
093fdf5f P |
1010 | void Extrema_ExtElC::Points (const Standard_Integer N, |
1011 | Extrema_POnCurv& P1, | |
1012 | Extrema_POnCurv& P2) const | |
1013 | { | |
1014 | if (N < 1 || N > NbExt()) { | |
1015 | Standard_OutOfRange::Raise(); | |
1016 | } | |
1017 | P1 = myPoint[N-1][0]; | |
1018 | P2 = myPoint[N-1][1]; | |
1019 | } | |
eb0a5b14 P |
1020 | //modified by NIZNHY-PKV Wed Sep 21 07:59:19 2011f |
1021 | //======================================================================= | |
1022 | //function : RefineDir | |
1023 | //purpose : | |
1024 | //======================================================================= | |
1025 | void RefineDir(gp_Dir& aDir) | |
1026 | { | |
1027 | Standard_Integer i, j, k, iK; | |
1028 | Standard_Real aCx[3], aEps, aX1, aX2, aOne; | |
1029 | // | |
1030 | iK=3; | |
1031 | aEps=RealEpsilon(); | |
1032 | aDir.Coord(aCx[0], aCx[1], aCx[2]); | |
1033 | // | |
1034 | for (i=0; i<iK; ++i) { | |
1035 | aOne=(aCx[i]>0.) ? 1. : -1.; | |
1036 | aX1=aOne-aEps; | |
1037 | aX2=aOne+aEps; | |
1038 | // | |
1039 | if (aCx[i]>aX1 && aCx[i]<aX2) { | |
1040 | j=(i+1)%iK; | |
1041 | k=(i+2)%iK; | |
1042 | aCx[i]=aOne; | |
1043 | aCx[j]=0.; | |
1044 | aCx[k]=0.; | |
1045 | aDir.SetCoord(aCx[0], aCx[1], aCx[2]); | |
1046 | return; | |
1047 | } | |
1048 | } | |
1049 | } | |
1050 | //modified by NIZNHY-PKV Wed Sep 21 07:59:26 2011t |