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