1 //-------------------------------------------------------------------
2 // algorihme lieu a fleche constante
4 // cas traites : courbe parametree
5 // la courbe doit etre C2
6 // on assure une fleche maxi
8 // algorithme courbe parametree:
11 // le calcul du pas d avancement est
12 // du = sqrt(8*fleche*||P'(u)||/||P'(u)^P''(u)||
14 // on calcule chaque point t.q. u+Du
16 // on verifie si la fleche est effectivement respectee ,si oui on continue
17 // sinon on rectifie le pas
19 // si du ne peut etre calculer (courbure nulle ,singularite sur la courbe) on
20 // prendra alors un pas constant pour atteindre le dernier point ou le depass// er
22 // le dernier point est reajuste selon les criteres suivants:
24 // si le dernier parametre calcule <2*resolution,on recadre le dernier
25 // point trouve entre lui meme et le precedent et on rajoute le point
26 // de fin (eviter une concentration a la fin)
28 // sinon si la distance (dernier point calcule ,point de fin)<fleche,on
29 // remplace le dernier point calcule par le point de fin
31 // sinon on calcule une fleche max entre l avant dernier point calcule
32 // et le point de fin ;si cette fleche est superieure a la fleche on
33 // remplace le dernier point par celui ci et le point de fin
36 // LES CONTROLES DE FLECHE ET DERNIER POINT NE SONT FAITS QUE SI
39 // chaque iteration calcule au maximum 3 points
42 //-------------------------------------------------------------------------
44 #include <CPnts_UniformDeflection.ixx>
46 #include <StdFail_NotDone.hxx>
47 #include <Standard_DomainError.hxx>
48 #include <Standard_OutOfRange.hxx>
49 #include <Standard_ConstructionError.hxx>
53 #include <gp_Pnt2d.hxx>
54 #include <gp_Vec2d.hxx>
56 static inline void D03d(const Standard_Address C, const Standard_Real U,
59 ((Adaptor3d_Curve*)C)->D0(U,P);
62 static void D02d(const Standard_Address C, const Standard_Real U,
66 ((Adaptor2d_Curve2d*)C)->D0(U,P);
67 PP.SetCoord(P.X(),P.Y(),0.);
70 static inline void D13d(const Standard_Address C, const Standard_Real U,
71 gp_Pnt& P, gp_Vec& V1)
73 ((Adaptor3d_Curve*)C)->D1(U,P,V1);
78 static void D12d(const Standard_Address C, const Standard_Real U,
79 gp_Pnt& PP, gp_Vec& VV1)
83 ((Adaptor2d_Curve2d*)C)->D1(U,P,V1);
84 PP.SetCoord(P.X(),P.Y(),0.);
85 VV1.SetCoord(V1.X(),V1.Y(),0.);
89 static inline void D23d(const Standard_Address C, const Standard_Real U,
90 gp_Pnt& P, gp_Vec& V1, gp_Vec& V2)
92 ((Adaptor3d_Curve*)C)->D2(U,P,V1,V2);
95 static void D22d(const Standard_Address C, const Standard_Real U,
96 gp_Pnt& PP, gp_Vec& VV1, gp_Vec& VV2)
100 ((Adaptor2d_Curve2d*)C)->D2(U,P,V1,V2);
101 PP.SetCoord(P.X(),P.Y(),0.);
102 VV1.SetCoord(V1.X(),V1.Y(),0.);
103 VV2.SetCoord(V2.X(),V2.Y(),0.);
106 //=======================================================================
109 //=======================================================================
111 void CPnts_UniformDeflection::Perform()
114 // gp_Vec V1, V2, VV1, VV2, VV;
117 Standard_Real NormD1, NormD2;
122 while ( (myNbPoints<2) && (!myFinish) ) {
124 myNbPoints = myNbPoints + 1;
125 myParams[myNbPoints] = myFirstParam;
128 D23d(myCurve, myFirstParam, myPoints[myNbPoints], V1, V2);
130 D22d(myCurve, myFirstParam, myPoints[myNbPoints], V1, V2);
131 P = myPoints[myNbPoints] ;
132 NormD1 = V1.Magnitude();
133 if (NormD1 < myTolCur || V2.Magnitude() < myTolCur) {
134 // singularite sur la tangente ou courbure nulle
135 myDu = Min(myDwmax, 1.5 * myDu);
138 NormD2 = V2.CrossMagnitude(V1);
139 if (NormD2 / NormD1 < myDeflection) { // collinearite des derivees
140 myDu = Min(myDwmax, 1.5 * myDu);
143 myDu = Sqrt(8.* myDeflection * NormD1 / NormD2 );
144 myDu = Min(Max(myDu, myTolCur), myDwmax);
148 // verifier si la fleche est respectee si WithControl
151 myDu = Min(myDu, myLastParam-myFirstParam);
154 D03d(myCurve, myFirstParam + myDu,P);
155 D03d(myCurve, myFirstParam + (myDu / 2.0),P1);
159 D02d(myCurve, myFirstParam + myDu,P);
160 D02d(myCurve, myFirstParam + (myDu / 2.0),P1);
162 V1= gp_Vec(myPoints[myNbPoints], P);
163 NormD1 = V1.Magnitude();
164 if (NormD1 >= myDeflection) {
165 V2 = gp_Vec(myPoints[myNbPoints], P1);
166 NormD2 = V2.CrossMagnitude(V1) / NormD1;
168 // le depassement de fleche a partir duquel on redivise est arbitraire
169 // il faudra peut etre le reajuster (differencier le premier point des
170 // autres) ce test ne marche pas sur les points d inflexion
172 if (NormD2 > myDeflection / 5.0) {
173 NormD2 = Max(NormD2, 1.1 * myDeflection);
174 myDu = myDu * Sqrt(myDeflection / NormD2);
175 myDu = Min(Max(myDu, myTolCur), myDwmax);
179 myFirstParam = myFirstParam + myDu;
180 myFinish = (myLastParam - myFirstParam < myTolCur) || (myDu == 0.);
183 // le dernier point est corrige si control
184 if (myControl && (myNbPoints == 1) ) {
186 if (myLastParam - Un1 < 0.33*(myLastParam-myFirstParam)) {
187 myFirstParam = (myLastParam + Un1) / 2.0;
188 myParams[0]= myFirstParam;
189 myParams[1]= myLastParam;
191 D03d(myCurve, myParams[0], myPoints[0]);
192 D03d(myCurve, myParams[1], myPoints[1]);
195 D02d(myCurve, myParams[0], myPoints[0]);
196 D02d(myCurve, myParams[1], myPoints[1]);
201 D23d(myCurve, myLastParam, P1, V1, V2);
204 D22d(myCurve, myLastParam, P1, V1, V2);
208 NormD1 = VV.Magnitude();
209 if ( NormD1 < myDeflection) {
210 myParams[1]= myLastParam;
214 myFirstParam = (myLastParam * (myParams[1] - Un1) + Un1 * myDu)
215 /(myFirstParam -Un1);
217 D03d(myCurve, myFirstParam, P2);
219 D02d(myCurve, myFirstParam, P2);
221 if ((VV.CrossMagnitude(gp_Vec(P2, P)) / NormD1 < myDeflection) &&
222 (Un1 >= myLastParam - myDwmax) ) {
223 // on supprime le point n
224 myParams[1]= myLastParam;
228 myParams[1]=myFirstParam;
230 myParams[2]=myLastParam;
232 myNbPoints = myNbPoints +1;
238 myNbPoints = myNbPoints +1 ;
239 if (myNbPoints >= 3) myNbPoints = 2;
240 myParams[myNbPoints]= myLastParam;
242 D03d(myCurve, myLastParam, myPoints[myNbPoints]);
245 D02d(myCurve, myLastParam, myPoints[myNbPoints]);
251 //=======================================================================
252 //function : CPnts_UniformDeflection
254 //=======================================================================
256 CPnts_UniformDeflection::CPnts_UniformDeflection ()
258 myDone = Standard_False;
261 //=======================================================================
262 //function : CPnts_UniformDeflection
264 //=======================================================================
266 CPnts_UniformDeflection::CPnts_UniformDeflection
267 (const Adaptor3d_Curve& C,
268 const Standard_Real Deflection,
269 const Standard_Real Resolution,
270 const Standard_Boolean WithControl)
272 Initialize(C, Deflection, Resolution, WithControl);
275 //=======================================================================
276 //function : CPnts_UniformDeflection
278 //=======================================================================
280 CPnts_UniformDeflection::CPnts_UniformDeflection
281 (const Adaptor2d_Curve2d& C,
282 const Standard_Real Deflection,
283 const Standard_Real Resolution,
284 const Standard_Boolean WithControl)
286 Initialize(C, Deflection, Resolution, WithControl);
289 //=======================================================================
290 //function : Initialize
292 //=======================================================================
294 void CPnts_UniformDeflection::Initialize(const Adaptor3d_Curve& C,
295 const Standard_Real Deflection,
296 const Standard_Real Resolution,
297 const Standard_Boolean WithControl)
299 Initialize(C,Deflection,C.FirstParameter(),C.LastParameter(),
300 Resolution,WithControl);
303 //=======================================================================
304 //function : Initialize
306 //=======================================================================
308 void CPnts_UniformDeflection::Initialize(const Adaptor2d_Curve2d& C,
309 const Standard_Real Deflection,
310 const Standard_Real Resolution,
311 const Standard_Boolean WithControl)
313 Initialize(C,Deflection,C.FirstParameter(),C.LastParameter(),
314 Resolution,WithControl);
317 //=======================================================================
318 //function : CPnts_UniformDeflection
320 //=======================================================================
322 CPnts_UniformDeflection ::CPnts_UniformDeflection
323 (const Adaptor3d_Curve& C,
324 const Standard_Real Deflection,
325 const Standard_Real U1,
326 const Standard_Real U2,
327 const Standard_Real Resolution,
328 const Standard_Boolean WithControl)
330 Initialize(C, Deflection, U1, U2, Resolution, WithControl);
333 //=======================================================================
334 //function : CPnts_UniformDeflection
336 //=======================================================================
338 CPnts_UniformDeflection ::CPnts_UniformDeflection
339 (const Adaptor2d_Curve2d& C,
340 const Standard_Real Deflection,
341 const Standard_Real U1,
342 const Standard_Real U2,
343 const Standard_Real Resolution,
344 const Standard_Boolean WithControl)
346 Initialize(C, Deflection, U1, U2, Resolution, WithControl);
349 //=======================================================================
350 //function : Initialize
352 //=======================================================================
354 void CPnts_UniformDeflection::Initialize (const Adaptor3d_Curve& C,
355 const Standard_Real Deflection,
356 const Standard_Real U1,
357 const Standard_Real U2,
358 const Standard_Real Resolution,
359 const Standard_Boolean WithControl)
369 my3d = Standard_True;
370 myDwmax = myLastParam-myFirstParam;
372 myDone = Standard_True;
373 myCurve = (Standard_Address) &C;
374 myFinish = Standard_False;
375 myTolCur = Resolution;
376 myDeflection = Deflection;
377 myControl = WithControl;
381 //=======================================================================
382 //function : Initialize
384 //=======================================================================
386 void CPnts_UniformDeflection::Initialize (const Adaptor2d_Curve2d& C,
387 const Standard_Real Deflection,
388 const Standard_Real U1,
389 const Standard_Real U2,
390 const Standard_Real Resolution,
391 const Standard_Boolean WithControl)
401 my3d = Standard_False;
402 myDwmax = myLastParam-myFirstParam;
404 myDone = Standard_True;
405 myCurve = (Standard_Address) &C;
406 myFinish = Standard_False;
407 myTolCur = Resolution;
408 myDeflection = Deflection;
409 myControl = WithControl;
413 //=======================================================================
416 //=======================================================================
418 Standard_Boolean CPnts_UniformDeflection::More()
421 return Standard_False;
423 else if (myIPoint == myNbPoints) {
425 return Standard_False;
433 return myIPoint < myNbPoints;