1 // Copyright (C) 2014-2017 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
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
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>
27 #include <gp_Dir2d.hxx>
28 #include <gp_Pnt2d.hxx>
31 /// \struct ThreePoints
32 /// \brief Used to store info about angle point and state.
33 struct ThreePoints2d {
40 #define MY_ANGLE implPtr<ThreePoints2d>()
41 #define PI 3.1415926535897932
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)
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;
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)
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;
66 std::shared_ptr<GeomAPI_Pnt2d> aPoint1, aPoint2;
68 aPoint1 = aPoint2 = theEnd1;
70 aPoint1 = theStart1->distance(aCenter) < theEnd1->distance(aCenter) ? theEnd1 : theStart1;
71 aPoint2 = theStart2->distance(aCenter) < theEnd2->distance(aCenter) ? theEnd2 : theStart2;
73 ThreePoints2d* anAngle = newAngle(aCenter, aPoint1, aPoint2);
74 anAngle->myReversed[0] = aPoint1 == theStart1;
75 anAngle->myReversed[1] = !isParallel && aPoint2 == theStart2;
79 static ThreePoints2d* newAngle(const std::shared_ptr<GeomAPI_Lin2d>& theLine1, bool theReversed1,
80 const std::shared_ptr<GeomAPI_Lin2d>& theLine2, bool theReversed2)
82 std::shared_ptr<GeomAPI_Pnt2d> aCenter = theLine1->intersect(theLine2);
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;
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))
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))
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))
120 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::center()
122 gp_Pnt2d aPnt = MY_ANGLE->myCenter;
123 return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
126 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::firstPoint()
128 gp_Pnt2d aPnt = MY_ANGLE->myFirst;
129 return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
132 std::shared_ptr<GeomAPI_Pnt2d> GeomAPI_Angle2d::secondPoint()
134 gp_Pnt2d aPnt = MY_ANGLE->mySecond;
135 return std::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(aPnt.X(), aPnt.Y()));
138 double GeomAPI_Angle2d::angleDegree()
140 return angleRadian() * 180.0 / PI;
143 double GeomAPI_Angle2d::angleRadian()
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;
153 bool GeomAPI_Angle2d::isReversed(int theIndex)
155 return MY_ANGLE->myReversed[theIndex & 0x1];