OCC22529 FitALL works incorrectly for small flat shapes
[occt.git] / src / Extrema / Extrema_FuncExtCC.gxx
CommitLineData
7fd59977 1//Modified by MPS : 21-05-97 PRO 7598
2// Le nombre de solutions rendu est mySqDist.Length() et non
3// mySqDist.Length()/2
4// ajout des valeurs absolues dans le test d'orthogonalite de
5// GetStateNumber()
6
7/*-----------------------------------------------------------------------------
8 Fonctions permettant de rechercher une distance extremale entre 2 courbes
9C1 et C2 (en partant de points approches C1(u0) et C2(v0)).
10 Cette classe herite de math_FunctionSetWithDerivatives et est utilisee par
11l'algorithme math_FunctionSetRoot.
12 Si on note Du et Dv, les derivees en u et v, les 2 fonctions a annuler sont:
13 { F1(u,v) = (C2(v)-C1(u)).Du(u)/||Du|| }
14 { F2(u,v) = (C2(v)-C1(u)).Dv(v)||Dv|| }
15 Si on note Duu et Dvv, les derivees secondes de C1 et C2, les derivees de F1
16et F2 sont egales a:
17 { Duf1(u,v) = -||Du|| + C1C2.Duu/||Du||- F1(u,v)*Duu*Du/||Du||**2
18 { Dvf1(u,v) = Dv.Du/||Du||
19 { Duf2(u,v) = -Du.Dv/||Dv||
20 { Dvf2(u,v) = ||Dv|| + C2C1.Dvv/||Dv||- F2(u,v)*Dv*Dvv/||Dv||**2
21
22----------------------------------------------------------------------------*/
23//=============================================================================
24
25#define Tol 1.e-20
26#define delta 1.e-9
27
28Extrema_FuncExtCC::Extrema_FuncExtCC(const Standard_Real thetol) : myC1 (0), myC2 (0), myTol (thetol)
29{
30}
31
32Extrema_FuncExtCC::Extrema_FuncExtCC (const Curve1& C1,
33 const Curve2& C2,
34 const Standard_Real thetol) :
35 myC1 ((Standard_Address)&C1), myC2 ((Standard_Address)&C2),
36 myTol (thetol)
37{
38}
39
40Standard_Boolean Extrema_FuncExtCC::Value (const math_Vector& UV,
41 math_Vector& F)
42{
43
44 Vec Du, Dv;
45
46 myU = UV(1);
47 myV = UV(2);
48 Tool1::D1(*((Curve1*)myC1), myU,myP1,Du);
49 Tool2::D1(*((Curve2*)myC2), myV,myP2,Dv);
50 Vec P1P2 (myP1,myP2);
51
52 Standard_Real Ndu = Du.Magnitude();
53 if (Ndu <= Tol) {
54 Pnt P1, P2;
55 P1 = Tool1::Value(*((Curve1*)myC1), myU-delta);
56 P2 = Tool1::Value(*((Curve1*)myC1), myU+delta);
57 Vec V(P1,P2);
58 Du = V;
59 Ndu = Du.Magnitude();
60 if (Ndu <= Tol) {
61 return Standard_False;
62 }
63 }
64
65 Standard_Real Ndv = Dv.Magnitude();
66 if (Ndv <= Tol) {
67 // Traitement des singularite, on approche la Tangente
68 // par une corde
69 Pnt P1, P2;
70 P1 = Tool2::Value(*((Curve2*)myC2), myV-delta);
71 P2 = Tool2::Value(*((Curve2*)myC2), myV+delta);
72 Vec V(P1,P2);
73 Dv = V;
74 Ndv = Dv.Magnitude();
75 if (Ndv <= Tol) {
76 return Standard_False;
77 }
78 }
79
80 F(1) = P1P2.Dot(Du)/Ndu;
81 F(2) = P1P2.Dot(Dv)/Ndv;
82 return Standard_True;
83}
84//=============================================================================
85
86Standard_Boolean Extrema_FuncExtCC::Derivatives (const math_Vector& UV,
87 math_Matrix& Df)
88{
89 math_Vector F(1,2);
90 return Values(UV,F,Df);
91}
92//=============================================================================
93
94Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
95 math_Vector& F,
96 math_Matrix& Df)
97{
98 myU = UV(1);
99 myV = UV(2);
100 Vec Du, Dv, Duu, Dvv;
101 Tool1::D2(*((Curve1*)myC1), myU,myP1,Du,Duu);
102 Tool2::D2(*((Curve2*)myC2), myV,myP2,Dv,Dvv);
103
104 Vec P1P2 (myP1,myP2);
105
106 Standard_Real Ndu = Du.Magnitude();
107 if (Ndu <= Tol) {
108 Pnt P1, P2;
109 Vec V1;
110 Tool1::D1(*((Curve1*)myC1),myU+delta, P2, Duu);
111 Tool1::D1(*((Curve1*)myC1),myU-delta, P1, V1);
112 Vec V(P1,P2);
113 Du = V;
114 Duu -= V1;
115 Ndu = Du.Magnitude();
116 if (Ndu <= Tol) {
117 return Standard_False;
118 }
119 }
120
121 Standard_Real Ndv = Dv.Magnitude();
122 if (Ndv <= Tol) {
123 Pnt P1, P2;
124 Vec V1;
125 Tool2::D1(*((Curve2*)myC2),myV+delta, P2, Dvv);
126 Tool2::D1(*((Curve2*)myC2),myV-delta, P1, V1);
127 Vec V(P1,P2);
128 Dv = V;
129 Dvv -= V1;
130 Ndv = Dv.Magnitude();
131 if (Ndv <= Tol) {
132 return Standard_False;
133 }
134 }
135
136 F(1) = P1P2.Dot(Du)/Ndu;
137 F(2) = P1P2.Dot(Dv)/Ndv;
138
139 Df(1,1) = - Ndu + (P1P2.Dot(Duu)/Ndu) - F(1)*(Du.Dot(Duu)/(Ndu*Ndu));
140 Df(1,2) = Dv.Dot(Du)/Ndu;
141 Df(2,1) = -Du.Dot(Dv)/Ndv;
142 Df(2,2) = Ndv + (P1P2.Dot(Dvv)/Ndv) - F(2)*(Dv.Dot(Dvv)/(Ndv*Ndv));
143 return Standard_True;
144
145}
146//=============================================================================
147
148Standard_Integer Extrema_FuncExtCC::GetStateNumber ()
149{
150 Vec Du, Dv;
151 Pnt P1, P2;
152 Tool1::D1(*((Curve1*)myC1), myU, P1, Du);
153 Tool2::D1(*((Curve2*)myC2), myV, P2, Dv);
154 Vec P1P2 (P1, P2);
155 Standard_Real mod = Du.Magnitude();
156 if(mod > Tol) {
157 Du /= mod;
158 }
159 mod = Dv.Magnitude();
160 if(mod > Tol) {
161 Dv /= mod;
162 }
163
164 if (Abs(P1P2.Dot(Du)) <= myTol && Abs(P1P2.Dot(Dv)) <= myTol) {
165 mySqDist.Append(myP1.SquareDistance(myP2));
166 myPoints.Append(POnC(myU, myP1));
167 myPoints.Append(POnC(myV, myP2));
168 }
169 return 0;
170}
171//=============================================================================
172
173void Extrema_FuncExtCC::Points (const Standard_Integer N,
174 POnC& P1,
175 POnC& P2) const
176{
177 P1 = myPoints.Value(2*N-1);
178 P2 = myPoints.Value(2*N);
179}
180//=============================================================================
181
182
183
184
185
186
187