0023948: Wrong intersection between a surface of revolution and a plane.
[occt.git] / src / IntAna2d / IntAna2d_Outils.cxx
CommitLineData
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//
d5f74e42 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
973c2be1 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.
b311480e 14
7fd59977 15//============================================================================
16//======================================================= IntAna2d_Outils.cxx
17//============================================================================
18#include <IntAna2d_Outils.hxx>
19#include <math_DirectPolynomialRoots.hxx>
20
21MyDirectPolynomialRoots::MyDirectPolynomialRoots(const Standard_Real A4,
22 const Standard_Real A3,
23 const Standard_Real A2,
24 const Standard_Real A1,
25 const Standard_Real A0) {
26 //-- cout<<" IntAna2d : A4..A0 "<<A4<<" "<<A3<<" "<<A2<<" "<<A1<<" "<<A0<<" "<<endl;
27 nbsol = 0;
28 same = Standard_False;
29// Modified by Sergey KHROMOV - Thu Oct 24 13:10:14 2002 Begin
30 Standard_Real anAA[5];
31
32 anAA[0] = Abs(A0);
33 anAA[1] = Abs(A1);
34 anAA[2] = Abs(A2);
35 anAA[3] = Abs(A3);
36 anAA[4] = Abs(A4);
37
38// if((Abs(A4)+Abs(A3)+Abs(A2)+Abs(A1)+Abs(A0))<Epsilon(10000.0)) {
39 if((anAA[0]+anAA[1]+anAA[2]+anAA[3]+anAA[4])<Epsilon(10000.0)) {
40// Modified by Sergey KHROMOV - Thu Oct 24 13:10:15 2002 End
41 same = Standard_True;
42 return;
43 }
44 Standard_Integer i,j,nbp;
45 for(i=0;i<16;i++) val[i]=RealLast();
46
47 Standard_Real tol = Epsilon(100.0);
48 math_DirectPolynomialRoots MATH_A43210(A4,A3,A2,A1,A0);
49 Standard_Boolean PbPossible = Standard_False;
50 Standard_Integer NbsolPolyComplet = 0;
51 if(MATH_A43210.IsDone()) {
52 nbp = MATH_A43210.NbSolutions();
53 NbsolPolyComplet = nbp;
54 for(i=1;i<=nbp;i++) {
55 Standard_Real x = MATH_A43210.Value(i);
56 //-- cout<<" IntAna2d : x Pol Complet :"<<x<<endl;
57 val[nbsol] = A0 + x*(A1+x*(A2+x*(A3+x*A4)));
58 sol[nbsol] = x;
59 if(val[nbsol]> tol || val[nbsol]<-tol) {
60 PbPossible = Standard_True;
61 }
62 nbsol++;
63 }
64 if(nbp & 1)
65 PbPossible = Standard_True;
66 }
67 else {
68 PbPossible = Standard_True;
69 }
70 //-- On recherche le plus petit coeff entre A4 et A0
71 if(PbPossible) {
72// Modified by Sergey KHROMOV - Thu Oct 24 12:45:35 2002 Begin
73 Standard_Real anAMin = RealLast();
74 Standard_Real anAMax = -1;
75 Standard_Real anEps = RealEpsilon();
76
77 for (i = 0; i < 5; i++) {
78 anAMin = Min(anAMin, Max(anAA[i], anEps));
79 anAMax = Max(anAMax, Max(anAA[i], anEps));
80 }
81
82 anEps = Min(1.e-4, Epsilon(1000.*anAMax/anAMin));
83// Modified by Sergey KHROMOV - Thu Oct 24 15:46:24 2002 End
84 math_DirectPolynomialRoots MATH_A4321(A4,A3,A2,A1);
85 if(MATH_A4321.IsDone()) {
86 nbp = MATH_A4321.NbSolutions();
87 //-- On Ajoute les valeurs au tableau
88 for(i=1;i<=nbp;i++) {
89 Standard_Real x = MATH_A4321.Value(i);
90 Standard_Boolean Add = Standard_True;
91 for(j=0;j<nbsol;j++) {
92 Standard_Real t = sol[j]-x;
93// Modified by Sergey KHROMOV - Thu Oct 24 12:04:26 2002 Begin
94// if(Abs(t)<tol) {
95 if(Abs(t) < anEps) {
96// Modified by Sergey KHROMOV - Thu Oct 24 12:04:47 2002 End
97 Add = Standard_False;
98 }
99 }
100 if(Add) {
101 val[nbsol] = A0 + x*(A1+x*(A2+x*(A3+x*A4)));
102 sol[nbsol] = x;
103 nbsol++;
104 }
105 }
106 }
107 math_DirectPolynomialRoots MATH_A3210(A3,A2,A1,A0);
108 if(MATH_A3210.IsDone()) {
109 nbp = MATH_A3210.NbSolutions();
110 //-- On Ajoute les valeurs au tableau
111 for(i=1;i<=nbp;i++) {
112 Standard_Real x = MATH_A3210.Value(i);
113 Standard_Boolean Add = Standard_True;
114 for(j=0;j<nbsol;j++) {
115 Standard_Real t = sol[j]-x;
116// Modified by Sergey KHROMOV - Thu Oct 24 12:06:01 2002 Begin
117// if(Abs(t)<tol) {
118 if(Abs(t) < anEps) {
119// Modified by Sergey KHROMOV - Thu Oct 24 12:06:04 2002 End
120 Add = Standard_False;
121 }
122 }
123 if(Add) {
124 val[nbsol] = A0 + x*(A1+x*(A2+x*(A3+x*A4)));
125 sol[nbsol] = x;
126 nbsol++;
127 }
128 }
129 }
130 math_DirectPolynomialRoots MATH_A210(A3,A2,A1);
131 if(MATH_A210.IsDone()) {
132 nbp = MATH_A210.NbSolutions();
133 //-- On Ajoute les valeurs au tableau
134 for(i=1;i<=nbp;i++) {
135 Standard_Real x = MATH_A210.Value(i);
136 Standard_Boolean Add = Standard_True;
137 for(j=0;j<nbsol;j++) {
138 Standard_Real t = sol[j]-x;
139// Modified by Sergey KHROMOV - Thu Oct 24 12:07:04 2002 Begin
140// if(Abs(t)<tol) {
141 if(Abs(t) < anEps) {
142// Modified by Sergey KHROMOV - Thu Oct 24 12:07:06 2002 End
143 Add = Standard_False;
144 }
145 }
146 if(Add) {
147 val[nbsol] = A0 + x*(A1+x*(A2+x*(A3+x*A4)));
148 sol[nbsol] = x;
149 nbsol++;
150 }
151 }
152 }
153 //------------------------------------------------------------
154 //-- On trie les valeurs par ordre decroissant de val
155 //-- for(i=0;i<nbsol;i++) {
156 //-- cout<<" IntAna2d Sol,Val"<<sol[i]<<" "<<val[i]<<endl;
157 //-- }
158 Standard_Boolean TriOK = Standard_False;
159 do {
160 TriOK = Standard_True;
161 for(i=1; i<nbsol;i++) {
162 if(Abs(val[i])<Abs(val[i-1])) {
163 Standard_Real t;
164 t = val[i];
165 val[i] = val[i-1];
166 val[i-1] = t;
167 t = sol[i];
168 sol[i] = sol[i-1];
169 sol[i-1] = t;
170 TriOK = Standard_False;
171 }
172 }
173 }
174 while(!TriOK);
175 //-----------------------------------------------------------
176 //-- On garde les premieres valeurs
177 //-- Au moins autant que le polynome Complet
178 //--
179 for(nbsol=0; nbsol<NbsolPolyComplet || Abs(val[nbsol])<Epsilon(10000.0); nbsol++) ;
180 //-- cout<<" IntAna2d : nbsol:"<<nbsol<<endl;
181 }
182 if(nbsol==0) {
183 nbsol=-1;
184 }
185 if(nbsol>4) {
186 same=1;
187 nbsol=0;
188 }
189}
190
191
192MyDirectPolynomialRoots::MyDirectPolynomialRoots(const Standard_Real A2,
193 const Standard_Real A1,
194 const Standard_Real A0) {
195 //-- cout<<" IntAna2d : A2..A0 "<<A2<<" "<<A1<<" "<<A0<<" "<<endl;
196 nbsol=0;
197 if((Abs(A2)+Abs(A1)+Abs(A0))<Epsilon(10000.0)) {
198 same = Standard_True;
199 return;
200 }
201 math_DirectPolynomialRoots MATH_A210(A2,A1,A0);
202 same = Standard_False;
203 if(MATH_A210.IsDone()) {
204 for(Standard_Integer i=1;i<=MATH_A210.NbSolutions(); i++) {
205 Standard_Real x = MATH_A210.Value(i);
206 val[nbsol] = A0 + x*(A1+x*A2);
207 sol[nbsol] = x;
208 //-- cout<<" IntAna2d : x Pol Complet :"<<x<<" Val:"<<val[nbsol]<<endl;
209 nbsol++;
210 }
211 }
212 else {
213 nbsol = -1;
214 }
215}
216
217Standard_Boolean Points_Confondus(const Standard_Real x1,const Standard_Real y1
218 ,const Standard_Real x2,const Standard_Real y2) {
219 if(Abs(x1-x2)<Epsilon(x1)) {
220 if(Abs(y1-y2)<Epsilon(y1)) {
221 return(Standard_True);
222 }
223 }
224 return(Standard_False);
225}
226
227//-----------------------------------------------------------------------------
228//--- Les points confondus sont supprimes
229//--- Le nombre de points est mis a jour
230
231void Traitement_Points_Confondus(Standard_Integer& nb_pts,
232 IntAna2d_IntPoint* pts) {
233 Standard_Integer i,j;
234 for(i=nb_pts;i>1;i--) {
235 Standard_Boolean Non_Egalite=Standard_True;
236 for(j=i-1;(j>0) && Non_Egalite;j--) {
237 // <--- Deja Teste --->
238 // | 1 |2 | | J | |I-1| I |I+1| |NPTS|
239 // | 1 |2 | | J | |I-1|XXX|I+1| |NPTS|
240 // | 1 |2 | | J | |I-1|I+1|I+2| |NPTS|
241 if(Points_Confondus(pts[i-1].Value().X(),
242 pts[i-1].Value().Y(),
243 pts[j-1].Value().X(),
244 pts[j-1].Value().Y())) {
245 Standard_Integer k;
246 Non_Egalite=Standard_False;
247 for(k=i;k<nb_pts;k++) {
248 Standard_Real Xk,Yk,Uk;
249 Xk=pts[k].Value().X();
250 Yk=pts[k].Value().Y();
251 Uk=pts[k].ParamOnFirst();
252 pts[k-1].SetValue(Xk,Yk,Uk);
253 }
254 nb_pts--;
255 }
256 }
257 }
258}
259
260//-----------------------------------------------------------------------------
261void Coord_Ancien_Repere(Standard_Real& x1,Standard_Real& y1,const gp_Ax2d Dir1) {
262 Standard_Real t11,t12,t21,t22,t13,t23;
263 Standard_Real x0,y0;
264
265 // x1 et y1 Sont les Coordonnees dans le repere lie a Dir1
266 // On Renvoie ces Coordonnees dans le repere "absolu"
267
268 Dir1.Direction().Coord(t11,t21);
269 Dir1.Location().Coord(t13,t23);
270
271 t22=t11;
272 t12=-t21;
273
274 x0= t11*x1 + t12*y1 + t13;
275 y0= t21*x1 + t22*y1 + t23;
276
277 x1=x0;
278 y1=y0;
279}
280
281
282
283#if 0
284
285//-- A Placer dans les ressources de la classe Conic ??
286//-----------------------------------------------------------------------------
287//--- Calcul des Coefficients A,..F dans le repere lie a Dir1
288//--- A Partir des Coefficients dans le repere "Absolu"
289
290void Coeff_Nouveau_Repere(Standard_Real& A,Standard_Real& B,Standard_Real& C
291 ,Standard_Real& D,Standard_Real& E,Standard_Real& F
292 ,const gp_Ax2d Dir1) {
293 Standard_Real t11,t12,t13; // x = t11 X + t12 Y + t13
294 Standard_Real t21,t22,t23; // y = t21 X + t22 Y + t23
295 Standard_Real A1,B1,C1,D1,E1,F1;
296
297 // On a P0(x,y)=A x x + B y y + ... + F =0 (x et y ds le repere "Absolu")
298 // et on cherche P1(X(x,y),Y(x,y))=P0(x,y)
299 // Avec P1(X,Y)= A1 X X + B1 Y Y + 2 C1 X Y + 2 D1 X + 2 E1 Y + F1
300 // = A x x + B y y + 2 C x y + 2 D x + 2 E y + f
301
302 Dir1.Direction().Coord(t11,t21);
303 Dir1.Location().Coord(t13,t23);
304
305 t22=t11;
306 t12=-t21;
307
308 A1=(t11*(A*t11 + 2*C*t21) + B*t21*t21);
309 B1=(t12*(A*t12 + 2*C*t22) + B*t22*t22);
310 C1=(t12*(A*t11 + C*t21) + t22*(C*t11 + B*t21));
311 D1=(t11*(D + A*t13) + t21*(E + C*t13) + t23*(C*t11 + B*t21));
312 E1=(t12*(D + A*t13) + t22*(E + C*t13) + t23*(C*t12 + B*t22));
313 F1=F + t13*(2.0*D + A*t13) + t23*(2.0*E + 2.0*C*t13 + B*t23);
314
315 A=A1; B=B1; C=C1; D=D1; E=E1; F=F1;
316}
317#endif
318
319
320
321
322
323
324
325
326
327