Integration of OCCT 6.5.0 from SVN
[occt.git] / src / CPnts / CPnts_AbscissaPoint.cxx
CommitLineData
7fd59977 1//------------------------------------------------------------------------
2// Calculer un point a abscisse donne a partir
3// d un point donne
4//
5// cas traites :segment de droite,arc de cercle courbe parametree
6// la courbe doit etre C1
7//
8// pour une courbe parametree:
9//
10// on calcule la longueur totale de la courbe
11// on calcule un point approche en assimilant la courbe a une droite
12// on calcule la longueur de la courbe entre le point de depart et
13// le point approche
14// par iteration succsessive on trouve le point et son parametre associe
15// appel a FunctionRoot
16//
17//
18
19#include <CPnts_AbscissaPoint.ixx>
20
21#include <math_GaussSingleIntegration.hxx>
22#include <math_FunctionRoot.hxx>
23#include <StdFail_NotDone.hxx>
24#include <Standard_ConstructionError.hxx>
25
26#include <gp_Vec.hxx>
27#include <gp_Vec2d.hxx>
28#include <Geom_BezierCurve.hxx>
29#include <Geom_BSplineCurve.hxx>
30#include <Geom2d_BezierCurve.hxx>
31#include <Geom2d_BSplineCurve.hxx>
32#include <Precision.hxx>
33
34// auxiliary functions to compute the length of the derivative
35
36static Standard_Real f3d(const Standard_Real X, const Standard_Address C)
37{
38 gp_Vec V = ((Adaptor3d_Curve*)C)->DN(X,1);
39 return V.Magnitude();
40}
41
42static Standard_Real f2d(const Standard_Real X, const Standard_Address C)
43{
44 gp_Vec2d V = ((Adaptor2d_Curve2d*)C)->DN(X,1);
45 return V.Magnitude();
46}
47
48static Standard_Integer order(const Adaptor3d_Curve& C)
49{
50 switch (C.GetType()) {
51
52 case GeomAbs_Line :
53 return 2;
54
55 case GeomAbs_Parabola :
56 return 5;
57
58 case GeomAbs_BezierCurve :
59 return Min(24, 2*C.Bezier()->Degree());
60
61 case GeomAbs_BSplineCurve :
62 return Min(24, 2*C.BSpline()->NbPoles()-1);
63
64 default :
65 return 10;
66 }
67}
68
69static Standard_Integer order(const Adaptor2d_Curve2d& C)
70{
71 switch (C.GetType()) {
72
73 case GeomAbs_Line :
74 return 2;
75
76 case GeomAbs_Parabola :
77 return 5;
78
79 case GeomAbs_BezierCurve :
80 return Min(24, 2*C.Bezier()->Degree());
81
82 case GeomAbs_BSplineCurve :
83 return Min(24, 2*C.BSpline()->NbPoles()-1);
84
85 default :
86 return 10;
87 }
88}
89
90
91//=======================================================================
92//function : Length
93//purpose : 3d
94//=======================================================================
95
96Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C)
97{
98 return CPnts_AbscissaPoint::Length(C, C.FirstParameter(),
99 C.LastParameter());
100}
101
102//=======================================================================
103//function : Length
104//purpose : 2d
105//=======================================================================
106
107Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C)
108{
109 return CPnts_AbscissaPoint::Length(C, C.FirstParameter(),
110 C.LastParameter());
111}
112
113//=======================================================================
114//function : Length
115//purpose : 3d with tolerance
116//=======================================================================
117
118Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C, const Standard_Real Tol)
119{
120 return CPnts_AbscissaPoint::Length(C, C.FirstParameter(),
121 C.LastParameter(), Tol);
122}
123
124//=======================================================================
125//function : Length
126//purpose : 2d with tolerance
127//=======================================================================
128
129Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C, const Standard_Real Tol)
130{
131 return CPnts_AbscissaPoint::Length(C, C.FirstParameter(),
132 C.LastParameter(), Tol);
133}
134
135
136//=======================================================================
137//function : Length
138//purpose : 3d with parameters
139//=======================================================================
140
141Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C,
142 const Standard_Real U1,
143 const Standard_Real U2)
144{
145 CPnts_MyGaussFunction FG;
146//POP pout WNT
147 CPnts_RealFunction rf = f3d;
148 FG.Init(rf,(Standard_Address)&C);
149// FG.Init(f3d,(Standard_Address)&C);
150 math_GaussSingleIntegration TheLength(FG, U1, U2, order(C));
151 if (!TheLength.IsDone()) {
152 Standard_ConstructionError::Raise();
153 }
154 return Abs(TheLength.Value());
155}
156
157//=======================================================================
158//function : Length
159//purpose : 2d with parameters
160//=======================================================================
161
162Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C,
163 const Standard_Real U1,
164 const Standard_Real U2)
165{
166 CPnts_MyGaussFunction FG;
167//POP pout WNT
168 CPnts_RealFunction rf = f2d;
169 FG.Init(rf,(Standard_Address)&C);
170// FG.Init(f2d,(Standard_Address)&C);
171 math_GaussSingleIntegration TheLength(FG, U1, U2, order(C));
172 if (!TheLength.IsDone()) {
173 Standard_ConstructionError::Raise();
174 }
175 return Abs(TheLength.Value());
176}
177
178//=======================================================================
179//function : Length
180//purpose : 3d with parameters and tolerance
181//=======================================================================
182
183Standard_Real CPnts_AbscissaPoint::Length(const Adaptor3d_Curve& C,
184 const Standard_Real U1,
185 const Standard_Real U2,
186 const Standard_Real Tol)
187{
188 CPnts_MyGaussFunction FG;
189//POP pout WNT
190 CPnts_RealFunction rf = f3d;
191 FG.Init(rf,(Standard_Address)&C);
192// FG.Init(f3d,(Standard_Address)&C);
193 math_GaussSingleIntegration TheLength(FG, U1, U2, order(C), Tol);
194 if (!TheLength.IsDone()) {
195 Standard_ConstructionError::Raise();
196 }
197 return Abs(TheLength.Value());
198}
199
200//=======================================================================
201//function : Length
202//purpose : 2d with parameters and tolerance
203//=======================================================================
204
205Standard_Real CPnts_AbscissaPoint::Length(const Adaptor2d_Curve2d& C,
206 const Standard_Real U1,
207 const Standard_Real U2,
208 const Standard_Real Tol)
209{
210 CPnts_MyGaussFunction FG;
211//POP pout WNT
212 CPnts_RealFunction rf = f2d;
213 FG.Init(rf,(Standard_Address)&C);
214// FG.Init(f2d,(Standard_Address)&C);
215 math_GaussSingleIntegration TheLength(FG, U1, U2, order(C), Tol);
216 if (!TheLength.IsDone()) {
217 Standard_ConstructionError::Raise();
218 }
219 return Abs(TheLength.Value());
220}
221
222//=======================================================================
223//function : CPnts_AbscissaPoint
224//purpose :
225//=======================================================================
226
227CPnts_AbscissaPoint::CPnts_AbscissaPoint() : myDone(Standard_False)
228{
229}
230
231//=======================================================================
232//function : CPnts_AbscissaPoint
233//purpose :
234//=======================================================================
235
236CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor3d_Curve& C,
237 const Standard_Real Abscissa,
238 const Standard_Real U0,
239 const Standard_Real Resolution)
240{
241// Init(C);
242 Init(C, Resolution); //rbv's modification
243//
244 Perform(Abscissa, U0, Resolution);
245}
246
247//=======================================================================
248//function : CPnts_AbscissaPoint
249//purpose :
250//=======================================================================
251
252CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor2d_Curve2d& C,
253 const Standard_Real Abscissa,
254 const Standard_Real U0,
255 const Standard_Real Resolution)
256{
257 Init(C);
258 Perform(Abscissa, U0, Resolution);
259}
260
261
262//=======================================================================
263//function : CPnts_AbscissaPoint
264//purpose :
265//=======================================================================
266
267CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor3d_Curve& C,
268 const Standard_Real Abscissa,
269 const Standard_Real U0,
270 const Standard_Real Ui,
271 const Standard_Real Resolution)
272{
273 Init(C);
274 Perform(Abscissa, U0, Ui, Resolution);
275}
276
277//=======================================================================
278//function : CPnts_AbscissaPoint
279//purpose :
280//=======================================================================
281
282CPnts_AbscissaPoint::CPnts_AbscissaPoint(const Adaptor2d_Curve2d& C,
283 const Standard_Real Abscissa,
284 const Standard_Real U0,
285 const Standard_Real Ui,
286 const Standard_Real Resolution)
287{
288 Init(C);
289 Perform(Abscissa, U0, Ui, Resolution);
290}
291
292
293//=======================================================================
294//function : Init
295//purpose :
296//=======================================================================
297
298void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C)
299{
300 Init(C,C.FirstParameter(),C.LastParameter());
301}
302
303//=======================================================================
304//function : Init
305//purpose :
306//=======================================================================
307
308void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C)
309{
310 Init(C,C.FirstParameter(),C.LastParameter());
311}
312
313//=======================================================================
314//function : Init
315//purpose : introduced by rbv for curvilinear parametrization
316//=======================================================================
317
318void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C, const Standard_Real Tol)
319{
320 Init(C,C.FirstParameter(),C.LastParameter(), Tol);
321}
322
323//=======================================================================
324//function : Init
325//purpose :
326//=======================================================================
327
328void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C, const Standard_Real Tol)
329{
330 Init(C,C.FirstParameter(),C.LastParameter(), Tol);
331}
332
333//=======================================================================
334//function : Init
335//purpose :
336//=======================================================================
337
338void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C,
339 const Standard_Real U1,
340 const Standard_Real U2)
341{
342//POP pout WNT
343 CPnts_RealFunction rf = f3d;
344 myF.Init(rf,(Standard_Address)&C,order(C));
345// myF.Init(f3d,(Standard_Address)&C,order(C));
346 myL = CPnts_AbscissaPoint::Length(C, U1, U2);
347 myUMin = Min(U1, U2);
348 myUMax = Max(U1, U2);
349 Standard_Real DU = myUMax - myUMin;
350 myUMin = myUMin - DU;
351 myUMax = myUMax + DU;
352}
353
354//=======================================================================
355//function : Init
356//purpose :
357//=======================================================================
358
359void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C,
360 const Standard_Real U1,
361 const Standard_Real U2)
362{
363//POP pout WNT
364 CPnts_RealFunction rf = f2d;
365 myF.Init(rf,(Standard_Address)&C,order(C));
366// myF.Init(f2d,(Standard_Address)&C,order(C));
367 myL = CPnts_AbscissaPoint::Length(C, U1, U2);
368 myUMin = Min(U1, U2);
369 myUMax = Max(U1, U2);
370 Standard_Real DU = myUMax - myUMin;
371 myUMin = myUMin - DU;
372 myUMax = myUMax + DU;
373}
374
375
376//=======================================================================
377//function : Init
378//purpose : introduced by rbv for curvilinear parametrization
379//=======================================================================
380
381void CPnts_AbscissaPoint::Init(const Adaptor3d_Curve& C,
382 const Standard_Real U1,
383 const Standard_Real U2,
384 const Standard_Real Tol)
385{
386//POP pout WNT
387 CPnts_RealFunction rf = f3d;
388 myF.Init(rf,(Standard_Address)&C,order(C));
389// myF.Init(f3d,(Standard_Address)&C,order(C));
390 myL = CPnts_AbscissaPoint::Length(C, U1, U2, Tol);
391 myUMin = Min(U1, U2);
392 myUMax = Max(U1, U2);
393 Standard_Real DU = myUMax - myUMin;
394 myUMin = myUMin - DU;
395 myUMax = myUMax + DU;
396}
397
398//=======================================================================
399//function : Init
400//purpose :
401//=======================================================================
402
403void CPnts_AbscissaPoint::Init(const Adaptor2d_Curve2d& C,
404 const Standard_Real U1,
405 const Standard_Real U2,
406 const Standard_Real Tol)
407{
408//POP pout WNT
409 CPnts_RealFunction rf = f2d;
410 myF.Init(rf,(Standard_Address)&C,order(C));
411// myF.Init(f2d,(Standard_Address)&C,order(C));
412 myL = CPnts_AbscissaPoint::Length(C, U1, U2, Tol);
413 myUMin = Min(U1, U2);
414 myUMax = Max(U1, U2);
415 Standard_Real DU = myUMax - myUMin;
416 myUMin = myUMin - DU;
417 myUMax = myUMax + DU;
418}
419
420//=======================================================================
421//function : Perform
422//purpose :
423//=======================================================================
424
425void CPnts_AbscissaPoint::Perform(const Standard_Real Abscissa,
426 const Standard_Real U0,
427 const Standard_Real Resolution)
428{
429 if (myL < Precision::Confusion()) {
430 //
431 // on sort moins violemment : j'espere que l'on espere pas
432 // un increment notable au niveau de myParam
433 //
434 myDone = Standard_True ;
435 myParam = U0 ;
436
437 }
438 else {
439 Standard_Real Ui = U0 + (Abscissa / myL) * (myUMax - myUMin) / 3.;
440 // exercice : why 3 ?
441 Perform(Abscissa,U0,Ui,Resolution);
442 }
443}
444
445//=======================================================================
446//function : Perform
447//purpose :
448//=======================================================================
449
450void CPnts_AbscissaPoint::Perform(const Standard_Real Abscissa,
451 const Standard_Real U0,
452 const Standard_Real Ui,
453 const Standard_Real Resolution)
454{
455 if (myL < Precision::Confusion()) {
456 //
457 // on sort moins violemment :
458 //
459 myDone = Standard_True ;
460 myParam = U0 ;
461 }
462 else {
463 myDone = Standard_False;
464 myF.Init(U0, Abscissa);
465
466 math_FunctionRoot Solution(myF, Ui, Resolution, myUMin, myUMax);
467
468// Temporairement on vire le test de validite de la solution
469// Il faudra des que l on pourra faire du cdl, rendre un tolreached
470// lbo 21/03/97
471// if (Solution.IsDone()) {
472// Standard_Real D;
473// myF.Derivative(Solution.Root(),D);
474// if (Abs(Solution.Value()) < Resolution * D) {
475// myDone = Standard_True;
476// myParam = Solution.Root();
477// }
478// }
479 if (Solution.IsDone()) {
480 myDone = Standard_True;
481 myParam = Solution.Root();
482 }
483 }
484}
485
486//=======================================================================
487//function : AdvPerform
488//purpose :
489//=======================================================================
490
491void CPnts_AbscissaPoint::AdvPerform(const Standard_Real Abscissa,
492 const Standard_Real U0,
493 const Standard_Real Ui,
494 const Standard_Real Resolution)
495{
496 if (myL < Precision::Confusion()) {
497 //
498 // on sort moins violemment :
499 //
500 myDone = Standard_True ;
501 myParam = U0 ;
502 }
503 else {
504 myDone = Standard_False;
505// myF.Init(U0, Abscissa);
506 myF.Init(U0, Abscissa, Resolution/10); // rbv's modification
507
508 math_FunctionRoot Solution(myF, Ui, Resolution, myUMin, myUMax);
509
510// Temporairement on vire le test de validite de la solution
511// Il faudra des que l on pourra faire du cdl, rendre un tolreached
512// lbo 21/03/97
513// if (Solution.IsDone()) {
514// Standard_Real D;
515// myF.Derivative(Solution.Root(),D);
516// if (Abs(Solution.Value()) < Resolution * D) {
517// myDone = Standard_True;
518// myParam = Solution.Root();
519// }
520// }
521 if (Solution.IsDone()) {
522 myDone = Standard_True;
523 myParam = Solution.Root();
524 }
525 }
526}