1 //-------------------------------------------------------------------
2 // Algorithm concerns the constant arrow
4 // cases processed : parameterized curve
5 // the curve should be C2
8 // algorithm of parameterized curve:
10 // calculation of the step of advancement is
11 // du = sqrt(8*fleche*||P'(u)||/||P'(u)^P''(u)||
13 // calculate each point such as u+Du
15 // check if the arrow is actually taken into account, if yes, continue
16 // otherwise correct the step
18 // si du cannot be calculated (null curvature, singularity on the curve)
19 // take a constant step to reach the last point or to go past it
20 // The last point is readjusted by the following criteria:
22 // if the last calculated parameter is <2*resolution, reframe the last point found
23 // between itself and the previous point and add the end point
24 // (avoid a concentration at the end)
26 // otherwise if the distance (last calculated point, end point)<arrow,
27 // replace the last calculated point by the end point
29 // otherwise calculate max arrow between the last but one calculated point
30 // and the end point; if this arrow is greater than the arrow
31 // replace the last point by this one and the end point
34 // CONTROLS OF ARROW AND THE LAST POINT ARE DONE ONLY IF withControl=true
36 // each iteration calculates at maximum 3 points
39 //-------------------------------------------------------------------------
41 #include <CPnts_UniformDeflection.ixx>
43 #include <StdFail_NotDone.hxx>
44 #include <Standard_DomainError.hxx>
45 #include <Standard_OutOfRange.hxx>
46 #include <Standard_ConstructionError.hxx>
50 #include <gp_Pnt2d.hxx>
51 #include <gp_Vec2d.hxx>
53 static inline void D03d(const Standard_Address C, const Standard_Real U,
56 ((Adaptor3d_Curve*)C)->D0(U,P);
59 static void D02d(const Standard_Address C, const Standard_Real U,
63 ((Adaptor2d_Curve2d*)C)->D0(U,P);
64 PP.SetCoord(P.X(),P.Y(),0.);
67 static inline void D13d(const Standard_Address C, const Standard_Real U,
68 gp_Pnt& P, gp_Vec& V1)
70 ((Adaptor3d_Curve*)C)->D1(U,P,V1);
75 static void D12d(const Standard_Address C, const Standard_Real U,
76 gp_Pnt& PP, gp_Vec& VV1)
80 ((Adaptor2d_Curve2d*)C)->D1(U,P,V1);
81 PP.SetCoord(P.X(),P.Y(),0.);
82 VV1.SetCoord(V1.X(),V1.Y(),0.);
86 static inline void D23d(const Standard_Address C, const Standard_Real U,
87 gp_Pnt& P, gp_Vec& V1, gp_Vec& V2)
89 ((Adaptor3d_Curve*)C)->D2(U,P,V1,V2);
92 static void D22d(const Standard_Address C, const Standard_Real U,
93 gp_Pnt& PP, gp_Vec& VV1, gp_Vec& VV2)
97 ((Adaptor2d_Curve2d*)C)->D2(U,P,V1,V2);
98 PP.SetCoord(P.X(),P.Y(),0.);
99 VV1.SetCoord(V1.X(),V1.Y(),0.);
100 VV2.SetCoord(V2.X(),V2.Y(),0.);
103 //=======================================================================
106 //=======================================================================
108 void CPnts_UniformDeflection::Perform()
111 // gp_Vec V1, V2, VV1, VV2, VV;
114 Standard_Real NormD1, NormD2;
119 while ( (myNbPoints<2) && (!myFinish) ) {
121 myNbPoints = myNbPoints + 1;
122 myParams[myNbPoints] = myFirstParam;
125 D23d(myCurve, myFirstParam, myPoints[myNbPoints], V1, V2);
127 D22d(myCurve, myFirstParam, myPoints[myNbPoints], V1, V2);
128 P = myPoints[myNbPoints] ;
129 NormD1 = V1.Magnitude();
130 if (NormD1 < myTolCur || V2.Magnitude() < myTolCur) {
131 // singularity on the tangent or null curvature
132 myDu = Min(myDwmax, 1.5 * myDu);
135 NormD2 = V2.CrossMagnitude(V1);
136 if (NormD2 / NormD1 < myDeflection) { // collinearity of derivatives
137 myDu = Min(myDwmax, 1.5 * myDu);
140 myDu = Sqrt(8.* myDeflection * NormD1 / NormD2 );
141 myDu = Min(Max(myDu, myTolCur), myDwmax);
145 // check if the arrow is observed if WithControl
148 myDu = Min(myDu, myLastParam-myFirstParam);
151 D03d(myCurve, myFirstParam + myDu,P);
152 D03d(myCurve, myFirstParam + (myDu / 2.0),P1);
156 D02d(myCurve, myFirstParam + myDu,P);
157 D02d(myCurve, myFirstParam + (myDu / 2.0),P1);
159 V1= gp_Vec(myPoints[myNbPoints], P);
160 NormD1 = V1.Magnitude();
161 if (NormD1 >= myDeflection) {
162 V2 = gp_Vec(myPoints[myNbPoints], P1);
163 NormD2 = V2.CrossMagnitude(V1) / NormD1;
165 // passing of arrow starting from which the redivision is done is arbitrary
166 // probably it will be necessary to readjust it (differenciate the first point
167 // from the others) this test does not work on the points of inflexion
169 if (NormD2 > myDeflection / 5.0) {
170 NormD2 = Max(NormD2, 1.1 * myDeflection);
171 myDu = myDu * Sqrt(myDeflection / NormD2);
172 myDu = Min(Max(myDu, myTolCur), myDwmax);
176 myFirstParam = myFirstParam + myDu;
177 myFinish = (myLastParam - myFirstParam < myTolCur) || (myDu == 0.);
180 // the last point is corrected if control
181 if (myControl && (myNbPoints == 1) ) {
183 if (myLastParam - Un1 < 0.33*(myLastParam-myFirstParam)) {
184 myFirstParam = (myLastParam + Un1) / 2.0;
185 myParams[0]= myFirstParam;
186 myParams[1]= myLastParam;
188 D03d(myCurve, myParams[0], myPoints[0]);
189 D03d(myCurve, myParams[1], myPoints[1]);
192 D02d(myCurve, myParams[0], myPoints[0]);
193 D02d(myCurve, myParams[1], myPoints[1]);
198 D23d(myCurve, myLastParam, P1, V1, V2);
201 D22d(myCurve, myLastParam, P1, V1, V2);
205 NormD1 = VV.Magnitude();
206 if ( NormD1 < myDeflection) {
207 myParams[1]= myLastParam;
211 myFirstParam = (myLastParam * (myParams[1] - Un1) + Un1 * myDu)
212 /(myFirstParam -Un1);
214 D03d(myCurve, myFirstParam, P2);
216 D02d(myCurve, myFirstParam, P2);
218 if ((VV.CrossMagnitude(gp_Vec(P2, P)) / NormD1 < myDeflection) &&
219 (Un1 >= myLastParam - myDwmax) ) {
220 // point n is removed
221 myParams[1]= myLastParam;
225 myParams[1]=myFirstParam;
227 myParams[2]=myLastParam;
229 myNbPoints = myNbPoints +1;
235 myNbPoints = myNbPoints +1 ;
236 if (myNbPoints >= 3) myNbPoints = 2;
237 myParams[myNbPoints]= myLastParam;
239 D03d(myCurve, myLastParam, myPoints[myNbPoints]);
242 D02d(myCurve, myLastParam, myPoints[myNbPoints]);
248 //=======================================================================
249 //function : CPnts_UniformDeflection
251 //=======================================================================
253 CPnts_UniformDeflection::CPnts_UniformDeflection ()
255 myDone = Standard_False;
258 //=======================================================================
259 //function : CPnts_UniformDeflection
261 //=======================================================================
263 CPnts_UniformDeflection::CPnts_UniformDeflection
264 (const Adaptor3d_Curve& C,
265 const Standard_Real Deflection,
266 const Standard_Real Resolution,
267 const Standard_Boolean WithControl)
269 Initialize(C, Deflection, Resolution, WithControl);
272 //=======================================================================
273 //function : CPnts_UniformDeflection
275 //=======================================================================
277 CPnts_UniformDeflection::CPnts_UniformDeflection
278 (const Adaptor2d_Curve2d& C,
279 const Standard_Real Deflection,
280 const Standard_Real Resolution,
281 const Standard_Boolean WithControl)
283 Initialize(C, Deflection, Resolution, WithControl);
286 //=======================================================================
287 //function : Initialize
289 //=======================================================================
291 void CPnts_UniformDeflection::Initialize(const Adaptor3d_Curve& C,
292 const Standard_Real Deflection,
293 const Standard_Real Resolution,
294 const Standard_Boolean WithControl)
296 Initialize(C,Deflection,C.FirstParameter(),C.LastParameter(),
297 Resolution,WithControl);
300 //=======================================================================
301 //function : Initialize
303 //=======================================================================
305 void CPnts_UniformDeflection::Initialize(const Adaptor2d_Curve2d& C,
306 const Standard_Real Deflection,
307 const Standard_Real Resolution,
308 const Standard_Boolean WithControl)
310 Initialize(C,Deflection,C.FirstParameter(),C.LastParameter(),
311 Resolution,WithControl);
314 //=======================================================================
315 //function : CPnts_UniformDeflection
317 //=======================================================================
319 CPnts_UniformDeflection ::CPnts_UniformDeflection
320 (const Adaptor3d_Curve& C,
321 const Standard_Real Deflection,
322 const Standard_Real U1,
323 const Standard_Real U2,
324 const Standard_Real Resolution,
325 const Standard_Boolean WithControl)
327 Initialize(C, Deflection, U1, U2, Resolution, WithControl);
330 //=======================================================================
331 //function : CPnts_UniformDeflection
333 //=======================================================================
335 CPnts_UniformDeflection ::CPnts_UniformDeflection
336 (const Adaptor2d_Curve2d& C,
337 const Standard_Real Deflection,
338 const Standard_Real U1,
339 const Standard_Real U2,
340 const Standard_Real Resolution,
341 const Standard_Boolean WithControl)
343 Initialize(C, Deflection, U1, U2, Resolution, WithControl);
346 //=======================================================================
347 //function : Initialize
349 //=======================================================================
351 void CPnts_UniformDeflection::Initialize (const Adaptor3d_Curve& C,
352 const Standard_Real Deflection,
353 const Standard_Real U1,
354 const Standard_Real U2,
355 const Standard_Real Resolution,
356 const Standard_Boolean WithControl)
366 my3d = Standard_True;
367 myDwmax = myLastParam-myFirstParam;
369 myDone = Standard_True;
370 myCurve = (Standard_Address) &C;
371 myFinish = Standard_False;
372 myTolCur = Resolution;
373 myDeflection = Deflection;
374 myControl = WithControl;
378 //=======================================================================
379 //function : Initialize
381 //=======================================================================
383 void CPnts_UniformDeflection::Initialize (const Adaptor2d_Curve2d& C,
384 const Standard_Real Deflection,
385 const Standard_Real U1,
386 const Standard_Real U2,
387 const Standard_Real Resolution,
388 const Standard_Boolean WithControl)
398 my3d = Standard_False;
399 myDwmax = myLastParam-myFirstParam;
401 myDone = Standard_True;
402 myCurve = (Standard_Address) &C;
403 myFinish = Standard_False;
404 myTolCur = Resolution;
405 myDeflection = Deflection;
406 myControl = WithControl;
410 //=======================================================================
413 //=======================================================================
415 Standard_Boolean CPnts_UniformDeflection::More()
418 return Standard_False;
420 else if (myIPoint == myNbPoints) {
422 return Standard_False;
430 return myIPoint < myNbPoints;