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 |
9 | C1 et C2 (en partant de points approches C1(u0) et C2(v0)). |
10 | Cette classe herite de math_FunctionSetWithDerivatives et est utilisee par |
11 | l'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 |
16 | et 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 | |
28 | Extrema_FuncExtCC::Extrema_FuncExtCC(const Standard_Real thetol) : myC1 (0), myC2 (0), myTol (thetol) |
29 | { |
30 | } |
31 | |
32 | Extrema_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 | |
40 | Standard_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 | |
86 | Standard_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 | |
94 | Standard_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 | |
148 | Standard_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 | |
173 | void 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 | |