0023346: MSVC++ Error C2664: 'AIS_InteractiveObject::PolygonOffsets': conversion...
[occt.git] / src / Geom2d / Geom2d_OffsetCurve.cxx
CommitLineData
b311480e 1// Created on: 1991-06-25
2// Created by: JCV
3// Copyright (c) 1991-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
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.
10//
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.
13//
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.
20
7fd59977 21
7fd59977 22
23// modified by Edward AGAPOV (eap) Jan 28 2002 --- DN(), occ143(BUC60654)
24
25
26
27#include <Geom2d_OffsetCurve.ixx>
28#include <gp.hxx>
29#include <Standard_ConstructionError.hxx>
30#include <Standard_RangeError.hxx>
31#include <Standard_NotImplemented.hxx>
32#include <Geom2d_UndefinedDerivative.hxx>
33#include <Geom2d_UndefinedValue.hxx>
34#include <Geom2d_Line.hxx>
35#include <Geom2d_Circle.hxx>
36#include <Geom2d_Ellipse.hxx>
37#include <Geom2d_Hyperbola.hxx>
38#include <Geom2d_Parabola.hxx>
39#include <Geom2d_BezierCurve.hxx>
40#include <Geom2d_BSplineCurve.hxx>
41#include <Geom2d_TrimmedCurve.hxx>
42#include <gp_XY.hxx>
43
44typedef Handle(Geom2d_OffsetCurve) Handle(OffsetCurve);
45typedef Geom2d_OffsetCurve OffsetCurve;
46typedef Handle(Geom2d_Geometry) Handle(Geometry);
47typedef Handle(Geom2d_Curve) Handle(Curve);
48typedef Geom2d_Curve Curve;
49typedef gp_Dir2d Dir2d;
50typedef gp_Pnt2d Pnt2d;
51typedef gp_Vec2d Vec2d;
52typedef gp_Trsf2d Trsf2d;
53typedef gp_XY XY;
54
55
56
57static const int MaxDegree = 9;
58//ordre de derivation maximum pour la recherche de la premiere
59//derivee non nulle
60
61
62
63//=======================================================================
64//function : Copy
65//purpose :
66//=======================================================================
67
68Handle(Geom2d_Geometry) Geom2d_OffsetCurve::Copy () const
69{
70 Handle(OffsetCurve) C;
71 C = new OffsetCurve (basisCurve, offsetValue);
72 return C;
73}
74
75
76//=======================================================================
77//function : Geom2d_OffsetCurve
78//purpose :
79//=======================================================================
80
81Geom2d_OffsetCurve::Geom2d_OffsetCurve (const Handle(Curve)& C,
82 const Standard_Real Offset)
83: offsetValue (Offset)
84{
85 if (C->DynamicType() == STANDARD_TYPE(Geom2d_OffsetCurve)) {
86 Handle(OffsetCurve) OC = Handle(OffsetCurve)::DownCast(C->Copy());
87 if ((OC->BasisCurve())->Continuity() == GeomAbs_C0)
88 Standard_ConstructionError::Raise();
89
90 basisCurve = Handle(Curve)::DownCast((OC->BasisCurve())->Copy());
91 offsetValue += OC->Offset();
92 } else {
93 if (C->Continuity() == GeomAbs_C0)
94 Standard_ConstructionError::Raise();
95
96 basisCurve = Handle(Curve)::DownCast(C->Copy());
97 }
98}
99
100//=======================================================================
101//function : Reverse
102//purpose :
103//=======================================================================
104
105void Geom2d_OffsetCurve::Reverse ()
106{
107 basisCurve->Reverse();
108 offsetValue = -offsetValue;
109}
110
111//=======================================================================
112//function : ReversedParameter
113//purpose :
114//=======================================================================
115
116Standard_Real Geom2d_OffsetCurve::ReversedParameter( const Standard_Real U) const
117{
118 return basisCurve->ReversedParameter( U);
119}
120
121//=======================================================================
122//function : SetBasisCurve
123//purpose :
124//=======================================================================
125
126void Geom2d_OffsetCurve::SetBasisCurve (const Handle(Curve)& C)
127{
128 if (C->Continuity() == GeomAbs_C0) Standard_ConstructionError::Raise();
129 basisCurve = Handle(Geom2d_Curve)::DownCast(C->Copy());
130}
131
132//=======================================================================
133//function : SetOffsetValue
134//purpose :
135//=======================================================================
136
137void Geom2d_OffsetCurve::SetOffsetValue (const Standard_Real D) { offsetValue = D; }
138
139//=======================================================================
140//function : BasisCurve
141//purpose :
142//=======================================================================
143
144Handle(Curve) Geom2d_OffsetCurve::BasisCurve () const
145{
146 return basisCurve;
147}
148
149//=======================================================================
150//function : Continuity
151//purpose :
152//=======================================================================
153
154GeomAbs_Shape Geom2d_OffsetCurve::Continuity () const
155{
156 GeomAbs_Shape OffsetShape=GeomAbs_C0;
157 switch (basisCurve->Continuity()) {
158 case GeomAbs_C0 : OffsetShape = GeomAbs_C0; break;
159 case GeomAbs_C1 : OffsetShape = GeomAbs_C0; break;
160 case GeomAbs_C2 : OffsetShape = GeomAbs_C1; break;
161 case GeomAbs_C3 : OffsetShape = GeomAbs_C2; break;
162 case GeomAbs_CN : OffsetShape = GeomAbs_CN; break;
163 case GeomAbs_G1 : OffsetShape = GeomAbs_G1; break;
164 case GeomAbs_G2 : OffsetShape = GeomAbs_G2; break;
165 }
166 return OffsetShape;
167}
168
169//=======================================================================
170//function : D0
171//purpose :
172//=======================================================================
173
174void Geom2d_OffsetCurve::D0 (const Standard_Real U,
175 Pnt2d& P ) const
176{
177 Vec2d V1;
178
179 basisCurve->D1 (U, P, V1);
180 Standard_Integer Index = 2;
181 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
182 V1 = basisCurve->DN (U, Index);
183 Index++;
184 }
185 Standard_Real A = V1.Y();
186 Standard_Real B = - V1.X();
187 Standard_Real R = Sqrt(A*A + B * B);
188 if (R <= gp::Resolution()) Geom2d_UndefinedValue::Raise();
189 A = A * offsetValue/R;
190 B = B * offsetValue/R;
191 P.SetCoord(P.X() + A, P.Y() + B);
192}
193
194//=======================================================================
195//function : D1
196//purpose :
197//=======================================================================
198
199void Geom2d_OffsetCurve::D1 (const Standard_Real U, Pnt2d& P, Vec2d& V1) const {
200
201 // P(u) = p(u) + Offset * Ndir / R
202 // with R = || p' ^ Z|| and Ndir = P' ^ Z
203
204 // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
205
7fd59977 206 Vec2d V2;
207 basisCurve->D2 (U, P, V1, V2);
208 Standard_Integer Index = 2;
209 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
210 V1 = basisCurve->DN (U, Index);
211 Index++;
212 }
213 if (Index != 2) { V2 = basisCurve->DN (U, Index); }
214 XY Ndir (V1.Y(), -V1.X());
215 XY DNdir (V2.Y(), -V2.X());
216 Standard_Real R2 = Ndir.SquareModulus();
217 Standard_Real R = Sqrt (R2);
218 Standard_Real R3 = R * R2;
219 Standard_Real Dr = Ndir.Dot (DNdir);
220 if (R3 <= gp::Resolution()) {
221 //We try another computation but the stability is not very good.
222 if (R2 <= gp::Resolution()) Geom2d_UndefinedDerivative::Raise();
223 DNdir.Multiply(R);
224 DNdir.Subtract (Ndir.Multiplied (Dr/R));
225 DNdir.Multiply (offsetValue/R2);
226 V1.Add (Vec2d(DNdir));
227 }
228 else {
229 // Same computation as IICURV in EUCLID-IS because the stability is
230 // better
231 DNdir.Multiply (offsetValue/R);
232 DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
233 V1.Add (Vec2d(DNdir));
234 }
235 Ndir.Multiply (offsetValue/R);
236 Ndir.Add (P.XY());
237 P.SetXY (Ndir);
238}
239
240//=======================================================================
241//function : D2
242//purpose :
243//=======================================================================
244
245void Geom2d_OffsetCurve::D2 (const Standard_Real U,
246 Pnt2d& P,
247 Vec2d& V1, Vec2d& V2) const
248{
249 // P(u) = p(u) + Offset * Ndir / R
250 // with R = || p' ^ Z|| and Ndir = P' ^ Z
251
252 // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
253
254 // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
255 // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
256
7fd59977 257 Vec2d V3;
258 basisCurve->D3 (U, P, V1, V2, V3);
259 Standard_Integer Index = 2;
260 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
261 V1 = basisCurve->DN (U, Index);
262 Index++;
263 }
264 if (Index != 2) {
265 V2 = basisCurve->DN (U, Index);
266 V3 = basisCurve->DN (U, Index + 1);
267 }
268 XY Ndir (V1.Y(), -V1.X());
269 XY DNdir (V2.Y(), -V2.X());
270 XY D2Ndir (V3.Y(), -V3.X());
271 Standard_Real R2 = Ndir.SquareModulus();
272 Standard_Real R = Sqrt (R2);
273 Standard_Real R3 = R2 * R;
274 Standard_Real R4 = R2 * R2;
275 Standard_Real R5 = R3 * R2;
276 Standard_Real Dr = Ndir.Dot (DNdir);
277 Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
278 if (R5 <= gp::Resolution()) {
279 //We try another computation but the stability is not very good
280 //dixit ISG.
281 if (R4 <= gp::Resolution()) { Geom2d_UndefinedDerivative::Raise(); }
282 // V2 = P" (U) :
283 Standard_Real R4 = R2 * R2;
284 D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
285 D2Ndir.Add (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
286 D2Ndir.Multiply (offsetValue / R);
287 V2.Add (Vec2d(D2Ndir));
288 // V1 = P' (U) :
289 DNdir.Multiply(R);
290 DNdir.Subtract (Ndir.Multiplied (Dr/R));
291 DNdir.Multiply (offsetValue/R2);
292 V1.Add (Vec2d(DNdir));
293 }
294 else {
295 // Same computation as IICURV in EUCLID-IS because the stability is
296 // better.
297 // V2 = P" (U) :
298 D2Ndir.Multiply (offsetValue/R);
299 D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
300 D2Ndir.Add (Ndir.Multiplied
301 (offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))));
302 V2.Add (Vec2d(D2Ndir));
303 // V1 = P' (U)
304 DNdir.Multiply (offsetValue/R);
305 DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
306 V1.Add (Vec2d(DNdir));
307 }
308 //P (U) :
309 Ndir.Multiply (offsetValue/R);
310 Ndir.Add (P.XY());
311 P.SetXY (Ndir);
312}
313
314
315//=======================================================================
316//function : D3
317//purpose :
318//=======================================================================
319
320void Geom2d_OffsetCurve::D3 (const Standard_Real U,
321 Pnt2d& P,
322 Vec2d& V1, Vec2d& V2, Vec2d& V3) const {
323
324
325 // P(u) = p(u) + Offset * Ndir / R
326 // with R = || p' ^ Z|| and Ndir = P' ^ Z
327
328 // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
329
330 // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
331 // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
332
333 //P"'(u) = p"'(u) + (Offset / R) * (D3Ndir - (3.0 * Dr/R**2 ) * D2Ndir -
334 // (3.0 * D2r / R2) * DNdir) + (3.0 * Dr * Dr / R4) * DNdir -
335 // (D3r/R2) * Ndir + (6.0 * Dr * Dr / R4) * Ndir +
336 // (6.0 * Dr * D2r / R4) * Ndir - (15.0 * Dr* Dr* Dr /R6) * Ndir
337
338
339
340 basisCurve->D3 (U, P, V1, V2, V3);
341 Vec2d V4 = basisCurve->DN (U, 4);
342 Standard_Integer Index = 2;
343 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
344 V1 = basisCurve->DN (U, Index);
345 Index++;
346 }
347 if (Index != 2) {
348 V2 = basisCurve->DN (U, Index);
349 V3 = basisCurve->DN (U, Index + 1);
350 V4 = basisCurve->DN (U, Index + 2);
351 }
352 XY Ndir (V1.Y(), -V1.X());
353 XY DNdir (V2.Y(), -V2.X());
354 XY D2Ndir (V3.Y(), -V3.X());
355 XY D3Ndir (V4.Y(), -V4.X());
356 Standard_Real R2 = Ndir.SquareModulus();
357 Standard_Real R = Sqrt (R2);
358 Standard_Real R3 = R2 * R;
359 Standard_Real R4 = R2 * R2;
360 Standard_Real R5 = R3 * R2;
361 Standard_Real R6 = R3 * R3;
362 Standard_Real R7 = R5 * R2;
363 Standard_Real Dr = Ndir.Dot (DNdir);
364 Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
365 Standard_Real D3r = Ndir.Dot (D3Ndir) + 3.0 * DNdir.Dot (D2Ndir);
366 if (R7 <= gp::Resolution()) {
367 //We try another computation but the stability is not very good
368 //dixit ISG.
369 if (R6 <= gp::Resolution()) Geom2d_UndefinedDerivative::Raise();
370 // V3 = P"' (U) :
371 D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * offsetValue * Dr / R2));
372 D3Ndir.Subtract (
373 (DNdir.Multiplied ((3.0 * offsetValue) * ((D2r/R2) + (Dr*Dr)/R4))));
374 D3Ndir.Add (Ndir.Multiplied (
375 (offsetValue * (6.0*Dr*Dr/R4 + 6.0*Dr*D2r/R4 - 15.0*Dr*Dr*Dr/R6 - D3r))
376 ));
377 D3Ndir.Multiply (offsetValue/R);
378 V3.Add (Vec2d(D3Ndir));
379 // V2 = P" (U) :
380 Standard_Real R4 = R2 * R2;
381 D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
382 D2Ndir.Subtract (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
383 D2Ndir.Multiply (offsetValue / R);
384 V2.Add (Vec2d(D2Ndir));
385 // V1 = P' (U) :
386 DNdir.Multiply(R);
387 DNdir.Subtract (Ndir.Multiplied (Dr/R));
388 DNdir.Multiply (offsetValue/R2);
389 V1.Add (Vec2d(DNdir));
390 }
391 else {
392 // Same computation as IICURV in EUCLID-IS because the stability is
393 // better.
394 // V3 = P"' (U) :
395 D3Ndir.Multiply (offsetValue/R);
396 D3Ndir.Subtract (D2Ndir.Multiplied (3.0 * offsetValue * Dr / R3));
397 D3Ndir.Subtract (DNdir.Multiplied (
398 ((3.0 * offsetValue) * ((D2r/R3) + (Dr*Dr)/R5))) );
399 D3Ndir.Add (Ndir.Multiplied (
400 (offsetValue * (6.0*Dr*Dr/R5 + 6.0*Dr*D2r/R5 - 15.0*Dr*Dr*Dr/R7 - D3r))
401 ));
402 V3.Add (Vec2d(D3Ndir));
403 // V2 = P" (U) :
404 D2Ndir.Multiply (offsetValue/R);
405 D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
406 D2Ndir.Subtract (Ndir.Multiplied (
407 offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))
408 )
409 );
410 V2.Add (Vec2d(D2Ndir));
411 // V1 = P' (U) :
412 DNdir.Multiply (offsetValue/R);
413 DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
414 V1.Add (Vec2d(DNdir));
415 }
416 //P (U) :
417 Ndir.Multiply (offsetValue/R);
418 Ndir.Add (P.XY());
419 P.SetXY (Ndir);
420}
421
422//=======================================================================
423//function : DN
424//purpose :
425//=======================================================================
426
427Vec2d Geom2d_OffsetCurve::DN (const Standard_Real U,
428 const Standard_Integer N) const
429{
430 Standard_RangeError_Raise_if (N < 1, "Geom2d_OffsetCurve::DN()");
431
432 gp_Vec2d VN, VBidon;
433 gp_Pnt2d PBidon;
434 switch (N) {
435 case 1: D1( U, PBidon, VN); break;
436 case 2: D2( U, PBidon, VBidon, VN); break;
437 case 3: D3( U, PBidon, VBidon, VBidon, VN); break;
438 default:
439 Standard_NotImplemented::Raise();
440 }
441
442 return VN;
443}
444
445
446//=======================================================================
447//function : Value
448//purpose :
449//=======================================================================
450
451void Geom2d_OffsetCurve::Value (const Standard_Real U,
452 Pnt2d& P, Pnt2d& Pbasis,
453 Vec2d& V1basis ) const
454{
455
456 basisCurve->D1 (U, Pbasis, V1basis);
457 Standard_Integer Index = 2;
458 while (V1basis.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
459 V1basis = basisCurve->DN (U, Index);
460 Index++;
461 }
462 Standard_Real A = V1basis.Y();
463 Standard_Real B = - V1basis.X();
464 Standard_Real R = Sqrt(A*A + B * B);
465 if (R <= gp::Resolution()) Geom2d_UndefinedValue::Raise();
466 A = A * offsetValue/R;
467 B = B * offsetValue/R;
468 P.SetCoord (A + Pbasis.X(), B + Pbasis.Y());
469}
470
471
472//=======================================================================
473//function : D1
474//purpose :
475//=======================================================================
476
477void Geom2d_OffsetCurve::D1 (const Standard_Real U,
478 Pnt2d& P, Pnt2d& Pbasis,
479 Vec2d& V1, Vec2d& V1basis,
480 Vec2d& V2basis ) const
481{
482 // P(u) = p(u) + Offset * Ndir / R
483 // with R = || p' ^ Z|| and Ndir = P' ^ Z
484
485 // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
486
7fd59977 487 basisCurve->D2 (U, Pbasis, V1basis, V2basis);
488 V1 = V1basis;
489 Vec2d V2 = V2basis;
490 Standard_Integer Index = 2;
491 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
492 V1 = basisCurve->DN (U, Index);
493 Index++;
494 }
495 if (Index != 2) {
496 V2 = basisCurve->DN (U, Index);
497 }
498 XY Ndir (V1.Y(), -V1.X());
499 XY DNdir (V2.Y(), -V2.X());
500 Standard_Real R2 = Ndir.SquareModulus();
501 Standard_Real R = Sqrt (R2);
502 Standard_Real R3 = R * R2;
503 Standard_Real Dr = Ndir.Dot (DNdir);
504 if (R3 <= gp::Resolution()) {
505 //We try another computation but the stability is not very good.
506 if (R2 <= gp::Resolution()) { Geom2d_UndefinedDerivative::Raise(); }
507 DNdir.Multiply(R);
508 DNdir.Subtract (Ndir.Multiplied (Dr/R));
509 DNdir.Multiply (offsetValue / R2);
510 V1.Add (Vec2d(DNdir));
511 }
512 else {
513 // Same computation as IICURV in EUCLID-IS because the stability is
514 // better
515 DNdir.Multiply (offsetValue/R);
516 DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
517 V1.Add (Vec2d(DNdir));
518 }
519 Ndir.Multiply (offsetValue/R);
520 Ndir.Add (Pbasis.XY());
521 P.SetXY (Ndir);
522}
523
524
525//=======================================================================
526//function : D2
527//purpose :
528//=======================================================================
529
530void Geom2d_OffsetCurve::D2 (const Standard_Real U,
531 Pnt2d& P, Pnt2d& Pbasis,
532 Vec2d& V1, Vec2d& V2,
533 Vec2d& V1basis, Vec2d& V2basis,
534 Vec2d& V3basis ) const
535{
536 // P(u) = p(u) + Offset * Ndir / R
537 // with R = || p' ^ Z|| and Ndir = P' ^ Z
538
539 // P'(u) = p'(u) + (Offset / R**2) * (DNdir/DU * R - Ndir * (DR/R))
540
541 // P"(u) = p"(u) + (Offset / R) * (D2Ndir/DU - DNdir * (2.0 * Dr/ R**2) +
542 // Ndir * ( (3.0 * Dr**2 / R**4) - (D2r / R**2)))
543
7fd59977 544 basisCurve->D3 (U, Pbasis, V1basis, V2basis, V3basis);
545 Standard_Integer Index = 2;
546 V1 = V1basis;
547 V2 = V2basis;
548 Vec2d V3 = V3basis;
549 while (V1.Magnitude() <= gp::Resolution() && Index <= MaxDegree) {
550 V1 = basisCurve->DN (U, Index);
551 Index++;
552 }
553 if (Index != 2) {
554 V2 = basisCurve->DN (U, Index);
555 V3 = basisCurve->DN (U, Index + 1);
556 }
557 XY Ndir (V1.Y(), -V1.X());
558 XY DNdir (V2.Y(), -V2.X());
559 XY D2Ndir (V3.Y(), -V3.X());
560 Standard_Real R2 = Ndir.SquareModulus();
561 Standard_Real R = Sqrt (R2);
562 Standard_Real R3 = R2 * R;
563 Standard_Real R4 = R2 * R2;
564 Standard_Real R5 = R3 * R2;
565 Standard_Real Dr = Ndir.Dot (DNdir);
566 Standard_Real D2r = Ndir.Dot (D2Ndir) + DNdir.Dot (DNdir);
567 if (R5 <= gp::Resolution()) {
568 //We try another computation but the stability is not very good
569 //dixit ISG.
570 if (R4 <= gp::Resolution()) { Geom2d_UndefinedDerivative::Raise(); }
571 // V2 = P" (U) :
572 Standard_Real R4 = R2 * R2;
573 D2Ndir.Subtract (DNdir.Multiplied (2.0 * Dr / R2));
574 D2Ndir.Subtract (Ndir.Multiplied (((3.0 * Dr * Dr)/R4) - (D2r/R2)));
575 D2Ndir.Multiply (offsetValue / R);
576 V2.Add (Vec2d(D2Ndir));
577 // V1 = P' (U) :
578 DNdir.Multiply(R);
579 DNdir.Subtract (Ndir.Multiplied (Dr/R));
580 DNdir.Multiply (offsetValue/R2);
581 V1.Add (Vec2d(DNdir));
582 }
583 else {
584 // Same computation as IICURV in EUCLID-IS because the stability is
585 // better.
586 // V2 = P" (U) :
587 D2Ndir.Multiply (offsetValue/R);
588 D2Ndir.Subtract (DNdir.Multiplied (2.0 * offsetValue * Dr / R3));
589 D2Ndir.Subtract (Ndir.Multiplied (
590 offsetValue * (((3.0 * Dr * Dr) / R5) - (D2r / R3))
591 )
592 );
593 V2.Add (Vec2d(D2Ndir));
594 // V1 = P' (U) :
595 DNdir.Multiply (offsetValue/R);
596 DNdir.Subtract (Ndir.Multiplied (offsetValue*Dr/R3));
597 V1.Add (Vec2d(DNdir));
598 }
599 //P (U) :
600 Ndir.Multiply (offsetValue/R);
601 Ndir.Add (Pbasis.XY());
602 P.SetXY (Ndir);
603}
604
605//=======================================================================
606//function : FirstParameter
607//purpose :
608//=======================================================================
609
610Standard_Real Geom2d_OffsetCurve::FirstParameter () const
611{
612 return basisCurve->FirstParameter();
613}
614
615//=======================================================================
616//function : LastParameter
617//purpose :
618//=======================================================================
619
620Standard_Real Geom2d_OffsetCurve::LastParameter () const
621{
622 return basisCurve->LastParameter();
623}
624
625
626//=======================================================================
627//function : Offset
628//purpose :
629//=======================================================================
630
631Standard_Real Geom2d_OffsetCurve::Offset () const { return offsetValue; }
632
633//=======================================================================
634//function : IsClosed
635//purpose :
636//=======================================================================
637
638Standard_Boolean Geom2d_OffsetCurve::IsClosed () const
639{
640 gp_Pnt2d PF, PL;
641 D0(FirstParameter(),PF);
642 D0(LastParameter(),PL);
643 return ( PF.Distance(PL) <= gp::Resolution());
644}
645
646//=======================================================================
647//function : IsCN
648//purpose :
649//=======================================================================
650
651Standard_Boolean Geom2d_OffsetCurve::IsCN (const Standard_Integer N) const
652{
653 Standard_RangeError_Raise_if (N < 0, " " );
654 return basisCurve->IsCN (N + 1);
655}
656
657//=======================================================================
658//function : IsPeriodic
659//purpose :
660//=======================================================================
661
662Standard_Boolean Geom2d_OffsetCurve::IsPeriodic () const
663{
664 return basisCurve->IsPeriodic();
665}
666
667//=======================================================================
668//function : Period
669//purpose :
670//=======================================================================
671
672Standard_Real Geom2d_OffsetCurve::Period() const
673{
674 return basisCurve->Period();
675}
676
677//=======================================================================
678//function : Transform
679//purpose :
680//=======================================================================
681
682void Geom2d_OffsetCurve::Transform (const Trsf2d& T)
683{
684 basisCurve->Transform (T);
685 offsetValue *= Abs(T.ScaleFactor());
686}
687
688
689//=======================================================================
690//function : TransformedParameter
691//purpose :
692//=======================================================================
693
694Standard_Real Geom2d_OffsetCurve::TransformedParameter(const Standard_Real U,
695 const gp_Trsf2d& T) const
696{
697 return basisCurve->TransformedParameter(U,T);
698}
699
700//=======================================================================
701//function : ParametricTransformation
702//purpose :
703//=======================================================================
704
705Standard_Real Geom2d_OffsetCurve::ParametricTransformation(const gp_Trsf2d& T) const
706{
707 return basisCurve->ParametricTransformation(T);
708}