1 // Copyright (C) 2014-2019 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
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>
26 #include <gp_Dir2d.hxx>
27 #include <gp_Pnt2d.hxx>
30 /// \struct ThreePoints
31 /// \brief Used to store info about angle point and state.
32 struct ThreePoints2d {
39 #define MY_ANGLE implPtr<ThreePoints2d>()
40 #define PI 3.1415926535897932
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)
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;
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)
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;
65 std::shared_ptr<GeomAPI_Pnt2d> aPoint1, aPoint2;
67 aPoint1 = aPoint2 = theEnd1;
69 aPoint1 = theStart1->distance(aCenter) < theEnd1->distance(aCenter) ? theEnd1 : theStart1;
70 aPoint2 = theStart2->distance(aCenter) < theEnd2->distance(aCenter) ? theEnd2 : theStart2;
72 ThreePoints2d* anAngle = newAngle(aCenter, aPoint1, aPoint2);
73 anAngle->myReversed[0] = aPoint1 == theStart1;
74 anAngle->myReversed[1] = !isParallel && aPoint2 == theStart2;
78 static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Lin2d>& theLine1, bool theReversed1,
79 const std::shared_ptr<GeomAPI_Lin2d>& theLine2, bool theReversed2)
81 std::shared_ptr<GeomAPI_Pnt2d> aCenter = theLine1->intersect(theLine2);
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;
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))
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))
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))
119 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::center()
121 gp_Pnt2d aPnt = MY_ANGLE->myCenter;
122 return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
125 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::firstPoint()
127 gp_Pnt2d aPnt = MY_ANGLE->myFirst;
128 return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
131 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::secondPoint()
133 gp_Pnt2d aPnt = MY_ANGLE->mySecond;
134 return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
137 double GeomAPI_Angle2d::angleDegree()
139 return angleRadian() * 180.0 / PI;
142 double GeomAPI_Angle2d::angleRadian()
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 double aRes = aDir1.Angle(aDir2);
148 if (aRes < 0.0) aRes += 2 * PI;
152 bool GeomAPI_Angle2d::isReversed(int theIndex)
154 return MY_ANGLE->myReversed[theIndex & 0x1];