Salome HOME
Add copyright header according to request of CEA from 06.06.2017
[modules/shaper.git] / src / GeomAPI / GeomAPI_Angle2d.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include <GeomAPI_Angle2d.h>
22 #include <GeomAPI_Dir2d.h>
23 #include <GeomAPI_Lin2d.h>
24 #include <GeomAPI_Pnt2d.h>
25 #include <GeomAPI_XY.h>
26
27 #include <gp_Dir2d.hxx>
28 #include <gp_Pnt2d.hxx>
29 #include <gp_XY.hxx>
30
31 /// \struct ThreePoints
32 /// \brief Used to store info about angle point and state.
33 struct ThreePoints2d {
34   gp_Pnt2d myCenter;
35   gp_Pnt2d myFirst;
36   gp_Pnt2d mySecond;
37   bool myReversed[2];
38 };
39
40 #define MY_ANGLE implPtr<ThreePoints2d>()
41 #define PI 3.1415926535897932
42
43 static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
44                                const std::shared_ptr<GeomAPI_Pnt2d>& theFirst,
45                                const std::shared_ptr<GeomAPI_Pnt2d>& theSecond)
46 {
47   ThreePoints2d* aResult = new ThreePoints2d;
48   aResult->myCenter = gp_Pnt2d(theCenter->x(), theCenter->y());
49   aResult->myFirst  = gp_Pnt2d(theFirst->x(), theFirst->y());
50   aResult->mySecond = gp_Pnt2d(theSecond->x(), theSecond->y());
51   aResult->myReversed[0] = aResult->myReversed[1] = false;
52   return aResult;
53 }
54
55 static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Pnt2d>& theStart1,
56                                const std::shared_ptr<GeomAPI_Pnt2d>& theEnd1,
57                                const std::shared_ptr<GeomAPI_Pnt2d>& theStart2,
58                                const std::shared_ptr<GeomAPI_Pnt2d>& theEnd2)
59 {
60   std::shared_ptr<GeomAPI_Lin2d> aLine1(new GeomAPI_Lin2d(theStart1, theEnd1));
61   std::shared_ptr<GeomAPI_Lin2d> aLine2(new GeomAPI_Lin2d(theStart2, theEnd2));
62   std::shared_ptr<GeomAPI_Pnt2d> aCenter = aLine1->intersect(aLine2);
63   bool isParallel = !aCenter;
64   if (isParallel)
65     aCenter = theStart1;
66   std::shared_ptr<GeomAPI_Pnt2d> aPoint1, aPoint2;
67   if (isParallel)
68     aPoint1 = aPoint2 = theEnd1;
69   else {
70     aPoint1 = theStart1->distance(aCenter) < theEnd1->distance(aCenter) ? theEnd1 : theStart1;
71     aPoint2 = theStart2->distance(aCenter) < theEnd2->distance(aCenter) ? theEnd2 : theStart2;
72   }
73   ThreePoints2d* anAngle = newAngle(aCenter, aPoint1, aPoint2);
74   anAngle->myReversed[0] = aPoint1 == theStart1;
75   anAngle->myReversed[1] = !isParallel && aPoint2 == theStart2;
76   return anAngle;
77 }
78
79 static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Lin2d>& theLine1, bool theReversed1,
80                                const std::shared_ptr<GeomAPI_Lin2d>& theLine2, bool theReversed2)
81 {
82   std::shared_ptr<GeomAPI_Pnt2d> aCenter = theLine1->intersect(theLine2);
83   if (!aCenter)
84     aCenter = theLine1->location();
85   double aCoeff = theReversed1 ? -1.0 : 1.0;
86   std::shared_ptr<GeomAPI_Pnt2d> aPoint1(new GeomAPI_Pnt2d(
87       aCenter->xy()->added(theLine1->direction()->xy()->multiplied(aCoeff))));
88   aCoeff = theReversed2 ? -1.0 : 1.0;
89   std::shared_ptr<GeomAPI_Pnt2d> aPoint2(new GeomAPI_Pnt2d(
90       aCenter->xy()->added(theLine2->direction()->xy()->multiplied(aCoeff))));
91   ThreePoints2d* anAngle = newAngle(aCenter, aPoint1, aPoint2);
92   anAngle->myReversed[0] = theReversed1;
93   anAngle->myReversed[1] = theReversed2;
94   return anAngle;
95 }
96
97
98
99 GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Pnt2d>& theStartLine1,
100                                  const std::shared_ptr<GeomAPI_Pnt2d>& theEndLine1,
101                                  const std::shared_ptr<GeomAPI_Pnt2d>& theStartLine2,
102                                  const std::shared_ptr<GeomAPI_Pnt2d>& theEndLine2)
103     : GeomAPI_Interface(newAngle(theStartLine1, theEndLine1, theStartLine2, theEndLine2))
104 {
105 }
106
107 GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Lin2d>& theLine1, bool theReversed1,
108                                  const std::shared_ptr<GeomAPI_Lin2d>& theLine2, bool theReversed2)
109     : GeomAPI_Interface(newAngle(theLine1, theReversed1, theLine2, theReversed2))
110 {
111 }
112
113 GeomAPI_Angle2d::GeomAPI_Angle2d(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
114                                  const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
115                                  const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2)
116     : GeomAPI_Interface(newAngle(theCenter, thePoint1, thePoint2))
117 {
118 }
119
120 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::center()
121 {
122   gp_Pnt2d aPnt = MY_ANGLE->myCenter;
123   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
124 }
125
126 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::firstPoint()
127 {
128   gp_Pnt2d aPnt = MY_ANGLE->myFirst;
129   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
130 }
131
132 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::secondPoint()
133 {
134   gp_Pnt2d aPnt = MY_ANGLE->mySecond;
135   return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
136 }
137
138 double GeomAPI_Angle2d::angleDegree()
139 {
140   return angleRadian() * 180.0 / PI;
141 }
142
143 double GeomAPI_Angle2d::angleRadian()
144 {
145   ThreePoints2d* anAngle = MY_ANGLE;
146   gp_Dir2d aDir1(anAngle->myFirst.XY() - anAngle->myCenter.XY());
147   gp_Dir2d aDir2(anAngle->mySecond.XY() - anAngle->myCenter.XY());
148   double aRes = aDir1.Angle(aDir2);
149   if (aRes < 0.0) aRes += 2 * PI;
150   return aRes;
151 }
152
153 bool GeomAPI_Angle2d::isReversed(int theIndex)
154 {
155   return MY_ANGLE->myReversed[theIndex & 0x1];
156 }