1 // Created on: 1991-06-25
3 // Copyright (c) 1991-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 // 24-Aug-95 : xab removed C1 and C2 test : appeller D1 et D2
23 // avec discernement !
24 // 19-09-97 : JPI correction derivee seconde
27 #include <Geom_OffsetCurve.ixx>
32 #include <Geom_Line.hxx>
33 #include <Geom_Circle.hxx>
34 #include <Geom_Ellipse.hxx>
35 #include <Geom_Hyperbola.hxx>
36 #include <Geom_Parabola.hxx>
37 #include <Geom_BezierCurve.hxx>
38 #include <Geom_TrimmedCurve.hxx>
39 #include <Geom_BSplineCurve.hxx>
40 #include <Geom_Geometry.hxx>
42 #include <Geom_UndefinedDerivative.hxx>
43 #include <Geom_UndefinedValue.hxx>
44 #include <Standard_ConstructionError.hxx>
45 #include <Standard_RangeError.hxx>
46 #include <Standard_NotImplemented.hxx>
48 typedef Geom_OffsetCurve OffsetCurve;
49 typedef Handle(Geom_OffsetCurve) Handle(OffsetCurve);
50 typedef Geom_Curve Curve;
51 typedef Handle(Geom_Curve) Handle(Curve);
52 typedef Handle(Geom_Geometry) Handle(Geometry);
64 static const int MaxDegree = 9;
65 //ordre de derivation maximum pour la recherche de la premiere
70 //=======================================================================
73 //=======================================================================
75 Handle(Geom_Geometry) Geom_OffsetCurve::Copy () const {
77 Handle(OffsetCurve) C;
78 C = new OffsetCurve (basisCurve, offsetValue, direction);
84 //=======================================================================
85 //function : Geom_OffsetCurve
87 //=======================================================================
89 Geom_OffsetCurve::Geom_OffsetCurve (const Handle(Curve)& C,
90 const Standard_Real Offset,
92 : direction(V), offsetValue(Offset) {
94 if (C->DynamicType() == STANDARD_TYPE(Geom_OffsetCurve)) {
95 Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C);
96 if ((OC->BasisCurve())->Continuity() == GeomAbs_C0)
97 Standard_ConstructionError::Raise();
99 basisCurve = Handle(Curve)::DownCast((OC->BasisCurve())->Copy());
100 Standard_Real PrevOff = OC->Offset();
101 gp_Vec V1(OC->Direction());
102 gp_Vec V2(direction);
103 gp_Vec Vdir(PrevOff*V1 + offsetValue*V2);
106 offsetValue = Vdir.Magnitude();
107 direction.SetXYZ(Vdir.XYZ());
109 offsetValue = -Vdir.Magnitude();
110 direction.SetXYZ((-Vdir).XYZ());
113 if (C->Continuity() == GeomAbs_C0) Standard_ConstructionError::Raise();
114 basisCurve = Handle(Curve)::DownCast(C->Copy()); // DownCast: 10-03-93
119 //=======================================================================
122 //=======================================================================
124 void Geom_OffsetCurve::Reverse ()
126 basisCurve->Reverse();
127 offsetValue = -offsetValue;
131 //=======================================================================
132 //function : ReversedParameter
134 //=======================================================================
136 Standard_Real Geom_OffsetCurve::ReversedParameter( const Standard_Real U) const
138 return basisCurve->ReversedParameter( U);
141 //=======================================================================
142 //function : Direction
144 //=======================================================================
146 const gp_Dir& Geom_OffsetCurve::Direction () const
147 { return direction; }
149 //=======================================================================
150 //function : SetDirection
152 //=======================================================================
154 void Geom_OffsetCurve::SetDirection (const Dir& V)
157 //=======================================================================
158 //function : SetOffsetValue
160 //=======================================================================
162 void Geom_OffsetCurve::SetOffsetValue (const Standard_Real D)
166 //=======================================================================
167 //function : IsPeriodic
169 //=======================================================================
171 Standard_Boolean Geom_OffsetCurve::IsPeriodic () const
173 return basisCurve->IsPeriodic();
176 //=======================================================================
179 //=======================================================================
181 Standard_Real Geom_OffsetCurve::Period () const
183 return basisCurve->Period();
186 //=======================================================================
187 //function : SetBasisCurve
189 //=======================================================================
191 void Geom_OffsetCurve::SetBasisCurve (const Handle(Curve)& C) {
193 if (C->Continuity() == GeomAbs_C0) Standard_ConstructionError::Raise();
194 basisCurve = Handle(Curve)::DownCast(C->Copy()); // DownCast: 10-03-93
199 //=======================================================================
200 //function : BasisCurve
202 //=======================================================================
204 Handle(Curve) Geom_OffsetCurve::BasisCurve () const
210 //=======================================================================
211 //function : Continuity
213 //=======================================================================
215 GeomAbs_Shape Geom_OffsetCurve::Continuity () const {
217 GeomAbs_Shape OffsetShape=GeomAbs_C0;
218 switch (basisCurve->Continuity()) {
219 case GeomAbs_C0 : OffsetShape = GeomAbs_C0; break;
220 case GeomAbs_C1 : OffsetShape = GeomAbs_C0; break;
221 case GeomAbs_C2 : OffsetShape = GeomAbs_C1; break;
222 case GeomAbs_C3 : OffsetShape = GeomAbs_C2; break;
223 case GeomAbs_CN : OffsetShape = GeomAbs_CN; break;
224 case GeomAbs_G1 : OffsetShape = GeomAbs_G1; break;
225 case GeomAbs_G2 : OffsetShape = GeomAbs_G2; break;
231 //=======================================================================
234 //=======================================================================
236 void Geom_OffsetCurve::D0 (const Standard_Real U, Pnt& P) const
240 D0(U,P,PBasis,VBasis);
244 //=======================================================================
247 //=======================================================================
249 void Geom_OffsetCurve::D1 (const Standard_Real U, Pnt& P, Vec& V1) const
252 gp_Vec V1Basis,V2Basis;
253 D1(U,P,PBasis,V1,V1Basis,V2Basis);
258 //=======================================================================
261 //=======================================================================
263 void Geom_OffsetCurve::D2 (const Standard_Real U, Pnt& P, Vec& V1, Vec& V2) const
266 gp_Vec V1Basis,V2Basis,V3Basis;
267 D2(U,P,PBasis,V1,V2,V1Basis,V2Basis,V3Basis);
271 //=======================================================================
274 //=======================================================================
276 void Geom_OffsetCurve::D3 (const Standard_Real U, Pnt& P, Vec& V1, Vec& V2, Vec& V3)
280 // P(u) = p(u) + Offset * Ndir / R
281 // with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
283 // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
285 // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
286 // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
288 //P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2) * D2Ndir -
289 // (3.0 * D2r / R2) * DNdir + (3.0 * Dr * Dr / R4) * DNdir -
290 // (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
291 // (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
295 basisCurve->D3 (U, P, V1, V2, V3);
296 Vec V4 = basisCurve->DN (U, 4);
297 Standard_Integer Index = 2;
298 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
299 V1 = basisCurve->DN (U, Index);
303 V2 = basisCurve->DN (U, Index);
304 V3 = basisCurve->DN (U, Index + 1);
305 V4 = basisCurve->DN (U, Index + 2);
307 XYZ OffsetDir = direction.XYZ();
308 XYZ Ndir = (V1.XYZ()).Crossed (OffsetDir);
309 XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
310 XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir);
311 XYZ D3Ndir = (V4.XYZ()).Crossed (OffsetDir);
312 Standard_Real R2 = Ndir.SquareModulus();
313 Standard_Real R = Sqrt (R2);
314 Standard_Real R3 = R2 * R;
315 Standard_Real R4 = R2 * R2;
316 Standard_Real R5 = R3 * R2;
317 Standard_Real R6 = R3 * R3;
318 Standard_Real R7 = R5 * R2;
319 Standard_Real Dr = Ndir.Dot (DNdir);
320 Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
321 Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir);
322 if (R7 <= gp::Resolution()) {
323 if (R6 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
325 D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R2));
326 D3Ndir.Subtract (DNdir.Multiplied (3.0 * ((D2r/R2) + (Dr*Dr/R4))));
327 D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 -
328 15.0*Dr*Dr*Dr/R6 - D3r));
329 D3Ndir.Multiply (offsetValue/R);
330 V3.Add (Vec(D3Ndir));
332 Standard_Real R4 = R2 * R2;
333 D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
334 D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R4) - (D2r / R2)));
335 D2Ndir.Multiply (offsetValue / R);
336 V2.Add (Vec(D2Ndir));
339 DNdir.Subtract (Ndir.Multiplied (Dr/R));
340 DNdir.Multiply (offsetValue/R2);
346 D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * Dr / R3));
347 D3Ndir.Subtract (DNdir.Multiplied ((3.0 * ((D2r/R3) + (Dr*Dr)/R5))));
348 D3Ndir.Add (Ndir.Multiplied (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 -
349 15.0*Dr*Dr*Dr/R7 - D3r));
350 D3Ndir.Multiply (offsetValue);
351 V3.Add (Vec(D3Ndir));
354 D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R3));
355 D2Ndir.Subtract (Ndir.Multiplied ((3.0 * Dr * Dr / R5) - (D2r / R3)));
356 D2Ndir.Multiply (offsetValue);
357 V2.Add (Vec(D2Ndir));
359 DNdir.Multiply (offsetValue/R);
360 DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
364 Ndir.Multiply (offsetValue/R);
370 //=======================================================================
373 //=======================================================================
375 Vec Geom_OffsetCurve::DN (const Standard_Real U, const Standard_Integer N) const {
378 if (N < 1) Standard_RangeError::Raise();
379 XYZ OffsetDir = direction.XYZ();
383 basisCurve->D2 (U, P, V1, V2);
384 Standard_Integer Index = 2;
385 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
386 V1 = basisCurve->DN (U, Index);
389 if (Index != 2) V2 = basisCurve->DN (U, Index);
390 XYZ Ndir = (V1.XYZ()).Crossed (OffsetDir);
391 XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
392 Standard_Real R2 = Ndir.SquareModulus();
393 Standard_Real R = Sqrt (R2);
394 Standard_Real R3 = R * R2;
395 Standard_Real Dr = Ndir.Dot (DNdir);
396 if (R3 <= gp::Resolution()) {
397 if (R2 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
398 Ndir.Multiply (Dr/R);
400 DNdir.Subtract (Ndir);
401 DNdir.Multiply (offsetValue/R2);
405 Ndir.Multiply (offsetValue * Dr / R3);
406 DNdir.Multiply (offsetValue/R);
407 DNdir.Subtract (Ndir);
414 basisCurve->D3 (U, P, V1, V2, V3);
415 Standard_Integer Index = 2;
416 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
417 V1 = basisCurve->DN (U, Index);
421 V2 = basisCurve->DN (U, Index);
422 V3 = basisCurve->DN (U, Index + 1);
424 XYZ Ndir = (V1.XYZ()).Crossed (OffsetDir);
425 XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
426 XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir);
427 Standard_Real R2 = Ndir.SquareModulus();
428 Standard_Real R = Sqrt (R2);
429 Standard_Real R3 = R2 * R; Standard_Real R4 = R2 * R2; Standard_Real R5 = R3 * R2;
430 Standard_Real Dr = Ndir.Dot (DNdir);
431 Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
432 if (R5 <= gp::Resolution()) {
433 if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
434 Ndir.Multiply ((3.0 * Dr * Dr / R4) - (D2r/R2));
435 DNdir.Multiply (2.0 * Dr / R2);
436 D2Ndir.Subtract (DNdir);
437 D2Ndir.Subtract (Ndir);
438 D2Ndir.Multiply (offsetValue / R);
439 V2.Add (Vec(D2Ndir));
442 Ndir.Multiply ((3.0 * Dr * Dr / R4) - (D2r / R2));
443 DNdir.Multiply (2.0 * Dr / R2);
445 D2Ndir.Subtract (DNdir);
446 D2Ndir.Subtract (Ndir);
447 D2Ndir.Multiply (offsetValue);
448 V2.Add (Vec(D2Ndir));
454 basisCurve->D3 (U, P, V1, V2, V3);
455 Vec V4 = basisCurve->DN (U, 4);
456 Standard_Integer Index = 2;
457 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
458 V1 = basisCurve->DN (U, Index);
462 V2 = basisCurve->DN (U, Index);
463 V3 = basisCurve->DN (U, Index + 1);
464 V4 = basisCurve->DN (U, Index + 2);
466 XYZ Ndir = (V1.XYZ()).Crossed (OffsetDir);
467 XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
468 XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir);
469 XYZ D3Ndir = (V4.XYZ()).Crossed (OffsetDir);
470 Standard_Real R2 = Ndir.SquareModulus();
471 Standard_Real R = Sqrt (R2); Standard_Real R3 = R2 * R; Standard_Real R4 = R2 * R2;
472 Standard_Real R5 = R3 * R2; Standard_Real R6 = R3 * R3; Standard_Real R7 = R5 * R2;
473 Standard_Real Dr = Ndir.Dot (DNdir);
474 Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
475 Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir);
476 if (R7 <= gp::Resolution()) {
477 if (R6 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
478 D2Ndir.Multiply (3.0 * Dr / R2);
479 DNdir.Multiply (3.0 * ((D2r/R2) + (Dr*Dr)/R4));
480 Ndir.Multiply (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 - 15.0*Dr*Dr*Dr/R6 - D3r);
481 D3Ndir.Subtract (D2Ndir);
482 D3Ndir.Subtract (DNdir);
484 D3Ndir.Multiply (offsetValue/R);
485 V3.Add (Vec(D3Ndir));
488 D2Ndir.Multiply (3.0 * Dr / R3);
489 DNdir.Multiplied (3.0 * ((D2r/R3) + (Dr*Dr/R5)));
490 Ndir.Multiply (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 - 15.0*Dr*Dr*Dr/R7 - D3r);
492 D3Ndir.Subtract (D2Ndir);
493 D3Ndir.Subtract (DNdir);
495 D3Ndir.Multiply (offsetValue);
496 V3.Add (Vec(D3Ndir));
500 else { Standard_NotImplemented::Raise(); }
505 //=======================================================================
508 //=======================================================================
510 void Geom_OffsetCurve::D0(const Standard_Real U,
513 gp_Vec& V1basis)const
516 basisCurve->D1 (U, Pbasis, V1basis);
517 Standard_Integer Index = 2;
518 while (V1basis.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
519 V1basis = basisCurve->DN (U, Index);
522 XYZ Ndir = (V1basis.XYZ()).Crossed (direction.XYZ());
523 Standard_Real R = Ndir.Modulus();
524 if (R <= gp::Resolution()) Geom_UndefinedValue::Raise();
525 Ndir.Multiply (offsetValue/R);
526 Ndir.Add (Pbasis.XYZ());
530 //=======================================================================
533 //=======================================================================
535 void Geom_OffsetCurve::D1 ( const Standard_Real U,
536 Pnt& P , Pnt& PBasis ,
537 Vec& V1, Vec& V1basis, Vec& V2basis) const {
539 // P(u) = p(u) + Offset * Ndir / R
540 // with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
542 // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
544 basisCurve->D2 (U, PBasis, V1basis, V2basis);
547 Standard_Integer Index = 2;
548 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
549 V1 = basisCurve->DN (U, Index);
552 if (Index != 2) V2 = basisCurve->DN (U, Index);
553 XYZ OffsetDir = direction.XYZ();
554 XYZ Ndir = (V1.XYZ()).Crossed (OffsetDir);
555 XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
556 Standard_Real R2 = Ndir.SquareModulus();
557 Standard_Real R = Sqrt (R2);
558 Standard_Real R3 = R * R2;
559 Standard_Real Dr = Ndir.Dot (DNdir);
560 if (R3 <= gp::Resolution()) {
561 //We try another computation but the stability is not very good.
562 if (R2 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
564 DNdir.Subtract (Ndir.Multiplied (Dr/R));
565 DNdir.Multiply (offsetValue/R2);
569 // Same computation as IICURV in EUCLID-IS because the stability is
571 DNdir.Multiply (offsetValue/R);
572 DNdir.Subtract (Ndir.Multiplied (offsetValue * Dr/R3));
575 Ndir.Multiply (offsetValue/R);
576 Ndir.Add (PBasis.XYZ());
581 //=======================================================================
584 //=======================================================================
586 void Geom_OffsetCurve::D2 (const Standard_Real U,
587 Pnt& P , Pnt& PBasis ,
589 Vec& V1basis, Vec& V2basis, Vec& V3basis) const {
591 // P(u) = p(u) + Offset * Ndir / R
592 // with R = || p' ^ V|| and Ndir = P' ^ direction (local normal direction)
594 // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
596 // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
597 // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
599 basisCurve->D3 (U, PBasis, V1basis, V2basis, V3basis);
600 Standard_Integer Index = 2;
604 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
605 V1 = basisCurve->DN (U, Index);
609 V2 = basisCurve->DN (U, Index);
610 V3 = basisCurve->DN (U, Index + 1);
612 XYZ OffsetDir = direction.XYZ();
613 XYZ Ndir = (V1.XYZ()).Crossed (OffsetDir);
614 XYZ DNdir = (V2.XYZ()).Crossed (OffsetDir);
615 XYZ D2Ndir = (V3.XYZ()).Crossed (OffsetDir);
616 Standard_Real R2 = Ndir.SquareModulus();
617 Standard_Real R = Sqrt (R2);
618 Standard_Real R3 = R2 * R;
619 Standard_Real R4 = R2 * R2;
620 Standard_Real R5 = R3 * R2;
621 Standard_Real Dr = Ndir.Dot (DNdir);
622 Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
623 if (R5 <= gp::Resolution()) {
624 //We try another computation but the stability is not very good
626 if (R4 <= gp::Resolution()) Geom_UndefinedDerivative::Raise();
628 Standard_Real R4 = R2 * R2;
629 D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
630 D2Ndir.Add (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
631 D2Ndir.Multiply (offsetValue / R);
632 V2.Add (Vec(D2Ndir));
635 DNdir.Subtract (Ndir.Multiplied (Dr/R));
636 DNdir.Multiply (offsetValue/R2);
640 // Same computation as IICURV in EUCLID-IS because the stability is
643 D2Ndir.Multiply (offsetValue/R);
644 D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
645 D2Ndir.Add (Ndir.Multiplied (
646 offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))
649 V2.Add (Vec(D2Ndir));
651 DNdir.Multiply (offsetValue/R);
652 DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
656 Ndir.Multiply (offsetValue/R);
657 Ndir.Add (PBasis.XYZ());
662 //=======================================================================
663 //function : FirstParameter
665 //=======================================================================
667 Standard_Real Geom_OffsetCurve::FirstParameter () const {
669 return basisCurve->FirstParameter();
673 //=======================================================================
674 //function : LastParameter
676 //=======================================================================
678 Standard_Real Geom_OffsetCurve::LastParameter () const {
680 return basisCurve->LastParameter();
684 //=======================================================================
687 //=======================================================================
689 Standard_Real Geom_OffsetCurve::Offset () const { return offsetValue; }
691 //=======================================================================
694 //=======================================================================
696 void Geom_OffsetCurve::Value (
697 const Standard_Real U, Pnt& P, Pnt& PBasis, Vec& V1basis) const {
699 if (basisCurve->Continuity() == GeomAbs_C0) Geom_UndefinedValue::Raise();
700 basisCurve->D1 (U, PBasis, V1basis);
701 Standard_Integer Index = 2;
702 while (V1basis.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
703 V1basis = basisCurve->DN (U, Index);
706 XYZ Ndir = (V1basis.XYZ()).Crossed (direction.XYZ());
707 Standard_Real R = Ndir.Modulus();
708 if (R <= gp::Resolution()) Geom_UndefinedValue::Raise();
709 Ndir.Multiply (offsetValue/R);
710 Ndir.Add (PBasis.XYZ());
715 //=======================================================================
716 //function : IsClosed
718 //=======================================================================
720 Standard_Boolean Geom_OffsetCurve::IsClosed () const
723 D0(FirstParameter(),PF);
724 D0(LastParameter(),PL);
725 return ( PF.Distance(PL) <= gp::Resolution());
730 //=======================================================================
733 //=======================================================================
735 Standard_Boolean Geom_OffsetCurve::IsCN (const Standard_Integer N) const {
737 Standard_RangeError_Raise_if (N < 0, " ");
738 return basisCurve->IsCN (N + 1);
742 //=======================================================================
743 //function : Transform
745 //=======================================================================
747 void Geom_OffsetCurve::Transform (const Trsf& T) {
749 basisCurve->Transform (T);
750 direction.Transform(T);
751 offsetValue *= T.ScaleFactor();
754 //=======================================================================
755 //function : TransformedParameter
757 //=======================================================================
759 Standard_Real Geom_OffsetCurve::TransformedParameter(const Standard_Real U,
760 const gp_Trsf& T) const
762 return basisCurve->TransformedParameter(U,T);
765 //=======================================================================
766 //function : ParametricTransformation
768 //=======================================================================
770 Standard_Real Geom_OffsetCurve::ParametricTransformation(const gp_Trsf& T)
773 return basisCurve->ParametricTransformation(T);