Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / GeomAPI / GeomAPI_Angle2d.cpp
1 // Copyright (C) 2016-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAPI_Angle2d.cpp
4 // Created:     19 April 2016
5 // Author:      Artem ZHIDKOV
6
7 #include <GeomAPI_Angle2d.h>
8 #include <GeomAPI_Dir2d.h>
9 #include <GeomAPI_Lin2d.h>
10 #include <GeomAPI_Pnt2d.h>
11 #include <GeomAPI_XY.h>
12
13 #include <gp_Dir2d.hxx>
14 #include <gp_Pnt2d.hxx>
15 #include <gp_XY.hxx>
16
17 /// \struct ThreePoints
18 /// \brief Used to store info about angle point and state.
19 struct ThreePoints2d {
20   gp_Pnt2d myCenter;
21   gp_Pnt2d myFirst;
22   gp_Pnt2d mySecond;
23   bool myReversed[2];
24 };
25
26 #define MY_ANGLE implPtr<ThreePoints2d>()
27 #define PI 3.1415926535897932
28
29 static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
30                                const std::shared_ptr<GeomAPI_Pnt2d>& theFirst,
31                                const std::shared_ptr<GeomAPI_Pnt2d>& theSecond)
32 {
33   ThreePoints2d* aResult = new ThreePoints2d;
34   aResult->myCenter = gp_Pnt2d(theCenter->x(), theCenter->y());
35   aResult->myFirst  = gp_Pnt2d(theFirst->x(), theFirst->y());
36   aResult->mySecond = gp_Pnt2d(theSecond->x(), theSecond->y());
37   aResult->myReversed[0] = aResult->myReversed[1] = false;
38   return aResult;
39 }
40
41 static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Pnt2d>& theStart1,
42                                const std::shared_ptr<GeomAPI_Pnt2d>& theEnd1,
43                                const std::shared_ptr<GeomAPI_Pnt2d>& theStart2,
44                                const std::shared_ptr<GeomAPI_Pnt2d>& theEnd2)
45 {
46   std::shared_ptr<GeomAPI_Lin2d> aLine1(new GeomAPI_Lin2d(theStart1, theEnd1));
47   std::shared_ptr<GeomAPI_Lin2d> aLine2(new GeomAPI_Lin2d(theStart2, theEnd2));
48   std::shared_ptr<GeomAPI_Pnt2d> aCenter = aLine1->intersect(aLine2);
49   bool isParallel = !aCenter;
50   if (isParallel)
51     aCenter = theStart1;
52   std::shared_ptr<GeomAPI_Pnt2d> aPoint1, aPoint2;
53   if (isParallel)
54     aPoint1 = aPoint2 = theEnd1;
55   else {
56     aPoint1 = theStart1->distance(aCenter) < theEnd1->distance(aCenter) ? theEnd1 : theStart1;
57     aPoint2 = theStart2->distance(aCenter) < theEnd2->distance(aCenter) ? theEnd2 : theStart2;
58   }
59   ThreePoints2d* anAngle = newAngle(aCenter, aPoint1, aPoint2);
60   anAngle->myReversed[0] = aPoint1 == theStart1;
61   anAngle->myReversed[1] = !isParallel && aPoint2 == theStart2;
62   return anAngle;
63 }
64
65 static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Lin2d>& theLine1, bool theReversed1,
66                                const std::shared_ptr<GeomAPI_Lin2d>& theLine2, bool theReversed2)
67 {
68   std::shared_ptr<GeomAPI_Pnt2d> aCenter = theLine1->intersect(theLine2);
69   if (!aCenter)
70     aCenter = theLine1->location();
71   double aCoeff = theReversed1 ? -1.0 : 1.0;
72   std::shared_ptr<GeomAPI_Pnt2d> aPoint1(new GeomAPI_Pnt2d(
73       aCenter->xy()->added(theLine1->direction()->xy()->multiplied(aCoeff))));
74   aCoeff = theReversed2 ? -1.0 : 1.0;
75   std::shared_ptr<GeomAPI_Pnt2d> aPoint2(new GeomAPI_Pnt2d(
76       aCenter->xy()->added(theLine2->direction()->xy()->multiplied(aCoeff))));
77   ThreePoints2d* anAngle = newAngle(aCenter, aPoint1, aPoint2);
78   anAngle->myReversed[0] = theReversed1;
79   anAngle->myReversed[1] = theReversed2;
80   return anAngle;
81 }
82
83
84
85 GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Pnt2d>& theStartLine1,
86                                  const std::shared_ptr<GeomAPI_Pnt2d>& theEndLine1,
87                                  const std::shared_ptr<GeomAPI_Pnt2d>& theStartLine2,
88                                  const std::shared_ptr<GeomAPI_Pnt2d>& theEndLine2)
89     : GeomAPI_Interface(newAngle(theStartLine1, theEndLine1, theStartLine2, theEndLine2))
90 {
91 }
92
93 GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Lin2d>& theLine1, bool theReversed1,
94                                  const std::shared_ptr<GeomAPI_Lin2d>& theLine2, bool theReversed2)
95     : GeomAPI_Interface(newAngle(theLine1, theReversed1, theLine2, theReversed2))
96 {
97 }
98
99 GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
100                                  const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
101                                  const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2)
102     : GeomAPI_Interface(newAngle(theCenter, thePoint1, thePoint2))
103 {
104 }
105
106 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::center()
107 {
108   gp_Pnt2d aPnt = MY_ANGLE->myCenter;
109   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
110 }
111
112 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::firstPoint()
113 {
114   gp_Pnt2d aPnt = MY_ANGLE->myFirst;
115   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
116 }
117
118 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::secondPoint()
119 {
120   gp_Pnt2d aPnt = MY_ANGLE->mySecond;
121   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
122 }
123
124 double GeomAPI_Angle2d::angleDegree()
125 {
126   return angleRadian() * 180.0 / PI;
127 }
128
129 double GeomAPI_Angle2d::angleRadian()
130 {
131   ThreePoints2d* anAngle = MY_ANGLE;
132   gp_Dir2d aDir1(anAngle->myFirst.XY() - anAngle->myCenter.XY());
133   gp_Dir2d aDir2(anAngle->mySecond.XY() - anAngle->myCenter.XY());
134   double aRes = aDir1.Angle(aDir2);
135   if (aRes < 0.0) aRes += 2 * PI;
136   return aRes;
137 }
138
139 bool GeomAPI_Angle2d::isReversed(int theIndex)
140 {
141   return MY_ANGLE->myReversed[theIndex & 0x1];
142 }