0032137: Coding Rules - merge redundant .lxx files into header files within Package gp
[occt.git] / src / gp / gp_Elips2d.hxx
1 // Copyright (c) 1991-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #ifndef _gp_Elips2d_HeaderFile
16 #define _gp_Elips2d_HeaderFile
17
18 #include <gp.hxx>
19 #include <gp_Ax22d.hxx>
20 #include <gp_Ax2d.hxx>
21 #include <gp_Pnt2d.hxx>
22 #include <Standard_ConstructionError.hxx>
23
24 //! Describes an ellipse in the plane (2D space).
25 //! An ellipse is defined by its major and minor radii and
26 //! positioned in the plane with a coordinate system (a
27 //! gp_Ax22d object) as follows:
28 //! -   the origin of the coordinate system is the center of the ellipse,
29 //! -   its "X Direction" defines the major axis of the ellipse, and
30 //! -   its "Y Direction" defines the minor axis of the ellipse.
31 //! This coordinate system is the "local coordinate system"
32 //! of the ellipse. Its orientation (direct or indirect) gives an
33 //! implicit orientation to the ellipse. In this coordinate
34 //! system, the equation of the ellipse is:
35 //! @code
36 //! X*X / (MajorRadius**2) + Y*Y / (MinorRadius**2) = 1.0
37 //! @endcode
38 //! See Also
39 //! gce_MakeElips2d which provides functions for more
40 //! complex ellipse constructions
41 //! Geom2d_Ellipse which provides additional functions for
42 //! constructing ellipses and works, in particular, with the
43 //! parametric equations of ellipses
44 class gp_Elips2d 
45 {
46 public:
47
48   DEFINE_STANDARD_ALLOC
49
50   //! Creates an indefinite ellipse.
51   gp_Elips2d()
52   : majorRadius (RealLast()),
53     minorRadius (RealSmall())
54   {}
55
56   //! Creates an ellipse with the major axis, the major and the
57   //! minor radius. The location of the theMajorAxis is the center
58   //! of the  ellipse.
59   //! The sense of parametrization is given by theIsSense.
60   //! Warnings :
61   //! It is possible to create an ellipse with
62   //! theMajorRadius = theMinorRadius.
63   //! Raises ConstructionError if theMajorRadius < theMinorRadius or theMinorRadius < 0.0
64   gp_Elips2d (const gp_Ax2d& theMajorAxis, const Standard_Real theMajorRadius,
65               const Standard_Real theMinorRadius, const Standard_Boolean theIsSense = Standard_True)
66   : majorRadius (theMajorRadius),
67     minorRadius (theMinorRadius)
68   {
69     pos = gp_Ax22d (theMajorAxis, theIsSense);
70     Standard_ConstructionError_Raise_if (theMinorRadius < 0.0 || theMajorRadius < theMinorRadius,
71       "gp_Elips2d() - invalid construction parameters");
72   }
73
74   //! Creates an ellipse with radii MajorRadius and
75   //! MinorRadius, positioned in the plane by coordinate system theA where:
76   //! -   the origin of theA is the center of the ellipse,
77   //! -   the "X Direction" of theA defines the major axis of
78   //! the ellipse, that is, the major radius MajorRadius
79   //! is measured along this axis, and
80   //! -   the "Y Direction" of theA defines the minor axis of
81   //! the ellipse, that is, the minor radius theMinorRadius
82   //! is measured along this axis, and
83   //! -   the orientation (direct or indirect sense) of theA
84   //! gives the orientation of the ellipse.
85   //! Warnings :
86   //! It is possible to create an ellipse with
87   //! theMajorRadius = theMinorRadius.
88   //! Raises ConstructionError if theMajorRadius < theMinorRadius or theMinorRadius < 0.0
89   gp_Elips2d (const gp_Ax22d& theA, const Standard_Real theMajorRadius, const Standard_Real theMinorRadius)
90   : pos (theA),
91     majorRadius (theMajorRadius),
92     minorRadius (theMinorRadius)
93   {
94     Standard_ConstructionError_Raise_if (theMinorRadius < 0.0 || theMajorRadius < theMinorRadius,
95       "gp_Elips2d() - invalid construction parameters");
96   }
97
98   //! Modifies this ellipse, by redefining its local coordinate system so that
99   //! -   its origin becomes theP.
100   void SetLocation (const gp_Pnt2d& theP) { pos.SetLocation (theP); }
101
102   //! Changes the value of the major radius.
103   //! Raises ConstructionError if theMajorRadius < MinorRadius.
104   void SetMajorRadius (const Standard_Real theMajorRadius)
105   {
106     Standard_ConstructionError_Raise_if (theMajorRadius < minorRadius,
107       "gp_Elips2d::SetMajorRadius() - major radius should be greater or equal to minor radius");
108     majorRadius = theMajorRadius;
109   }
110   
111   //! Changes the value of the minor radius.
112   //! Raises ConstructionError if MajorRadius < theMinorRadius or MinorRadius < 0.0
113   void SetMinorRadius (const Standard_Real theMinorRadius)
114   {
115     Standard_ConstructionError_Raise_if (theMinorRadius < 0.0 || majorRadius < theMinorRadius,
116       "gp_Elips2d::SetMinorRadius() - minor radius should be a positive number lesser or equal to major radius");
117     minorRadius = theMinorRadius;
118   }
119
120   //! Modifies this ellipse, by redefining its local coordinate system so that
121   //! it becomes theA.
122   void SetAxis (const gp_Ax22d& theA) { pos.SetAxis (theA); }
123
124   //! Modifies this ellipse, by redefining its local coordinate system so that
125   //! its origin and its "X Direction"  become those
126   //! of the axis theA. The "Y  Direction"  is then
127   //! recomputed. The orientation of the local coordinate
128   //! system is not modified.
129   void SetXAxis (const gp_Ax2d& theA) { pos.SetXAxis (theA); }
130
131   //! Modifies this ellipse, by redefining its local coordinate system so that
132   //! its origin and its "Y Direction"  become those
133   //! of the axis theA. The "X  Direction"  is then
134   //! recomputed. The orientation of the local coordinate
135   //! system is not modified.
136   void SetYAxis (const gp_Ax2d& theA) { pos.SetYAxis (theA); }
137
138   //! Computes the area of the ellipse.
139   Standard_Real Area() const { return M_PI * majorRadius * minorRadius; }
140
141   //! Returns the coefficients of the implicit equation of the ellipse.
142   //! theA * (X**2) + theB * (Y**2) + 2*theC*(X*Y) + 2*theD*X + 2*theE*Y + theF = 0.
143   Standard_EXPORT void Coefficients (Standard_Real& theA, Standard_Real& theB, Standard_Real& theC,
144                                      Standard_Real& theD, Standard_Real& theE, Standard_Real& theF) const;
145
146   //! This directrix is the line normal to the XAxis of the ellipse
147   //! in the local plane (Z = 0) at a distance d = MajorRadius / e
148   //! from the center of the ellipse, where e is the eccentricity of
149   //! the ellipse.
150   //! This line is parallel to the "YAxis". The intersection point
151   //! between directrix1 and the "XAxis" is the location point of the
152   //! directrix1. This point is on the positive side of the "XAxis".
153   //!
154   //! Raised if Eccentricity = 0.0. (The ellipse degenerates into a
155   //! circle)
156   gp_Ax2d Directrix1() const;
157
158   //! This line is obtained by the symmetrical transformation
159   //! of "Directrix1" with respect to the minor axis of the ellipse.
160   //!
161   //! Raised if Eccentricity = 0.0. (The ellipse degenerates into a
162   //! circle).
163   gp_Ax2d Directrix2() const;
164
165   //! Returns the eccentricity of the ellipse  between 0.0 and 1.0
166   //! If f is the distance between the center of the ellipse and
167   //! the Focus1 then the eccentricity e = f / MajorRadius.
168   //! Returns 0 if MajorRadius = 0.
169   Standard_Real Eccentricity() const;
170
171   //! Returns the distance between the center of the ellipse
172   //! and focus1 or focus2.
173   Standard_Real Focal() const
174   {
175     return 2.0 * sqrt (majorRadius * majorRadius - minorRadius * minorRadius);
176   }
177
178   //! Returns the first focus of the ellipse. This focus is on the
179   //! positive side of the major axis of the ellipse.
180   gp_Pnt2d Focus1() const;
181
182   //! Returns the second focus of the ellipse. This focus is on the
183   //! negative side of the major axis of the ellipse.
184   gp_Pnt2d Focus2() const;
185
186   //! Returns the center of the ellipse.
187   const gp_Pnt2d& Location() const { return pos.Location(); }
188
189   //! Returns the major radius of the Ellipse.
190   Standard_Real MajorRadius() const { return majorRadius; }
191
192   //! Returns the minor radius of the Ellipse.
193   Standard_Real MinorRadius() const { return minorRadius; }
194
195   //! Returns p = (1 - e * e) * MajorRadius where e is the eccentricity
196   //! of the ellipse.
197   //! Returns 0 if MajorRadius = 0
198   Standard_Real Parameter() const;
199
200   //! Returns the major axis of the ellipse.
201   const gp_Ax22d& Axis() const { return pos; }
202
203   //! Returns the major axis of the ellipse.
204   gp_Ax2d XAxis() const { return pos.XAxis(); }
205
206   //! Returns the minor axis of the ellipse.
207   //! Reverses the direction of the circle.
208   gp_Ax2d YAxis() const { return pos.YAxis(); }
209
210   void Reverse()
211   {
212     gp_Dir2d aTemp = pos.YDirection();
213     aTemp.Reverse();
214     pos.SetAxis (gp_Ax22d (pos.Location(), pos.XDirection(), aTemp));
215   }
216
217   Standard_NODISCARD gp_Elips2d Reversed() const;
218
219   //! Returns true if the local coordinate system is direct
220   //! and false in the other case.
221   Standard_Boolean IsDirect() const { return (pos.XDirection().Crossed (pos.YDirection())) >= 0.0; }
222
223   Standard_EXPORT void Mirror (const gp_Pnt2d& theP);
224
225   //! Performs the symmetrical transformation of a ellipse with respect
226   //! to the point theP which is the center of the symmetry
227   Standard_NODISCARD Standard_EXPORT gp_Elips2d Mirrored (const gp_Pnt2d& theP) const;
228
229   Standard_EXPORT void Mirror (const gp_Ax2d& theA);
230
231   //! Performs the symmetrical transformation of a ellipse with respect
232   //! to an axis placement which is the axis of the symmetry.
233   Standard_NODISCARD Standard_EXPORT gp_Elips2d Mirrored (const gp_Ax2d& theA) const;
234
235   void Rotate (const gp_Pnt2d& theP, const Standard_Real theAng) { pos.Rotate (theP, theAng); }
236
237   Standard_NODISCARD gp_Elips2d Rotated (const gp_Pnt2d& theP, const Standard_Real theAng) const
238   {
239     gp_Elips2d anE = *this;
240     anE.pos.Rotate (theP, theAng);
241     return anE;
242   }
243
244   void Scale (const gp_Pnt2d& theP, const Standard_Real theS);
245
246   //! Scales a ellipse. theS is the scaling value.
247   Standard_NODISCARD gp_Elips2d Scaled (const gp_Pnt2d& theP, const Standard_Real theS) const;
248
249   void Transform (const gp_Trsf2d& theT);
250
251   //! Transforms an ellipse with the transformation theT from class Trsf2d.
252   Standard_NODISCARD gp_Elips2d Transformed (const gp_Trsf2d& theT) const;
253
254   void Translate (const gp_Vec2d& theV) { pos.Translate (theV); }
255
256   //! Translates a ellipse in the direction of the vector theV.
257   //! The magnitude of the translation is the vector's magnitude.
258   Standard_NODISCARD gp_Elips2d Translated (const gp_Vec2d& theV) const
259   {
260     gp_Elips2d anE = *this;
261     anE.pos.Translate (theV);
262     return anE;
263   }
264
265   void Translate (const gp_Pnt2d& theP1, const gp_Pnt2d& theP2) { pos.Translate (theP1, theP2); }
266
267   //! Translates a ellipse from the point theP1 to the point theP2.
268   Standard_NODISCARD gp_Elips2d Translated (const gp_Pnt2d& theP1, const gp_Pnt2d& theP2) const
269   {
270     gp_Elips2d anE = *this;
271     anE.pos.Translate (theP1, theP2);
272     return anE;
273   }
274
275 private:
276
277   gp_Ax22d pos;
278   Standard_Real majorRadius;
279   Standard_Real minorRadius;
280
281 };
282
283
284 // =======================================================================
285 // function : Directrix1
286 // purpose  :
287 // =======================================================================
288 inline gp_Ax2d gp_Elips2d::Directrix1() const
289 {
290   Standard_Real anE = Eccentricity();
291   Standard_ConstructionError_Raise_if (anE <= gp::Resolution(), "gp_Elips2d::Directrix1() - zero eccentricity");
292   gp_XY anOrig = pos.XDirection().XY();
293   anOrig.Multiply (majorRadius / anE);
294   anOrig.Add (pos.Location().XY());
295   return gp_Ax2d (gp_Pnt2d (anOrig), gp_Dir2d (pos.YDirection()));
296 }
297
298 // =======================================================================
299 // function : Directrix2
300 // purpose  :
301 // =======================================================================
302 inline gp_Ax2d gp_Elips2d::Directrix2() const
303 {
304   Standard_Real anE = Eccentricity();
305   Standard_ConstructionError_Raise_if (anE <= gp::Resolution(), "gp_Elips2d::Directrix2() - zero eccentricity");
306   gp_XY anOrig = pos.XDirection().XY();
307   anOrig.Multiply (-majorRadius / anE);
308   anOrig.Add (pos.Location().XY());
309   return gp_Ax2d (gp_Pnt2d (anOrig), gp_Dir2d (pos.YDirection()));
310 }
311
312 // =======================================================================
313 // function : Eccentricity
314 // purpose  :
315 // =======================================================================
316 inline Standard_Real gp_Elips2d::Eccentricity() const
317 {
318   if (majorRadius == 0.0)
319   {
320     return 0.0;
321   }
322   else
323   {
324     return sqrt (majorRadius * majorRadius - minorRadius * minorRadius) / majorRadius;
325   }
326 }
327
328 // =======================================================================
329 // function : Focus1
330 // purpose  :
331 // =======================================================================
332 inline gp_Pnt2d gp_Elips2d::Focus1() const
333 {
334   Standard_Real aC = sqrt (majorRadius * majorRadius - minorRadius * minorRadius);
335   const gp_Pnt2d& aPP = pos.Location();
336   const gp_Dir2d& aDD = pos.XDirection();
337   return gp_Pnt2d (aPP.X() + aC * aDD.X(),
338                    aPP.Y() + aC * aDD.Y());
339 }
340
341 // =======================================================================
342 // function : Focus2
343 // purpose  :
344 // =======================================================================
345 inline gp_Pnt2d gp_Elips2d::Focus2() const
346 {
347   Standard_Real aC = sqrt (majorRadius * majorRadius - minorRadius * minorRadius);
348   const gp_Pnt2d& aPP = pos.Location();
349   const gp_Dir2d& aDD = pos.XDirection();
350   return gp_Pnt2d (aPP.X() - aC * aDD.X(),
351                    aPP.Y() - aC * aDD.Y());
352 }
353
354 // =======================================================================
355 // function : Scale
356 // purpose  :
357 // =======================================================================
358 inline void gp_Elips2d::Scale (const gp_Pnt2d& theP, const Standard_Real theS)
359 {
360   majorRadius *= theS;
361   if (majorRadius < 0)
362   {
363     majorRadius = -majorRadius;
364   }
365   minorRadius *= theS;
366   if (minorRadius < 0)
367   {
368     minorRadius = -minorRadius;
369   }
370   pos.Scale (theP, theS);
371 }
372
373 // =======================================================================
374 // function : Scaled
375 // purpose  :
376 // =======================================================================
377 inline gp_Elips2d gp_Elips2d::Scaled (const gp_Pnt2d& theP, const Standard_Real theS) const
378 {
379   gp_Elips2d anE = *this;
380   anE.majorRadius *= theS;
381   if (anE.majorRadius < 0)
382   {
383     anE.majorRadius = -anE.majorRadius;
384   }
385   anE.minorRadius *= theS;
386   if (anE.minorRadius < 0)
387   {
388     anE.minorRadius = -anE.minorRadius;
389   }
390   anE.pos.Scale (theP, theS);
391   return anE; 
392 }
393
394 // =======================================================================
395 // function : Parameter
396 // purpose  :
397 // =======================================================================
398 inline Standard_Real gp_Elips2d::Parameter() const
399
400   if (majorRadius == 0.0)
401   {
402     return 0.0;
403   }
404   else
405   {
406     return (minorRadius * minorRadius) / majorRadius;
407   }
408 }
409
410 // =======================================================================
411 // function : Reversed
412 // purpose  :
413 // =======================================================================
414 inline gp_Elips2d gp_Elips2d::Reversed() const
415 {
416   gp_Elips2d anE = *this;
417   gp_Dir2d aTemp = pos.YDirection ();
418   aTemp.Reverse ();
419   anE.pos.SetAxis (gp_Ax22d (pos.Location(),pos.XDirection(), aTemp));
420   return anE;
421 }
422
423 // =======================================================================
424 // function : Transform
425 // purpose  :
426 // =======================================================================
427 inline void gp_Elips2d::Transform (const gp_Trsf2d& theT)
428 {
429   Standard_Real aTSca = theT.ScaleFactor();
430   if (aTSca < 0.0)
431   {
432     aTSca = -aTSca;
433   }
434   majorRadius *=  aTSca;
435   minorRadius *=  aTSca;
436   pos.Transform (theT);
437 }
438
439 // =======================================================================
440 // function : Transformed
441 // purpose  :
442 // =======================================================================
443 inline gp_Elips2d gp_Elips2d::Transformed (const gp_Trsf2d& theT) const  
444 {
445   gp_Elips2d anE = *this;
446   anE.majorRadius *= theT.ScaleFactor();
447   if (anE.majorRadius < 0)
448   {
449     anE.majorRadius = -anE.majorRadius;
450   }
451   anE.minorRadius *= theT.ScaleFactor();
452   if (anE.minorRadius < 0)
453   {
454     anE.minorRadius = -anE.minorRadius;
455   }
456   anE.pos.Transform (theT);
457   return anE;
458 }
459
460 #endif // _gp_Elips2d_HeaderFile