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